Compare commits

...

24 Commits

Author SHA1 Message Date
Surenjun
b0a490441d fix:build-profile修改 2025-10-10 14:32:41 +08:00
Surenjun
c06a122de4 feat:新科目视觉类代码 2025-10-09 09:25:37 +08:00
Surenjun
158f6260db feat:新科目视觉类代码 2025-09-29 08:39:44 +08:00
Surenjun
50c16cb56a feat:新科目三&安全员代码 2025-09-24 15:49:29 +08:00
Surenjun
4fa6ad0544 feat:新科目三 2025-09-02 09:40:01 +08:00
Surenjun
b5c641c16b feat:新科目三开发 2025-08-27 13:50:20 +08:00
Surenjun
4c6f25ee3a feat: 模拟灯光相关特性优化 2025-08-18 08:47:42 +08:00
Surenjun
2ff07dd2fb feat: 外壳参数优化 2025-08-08 13:51:22 +08:00
Surenjun
d2e795c82f feat:1. 靠边停车项目进行中不能退出 2.344参数修改 2025-07-29 15:07:29 +08:00
Surenjun
94b3b2e96a feat:安全员代码 2025-07-24 08:21:02 +08:00
Surenjun
ed4b981807 fix:遗漏方法提交 2025-07-22 18:43:54 +08:00
Surenjun
dc72d33536 feat: 断点续考specialkf修改 2025-07-22 09:14:44 +08:00
0832262cd7 fix:新增853参数 2025-06-30 19:28:17 +08:00
6b54e9da5c Revert "Revert "fix:新增503参数""
This reverts commit 6de9d4bdcb42c67f9533b693f3d70a04b0e8391d.
2025-06-30 19:27:41 +08:00
6de9d4bdcb Revert "fix:新增503参数"
This reverts commit addf143396b30a4b348dcf1830e0da3d4800163b.
2025-06-30 19:26:56 +08:00
addf143396 fix:新增503参数 2025-06-30 19:22:21 +08:00
448a16fab9 fix: 档位串口读取优化 2025-06-28 09:54:28 +08:00
e36b0f018b fix: 1.499参数修改; 2.科目二sbbm字段读取优化 2025-06-28 09:52:27 +08:00
lv
f9beb54a28 冲突提交 2025-06-25 10:21:28 +08:00
lv
f420a9512f 重连 2025-06-25 10:19:26 +08:00
920323bc78 无用代码清理 2025-06-18 15:24:33 +08:00
6f3bdbf176 fix:退回 2025-06-18 15:10:43 +08:00
8251bed720 fix:优化人工进项目 2025-06-18 15:01:19 +08:00
508c3f3954 fix:档位串口优化 2025-06-18 14:21:05 +08:00
27 changed files with 995 additions and 86 deletions

View File

@ -9,12 +9,17 @@
],
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
"cppFlags": ""
},
"sourceOption": {
"workers": [
'./src/main/ets/workers/worker.ts'
]
},
"arkOptions": {
"types": [
"./src/main/ets/common/lidar/type"
]
}
},
"targets": [

View File

@ -1,15 +1,13 @@
{
"lockfileVersion": 2,
"lockfileVersion": 1,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6"
},
"packages": {
"@ohos/hypium@1.0.6": {
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz",
"integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==",
"registryType": "ohpm",
"shasum": "3f5fed65372633233264b3447705b0831dfe7ea1"
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz",
"integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ=="
}
}
}

View File

@ -189,6 +189,7 @@ export async function uploadExamMileage(params) {
<lsh>${params.lsh}<lsh>
<kskssj>${params.examinationRoomId}<kskssj>
<kslc>${params.kslc}<kslc>
<specialkf>${params.specialkf}<specialkf>
</body>
</uploadExamMileageReq>`,
method: 'post',

View File

@ -0,0 +1,108 @@
import emitter from '@ohos.events.emitter';
import radarClient from './radar/index'
import visionClient from './vision/index'
import FileUtil from '../../common/utils/File';
import { GlobalConfig } from '../../config/index';
import { messageIds } from './type'
class Lidar {
public localRadarUdp: radarClient
public localVisionUdp: visionClient
//是否新科目三设备
private isNewKm3: Boolean
//雷达消息Ids
private radarMessageIds: messageIds = {}
///视觉消息Ids
private senseMessageIds: messageIds = {}
constructor() {
this.init()
}
async init() {
const fileUtil = new FileUtil(globalThis.context)
const addressStr = await fileUtil.readFile(GlobalConfig.comoonfileWriteAddress + '/config/ipConfig.txt');
const {deviceType,deviceIpArr,devicePortArr,udplocalIp} = JSON.parse(addressStr);
//新科目三设备
if (deviceType == '2') {
//雷达UDP
this.localRadarUdp = new radarClient({
deviceIpArr, devicePortArr, udplocalIp
})
this.localRadarUdp.onRadarClientMessage(async (obj) => {
//广播注册的radar消息
Reflect.ownKeys(this.radarMessageIds).forEach((messageId: string) => {
emitter.emit({ eventId: this.radarMessageIds[messageId] }, { data: obj })
})
})
// this.localRadarUdp.onMessage((obj) => {
// //广播注册的radar消息
// Reflect.ownKeys(this.radarMessageIds).forEach((messageId:string) => {
// emitter.emit({eventId:this.radarMessageIds[messageId]},{data:obj})
// })
// })
//
// this.localVisionUdp.onMessage((obj) => {
// //广播注册的sense消息
// Reflect.ownKeys(this.senseMessageIds).forEach((messageId:string) => {
// emitter.emit({eventId:this.radarMessageIds[messageId]},{data:obj})
// })
// })
this.isNewKm3 = true;
}
//安全员&新科目三均需要视觉
this.localVisionUdp = new visionClient({
deviceIpArr, devicePortArr, udplocalIp
})
//TODO 初始化视觉设备
this.localVisionUdp.visionInit();
this.localVisionUdp.onVisionClientMessage(async (obj) => {
//广播注册的sense消息
Reflect.ownKeys(this.senseMessageIds).forEach((messageId: string) => {
emitter.emit({ eventId: this.senseMessageIds[messageId] }, { data: obj })
})
})
}
//监听雷达信息
async onRadarMsg(messageId: string, callback: Function) {
if (this.radarMessageIds[messageId] === undefined) {
const eventId = this.generateRandomNumber();
emitter.on({ eventId }, (data) => {
callback(data)
});
this.radarMessageIds[messageId] = eventId;
}
}
//监听视觉信息
async onSenseMsg(messageId: string, callback: Function) {
if (this.senseMessageIds[messageId] === undefined) {
const eventId = this.generateRandomNumber();
emitter.on({ eventId }, (data) => {
callback(data)
});
this.senseMessageIds[messageId] = eventId;
}
}
//关闭消息
async offMsg(type: 'radar' | 'vision', messageId: string) {
emitter.off(
[type === 'radar' ? this.radarMessageIds[messageId] : this.senseMessageIds][messageId]
)
delete [type === 'radar' ? this.radarMessageIds[messageId] : this.senseMessageIds][messageId]
}
//随机生成6位的id
generateRandomNumber() {
let num = '';
for (let i = 0; i < 6; i++) {
num += Math.floor(Math.random() * 10);
}
return Number(num);
}
}

View File

@ -0,0 +1,90 @@
import UdpClient from '../udpClient/index'
import emitter from '@ohos.events.emitter';
import {Machine,messageIds} from '../type'
import systemTime from '@ohos.systemDateTime';
//雷达消息Ids
export default class RadarClient{
public localRadarUdp: UdpClient
constructor(params:{
deviceIpArr:string[],
devicePortArr:number[],
udplocalIp:string
}) {
const {deviceIpArr,devicePortArr,udplocalIp} = params;
//雷达UDP
this.localRadarUdp = new UdpClient('radar', {
deviceIpArr, devicePortArr, udplocalIp
});
}
//雷达信息监听
async onRadarClientMessage(callback){
this.localRadarUdp.onClientMessage((radarStr)=>{
const radarObj = this.radarStrToObj(radarStr)
callback(radarObj)
console.log(radarStr+'');
});
}
// 雷达数据解析
async radarStrToObj(str:string){
//$MachineVision,30.950^0_-1_1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1^-1,43083,0_0_0_0,-1^-1_-1_-1_1,-1^-1_-1_-1_1,-1^-1_-1_-1_1,10102264201.69632,1.1.1.2,0*+$VisualInfo,1_-7205_3480_-7300_3350_-7655_3610_-7560_3735_,*+[ { "bodyangle": "1.00", "bodyx": "0.490", "bodyy": "31.300", "elevation": "2.403", "geoangle": "323.90", "geolat": "29.92678975", "geolon": "119.89823128", "id": 1, "type": 2 } ]
const [machine, visual, obj] = str.split('+');
const machineArr = machine.split(',');
let tempObj:Machine = {};
tempObj.sj = await systemTime.getCurrentTime();
tempObj.xh = Number(machineArr[10]);
['qf', 'hf', 'zq', 'zh', 'yq', 'yh', 'zc', 'yc', 'zf'].forEach((c,index) => {
tempObj[c] = this.getMachineItem(machineArr[index + 1]);
});
['lq', 'lz', 'ly'].forEach((c,index) => {
tempObj[c] = this.getMachineItem(machineArr[index + 13]);
});
tempObj.wt = this.getMachineWt(machineArr[10])
tempObj.rc = this.getMachineRc(machineArr[12])
}
getMachineItem(str){
const strArr = str.split('_');
return {
//对象编号
bh:strArr[2],
//车类型
lx:strArr[3],
//纵向距离
jz:strArr[0].split('^')[0],
//横向距离
jh:strArr[0].split('^')[1],
//速度
sd:strArr[1]
}
}
//获取前方数据
getMachineWt(str){
return {
xz:str.split('_')[0].split('^')[0],
xh:str.split('_')[0].split('^')[1],
zz:str.split('_')[1].split('^')[0],
zh:str.split('_')[1].split('^')[1],
}
}
//获取绕车一周数据
getMachineRc(str){
return {
zh:str.split('_')[0],
yh:str.split('_')[1],
yq:str.split('_')[2],
zq:str.split('_')[3]
}
}
async offMessage(){
this.localRadarUdp.closeUdp()
}
}

View File

@ -0,0 +1,106 @@
interface visionType1 {
sj?: number
//置信度
df?: 0 | 1
//摇头旋转角度
yt?: number
//左右旋转角度
zy?: number
//上下点头角度
sx?: number
}
interface visionType2 {
sj?: number
//控制方向盘
fx?: number
//手伸出窗外
ch?: number
}
interface visionType3 {
sj?: number
//信号灯
xd?: string
//识别前方物体
wt: 0 | 1 | 2 | 3 | 4
//中心隔离设施或中心线
zx: 0 | 1 | -1
//后车超车信号灯
hc: string
}
interface MachineItem {
//对象编号
bh: number
//车类型
lx: number
//纵向距离
jz: number
//横向距离
jh: number
//速度
sd: number
}
export interface Machine {
sj?: number
//帧数
xh?: number
//本车道前方数据
qf?: MachineItem
//本车道后方数据
hf?: MachineItem
//左侧车道前方
zq?: MachineItem
//左侧车道后方
zh?: MachineItem
//右侧车道前方
yq?: MachineItem
//右侧车道后方
yh?: MachineItem
//左侧车道
zc?: MachineItem
//右侧车道
yc?: MachineItem
//左侧方向车道
zf?: MachineItem
//前方数据
wt?: {
//行人距离本车的距离(纵向距离)
xz: number
//行人距离本车的距离(横向向距离)
xh: number
//障碍物距离本车的距离(纵向距离)
zz: number
//障碍物距离本车的距离(横向距离)
zh: number
}
//绕车一车数据
rc?: {
//左后
zh: number
//右后
yh: number
//右前
yq: number
//左前
zq: number
},
//路口前方来车数据
lq?: MachineItem,
//路口左侧来车
lz?: MachineItem,
//路口右侧来车
ly?: MachineItem
[k: string]: any
}
export interface messageIds {
[k: string]: number;
}

View File

@ -0,0 +1,106 @@
import socket from '@ohos.net.socket';
import FileUtil from '../../../common/utils/File';
import { GlobalConfig } from '../../../config/index';
import {Machine} from '../type'
import promptAction from '@ohos.promptAction'
import systemTime from '@ohos.systemDateTime';
const TAG = 'LIDAUDP'
type TYPE = 'vision' | 'radar'
interface IPAPORT{
address:string,
port:number
}
interface Params{
deviceIpArr:string[],
devicePortArr:number[],
udplocalIp:string
}
export default class LidaUdpClient{
// 0: 视觉 1: 雷达
public type:TYPE
private udpClient:socket.UDPSocket
private localIp:string
private localSensePort: 33313
private localVisionPort: 33314
private params:Params
public message:string
constructor(type:TYPE,params:Params) {
this.type = type;
this.params = params
this.localIp = params.udplocalIp
}
async init(){
const {address,port} = await this.getIpAPort()
this.udpClient = socket.constructUDPSocketInstance();
//bind
await this.safeFn(async()=>{
await this.udpClient.bind({
address: this.localIp, port: port, family: 1
});
})
}
async onClientMessage(callback){
this.offMessage()
//message
this.udpClient.on('message',(buffer)=>{
const dataStr = this.arrayBuffetToStr(buffer.message);
callback(dataStr)
});
}
//arrayBuffer转string
arrayBuffetToStr(arrayBuffer){
let dataView = new DataView(arrayBuffer)
let str = ""
for (let i = 0; i < dataView?.byteLength; ++i) {
let c = String.fromCharCode(dataView?.getUint8(i))
if (c !== "\n") {
str += c
}
}
return str
}
//获取对应的IP和端口
async getIpAPort(): Promise<IPAPORT>{
const fileUtil = new FileUtil(globalThis.context)
const addressStr = await fileUtil.readFile(GlobalConfig.comoonfileWriteAddress + '/config/ipConfig.txt');
const {deviceIpArr,devicePortArr,udplocalIp} = JSON.parse(addressStr);
this.localIp = udplocalIp
return {
address:this.type === 'radar' ? deviceIpArr[0] : deviceIpArr[1],
port: Number(this.type === 'vision' ? devicePortArr[1] : devicePortArr[1])
}
}
async offMessage(){
this.udpClient.off('message')
}
async closeUdp(){
this.offMessage();
this.udpClient.close()
}
async safeFn(fn:Function){
try {
await fn()
} catch (e) {
console.info(TAG + JSON.stringify(e))
promptAction.showToast({
message: TAG + JSON.stringify(e),
duration: 3000
});
throw e
}
}
}

View File

@ -0,0 +1,106 @@
import UdpClient from '../udpClient/index'
import emitter from '@ohos.events.emitter';
import {messageIds} from '../type'
import systemTime from '@ohos.systemDateTime';
export default class VisionClient{
public localVisionUdp: UdpClient
constructor(params:{
deviceIpArr:string[],
devicePortArr:number[],
udplocalIp:string
}) {
const {deviceIpArr,devicePortArr,udplocalIp} = params;
//视觉UDP
this.localVisionUdp = new UdpClient('vision', {
deviceIpArr, devicePortArr, udplocalIp
});
}
// 视觉信息监听
public async onVisionClientMessage(callback){
this.localVisionUdp.onClientMessage((str) => {
const data = this.visionStrToObj(str)
callback(data)
})
}
// 视觉数据解析
async visionStrToObj(visionStr:string){
const visionDataArr = visionStr.split(',');
const [dataType, message] = [visionDataArr[3] , visionDataArr[4]];
const messageArr = (message || '').split('@')
const sj = await systemTime.getCurrentTime();
switch (dataType){
//头部姿态
case 'A204':return {
//系统时间戳
sj,
//置信度
df:Number(messageArr[0]),
//摇头旋转角度
yt:Number(messageArr[1]),
//左右旋转角度
zy:Number(messageArr[2]),
//上下点头角度
sx:Number(messageArr[3]),
}
//驾驶行为
case 'A206':return {
//系统时间戳
sj,
//控制方向盘
fx:Number(messageArr[0]),
//手伸出窗外
ch:Number(messageArr[1]),
}
//前方障碍物
case 'A205':return {
//系统时间戳
sj,
//信号灯
xd:messageArr[0],
//识别前方物体
wt:Number(messageArr[1]),
//中心隔离设施或中心线
zx:Number(messageArr[2]),
//后车超车信号
hc:messageArr[3]
}
}
//头部姿态 驾驶行为 前方障碍物
//$SBXS,85,20250603115529563,B202,赣A78QK6@360803200602253517@1@20250603115523132@@@@@李从星@001@@001@2506455453517,05,*SBJS
//$SBXS,213,20250603090553562,B207,邓凯倩@@320250603085259@000000100000001001001000@14@870@28520185@115902060@1@828@4294943473@359.8704@0@0@1111111111011111111111111111111100000000@0@0000000000@3142@0@0@@C1@赣A78QK6@0@001-001@360121200401040528,01,*SBJS
}
// 初始化指令
public async visionInit(){
//车牌号@时间戳@空@空@空@空@空
}
// 开始考试指令
async visionExamStart(){
//车牌号@考试身份证号@考试状态(1-考试考试0-结束考试)@开始考试时间@考试次数@考车信息@窗户标注信息@方向盘标注信息@考生姓名@安全员编号@是否合格(1-合格0-不合格)@安全员姓名@流水号
}
// 结束考试指令
async visionExamEnd(){}
// 开始录像
async visionStartRecord(){
//考车号_流水号_时间_扣分项目_扣分序号_倒退时长_顺延时长_是否扣分@关键值1_关键字2_关键字3@
}
// 结束录像
async visionEndRecord(){}
// 安全员信号传输
public async visionSignalSend(){
/*
* @考试员号@考车车型@车牌号@科目类型+@设备信号状态@速度@发动机转速@GPS (线)@GPS (线)
* @主天线位置@GPS (线)@GPS (线)@航向角@俯仰角@高程@项目状态@当前项目编号
* @场地设备编号@本次考试行驶总距离@扣分值@扣分项数量@n个扣分项序号@考车车型@车牌号
* @工控机是否在播报语音@安全员姓名
*/
}
}

View File

@ -7,12 +7,14 @@ import { takePhoto, deleteAllFileByPiC } from '../../common/service/videoService
// import { VideoConfigData } from '../../mock';
import request from '@ohos.request'
import Prompt from '@system.prompt';
import util from '@ohos.util';
import {
delSyncTable,
getDataBaseTable,
getMySystemSetTable,
upDataZhongxinginitialization,
getSyncData,
upDateTable
} from '../../common/service/initable'
import { GlobalConfig } from '../../config/index'
@ -433,17 +435,21 @@ let fd
const devPath = "/dev/ttyS3"
function openChuankouFn(callback) {
console.log('SerialOpen in indexservice, path=' + devPath)
//TODO 自动挡车不读取串口
testNapi.SerialOpenAsync(devPath, (fd) => {
globalThis.fd = fd;
globalThis.num = 0
let parity = 0x4e; // 'N'
let ret = testNapi.SerialSetAsync(globalThis.fd, 115200, 0, 8, 1, parity, (ret) => {
callback()
});
});
getSyncData('ES_CARINFO').then(result => {
const carInfo = result[0] || {};
globalThis.carInfo.kscx = carInfo.kscx
console.info('srj ES_CARINFO=>',JSON.stringify(carInfo))
if(carInfo.kscx == 'C1'){
testNapi.SerialOpenAsync(devPath, (fd) => {
globalThis.fd = fd;
globalThis.num = 0
let parity = 0x4e; // 'N'
let ret = testNapi.SerialSetAsync(globalThis.fd, 115200, 0, 8, 1, parity, (ret) => {
callback()
});
});
}
})
}
function getChuankouFnMsg() {
@ -451,9 +457,9 @@ function getChuankouFnMsg() {
let databuff = [0x61, 0xAA, 0x0A, 0X15, 0X00]; // send ABCDE
testNapi.SerialSendAsync(globalThis.fd, databuff, (ret) => {
testNapi.SerialRecvAsync(globalThis.fd, timeout, (revTestInfo) => {
const message = revTestInfo?.recevedBuf?.toString()
if (message == '') {
let msgBuf = util.TextDecoder.create().decodeWithStream(new Uint8Array(revTestInfo?.recevedBuf))
if (message == '' || msgBuf == '') {
globalThis.num = 1
// clearInterval(chuankou)
testNapi.SerialClose(globalThis.fd);
@ -464,16 +470,8 @@ function getChuankouFnMsg() {
return
}
const msg = message?.split(',')
if (!msg?.length) {
} else if (msg[0] != '98' || msg[1] != '85' || msg.length < 9) {
} else if (msg.length < 12) {
} else {
globalThis.chuankoMsg = msg[9]
}
let dang = Number(msgBuf?.split(",")?.[1]?.split('\r')[0] || 0)
globalThis.chuankoMsg =( msg[9] === '' || msg[9] >10 ) ? dang: msg[9]
setTimeout(() => {
getChuankouFnMsg()
}, 500)

View File

@ -218,6 +218,7 @@ export async function takePhoto(param, context, dir, flag = 1, callback?) {
// @ts-ignore
// var snapResult = rtsp_server.getVideoSnapshot(context, video_uri, '', dir);
if (flag == 0) {
//@ts-ignore
rtsp_server.detectVideoSnapshotSize(video_uri, fileName, (err, snapResult) => {
console.log("baohaowen_detectLoop round end size1:" + snapResult.fileSize);
callback({ fileSize: snapResult.fileSize, errorCode: snapResult.errorCode })

View File

@ -3,7 +3,7 @@ import { getSyncData } from '../service/initable';
import hilog from '@ohos.hilog';
import FileUtil from '../../common/utils/File'
import { GlobalConfig } from '../../config/index'
const TAG = 'socketTag[TcpDemo.TcpClient]'
export async function getTCP(flag=false) {
globalThis.getCloseTcp=true
const fileUtil = new FileUtil(globalThis.context)
@ -35,10 +35,16 @@ export async function getTCP(flag=false) {
console.log('ttttttt00')
clearInterval(globalThis.intervalSendmsg)
globalThis.intervalSendmsg=setInterval(()=>{
globalThis.intervalSendmsg=setInterval(async()=>{
console.log('getCloseTcp',globalThis.carInfo.carNo)
if(!globalThis.getCloseTcp){
globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002
await globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002
globalThis.tcpStep+=1
if(globalThis.tcpStep>30){
console.log(TAG,'tcp重连开始')
globalThis.tcpStep=0
getTCP()
}
}
},1000/3)
globalThis.TcpClient.onError((val) => {
@ -68,10 +74,16 @@ export async function getTCP(flag=false) {
console.log('ttttttt12')
clearInterval(globalThis.intervalSendmsg)
globalThis.intervalSendmsg=setInterval(()=>{
globalThis.intervalSendmsg=setInterval(async()=>{
// console.log('getCloseTcp',globalThis.getCloseTcp)
if(!globalThis.getCloseTcp){
globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002
await globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002
globalThis.tcpStep+=1
if(globalThis.tcpStep>30){
console.log(TAG,'tcp重连开始')
globalThis.tcpStep=0
getTCP()
}
}
},1000/3)
globalThis.TcpClient.onError((val) => {

View File

@ -148,13 +148,12 @@ export default class TcpClient {
this.tcpSendNum=0
return
}
globalThis.getCloseTcp=true
console.log(`${TAG} TCPsend error ${JSON.stringify(err)}`)
// this.writeLog({
// time:dateFormat(new Date()),
// message: `${TAG} TCPsend error ${JSON.stringify(err)}`,
// })
reslove(false)
reject(false)
});
})
}
@ -165,6 +164,7 @@ export default class TcpClient {
// time:dateFormat(new Date()),
// PLC:`${TAG} Tcponmessage`,
// })
globalThis.tcpStep=0
globalThis.tcpUdpError = false
if (value) {
callback && callback(value.message)

View File

@ -38,7 +38,7 @@ export default class EntryAbility extends UIAbility {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
await tcpUtil.init()
globalThis.tcpStep=0
globalThis.carInfo = {}
globalThis.examinerInfo = {}

View File

@ -85,3 +85,7 @@ export const RoadData = [
{name:'形状',key:['InShapeAttr','ShapeNo','']},
{name:'路段点',key:['CrossPointNo']},
]
export const radarData = [
]

View File

@ -677,6 +677,11 @@ struct Index {
}, 1000)
this.createAlbum()
getSyncData('ES_CARINFO').then(result => {
const carInfo = result[0] || {};
globalThis.carInfo.kscx = carInfo.kscx
})
// clearInterval(globalThis.demo)
// globalThis.demo= setInterval(()=>{
// const str= {"carId":"1062","examinationRoomId":"2","videoVersion":"1.0","judgeVersion":"2023.09.30.1","shellVersion":"2023.12.13.01","host":"http://172.37.55.191:8082"}

View File

@ -442,7 +442,7 @@ struct Index {
const ddxkKsxmArr = examItemsArrs[2]?.split(',').filter(item => item) || []
const ddxkKfArr = examItemsArrs[3]?.split('^').filter(item => item) || []
if (judgeConfigObj['432'] == 2 || examSubject == 2) {
//TODO 带项目带里程
if (ddxkKsxmArr?.length) {
//断点续考
ddxkKsxmArr.forEach(xmdm => {
@ -455,6 +455,8 @@ struct Index {
})
this.ddxkKsxmArr = ddxkKsxmArr
}
this.specialkf = examItemsArrs[4];
this.yklc = Number(examItemsArrs[1]) || 0
}
//扣分续考
ddxkKfArr.forEach((kf) => {
@ -480,6 +482,7 @@ struct Index {
this.ddxkKfArr = ddxkKfArr
this.ddxkTime = Date.parse(startTime);
this.isDdxk = true
}
}
@ -563,7 +566,7 @@ struct Index {
//上车准备&起步都开始时
if (this.syssetParam386 == '3'
&& (this.projectsObj[1].type == '2' || this.projectsObj[1].type == '3')
&& this.projectsObj[2].type == '2'
&& (this.projectsObj[2].type !== '1' && this.projectsObj[2].type !== undefined)
&& !this.syssetParam386ET3
) {
this.judge.rmndg = 2;
@ -572,7 +575,7 @@ struct Index {
}
// 上传考试里程
async uploadMileage() {
async uploadMileage(specialkf) {
if (!globalThis.singlePlay) {
const {lsh,startExamTime:kskssj,jl:kslc} = this
const { carId ,examinationRoomId} = globalThis.carInfo;
@ -581,7 +584,9 @@ struct Index {
examinationRoomId,
lsh,
kskssj,
kslc
//考试里程单位cm
kslc:kslc * 100,
specialkf
})
}
}
@ -915,6 +920,25 @@ struct Index {
.backgroundImage($rawfile('judge/anniu_nor.png'), ImageRepeat.NoRepeat)
.backgroundImageSize({ width: '100%', height: '100%' })
.onClick(() => {
//靠边停车进行中&且其它项目都已经完成 不能结束
if(!this.singlePlay && this.projectsObj['40600']?.type == '2' && this.isRequiredProjectsEnd){
Prompt.showToast({
message: '靠边停车项目进行中,不允许手动退出!',
duration: 4000
});
return
}
//考试未结束且有扣分,不允许退出
if (!this.singlePlay && this.judgeConfigObj['344'] == 1 && this.kfArr.length > 0&& !this.isAllProjectsEnd ) {
Prompt.showToast({
message: '考试未结束且有扣分,不允许手动退出!',
duration: 4000
});
return
}
// this.vocObj.playAudio({
// type: 1,
// name: 'button_media.wav'
@ -1024,13 +1048,7 @@ struct Index {
router.back()
return
}
if (this.judgeConfigObj['344'] == 1) {
Prompt.showToast({
message: '考试未结束,不允许手动退出!',
duration: 4000
});
return
}
this.endPopupVisible = false;
this.loadingPopupVisible = true
clearInterval(this.timer);
@ -1103,6 +1121,9 @@ struct Index {
case '4':
return '#FF7566';
break;
case '5':
return '#FF7566';
break;
default:
return '#E6DECF';
break;
@ -1422,7 +1443,7 @@ struct Index {
// 必考项目除靠边停车是否全部完成
@State isRequiredProjectsEnd: boolean = false;
// 考试项目是否全部完成
// @State isAllProjectsEnd: boolean = false;
@State isAllProjectsEnd: boolean = false;
@State lane: LANE = { road: '', num: 0, count: 0 }
@State roadData: Object = {};
//定位差分状态时候正常
@ -1443,4 +1464,8 @@ struct Index {
@State errorMsg: string = ''
@State isErrorMsgEnd: boolean = false
@State disConnectErrorOpen: boolean = false
//开始考试特殊标记
@State specialkf:string = ''
//已考里程
@State yklc:number = 0
}

View File

@ -23,10 +23,15 @@ struct Index {
@State terTextList: string[] = ['一型机', '二型机', '三型机', '一体机']
@State cardTextList: string[] = ['北云', '天宝MB2']
@State netTextList: string[] = ['否', '是']
@State deviceTypeSelect: string[] = ['正常', '安全员','新科目三']
@State selectedTerType: number = 0
@State selectedCardType: number = 0
//是否启用网络差分
@State netOpen: number = 0
//设备应用类型
@State deviceType: number = 0
@State deviceIpArr: string[] = ['192.168.7.173', '192.168.7.173']
@State devicePortArr: string[] = ['8052', '8053']
// @State inputTextList2: string[] = []
// 112.80.35.83 11052
// @State inputTextList1: string[] = ['192.168.36.2','8084','192.168.36.200','20122','255.255.255.0','192.168.36.1','','','114.114.114.114','192.168.36.139','8000']
@ -118,7 +123,6 @@ struct Index {
})
}.width('51%').height('14%')
Row(){
Text('板卡类型')
.width('40%')
@ -140,6 +144,128 @@ struct Index {
})
}.width('49%').height('14%')
Row() {
Text('设备应用场景')
.width('40%')
.height('100%')
.fontColor('#E5CBA1')
.padding({ 'left': '35px' })
.fontSize(this.inputFontSize * this.ratio)
ForEach(this.deviceTypeSelect, (netText, index) => {
Radio({ value: netText, group: 'deviceRadioGroup' })
.borderColor('#E5CBA1')
.checked(index === this.deviceType)
.onChange((value: boolean) => {
if(value){
this.deviceType = index
}
})
Text(netText).fontSize(20).fontColor('#FFF')
})
}.width('52%').height('14%')
// 新科目三设备
if(this.deviceType == 1 || this.deviceType == 2){
Row() {
Text('雷达设备IP')
.width('40%')
.height('100%')
.fontColor('#E5CBA1')
.padding({ 'left': '35px' })
.fontSize(this.inputFontSize * this.ratio)
TextInput({ 'text':this.deviceIpArr[0] })
.width('50%')
.height('50%')
.fontColor('#fff')
.borderColor('#E6E0D8')
.borderRadius('10px')
.borderWidth('2px')
.fontSize(this.inputFontSize * this.ratio)
.padding({ top: 0, bottom: 0 })
.linearGradient({angle: 0,colors: [[0x403C36, 0.0], [0x4D473D, 0.34], [0x3D3A34, 1.0]] })
.onChange((value: string) => {
this.deviceIpArr[0] = value
})
}.width('50%').height('14%')
Row() {
Text('响应端口')
.width('40%')
.height('100%')
.fontColor('#E5CBA1')
.padding({ 'left': '35px' })
.fontSize(this.inputFontSize * this.ratio)
TextInput({ 'text':this.devicePortArr[0] })
.width('50%')
.height('50%')
.fontColor('#fff')
.borderColor('#E6E0D8')
.borderRadius('10px')
.borderWidth('2px')
.fontSize(this.inputFontSize * this.ratio)
.padding({ top: 0, bottom: 0 })
.linearGradient({
angle: 0,
colors: [[0x403C36, 0.0], [0x4D473D, 0.34], [0x3D3A34, 1.0]]
})
.onChange((value: string) => {
this.devicePortArr[0] = value
})
}.width('50%').height('14%')
}
// 安全员设备
if(this.deviceType == 2){
Row() {
Text('视觉设备IP')
.width('40%')
.height('100%')
.fontColor('#E5CBA1')
.padding({ 'left': '35px' })
.fontSize(this.inputFontSize * this.ratio)
TextInput({ 'text': this.deviceIpArr[1] })
.width('50%')
.height('50%')
.fontColor('#fff')
.borderColor('#E6E0D8')
.borderRadius('10px')
.borderWidth('2px')
.fontSize(this.inputFontSize * this.ratio)
.padding({ top: 0, bottom: 0 })
.linearGradient({
angle: 0,
colors: [[0x403C36, 0.0], [0x4D473D, 0.34], [0x3D3A34, 1.0]]
})
.onChange((value: string) => {
this.deviceIpArr[1] = value
})
}.width('50%').height('14%')
Row() {
Text('响应端口')
.width('40%')
.height('100%')
.fontColor('#E5CBA1')
.padding({ 'left': '35px' })
.fontSize(this.inputFontSize * this.ratio)
TextInput({ 'text': this.devicePortArr[1] })
.width('50%')
.height('50%')
.fontColor('#fff')
.borderColor('#E6E0D8')
.borderRadius('10px')
.borderWidth('2px')
.fontSize(this.inputFontSize * this.ratio)
.padding({ top: 0, bottom: 0 })
.linearGradient({
angle: 0,
colors: [[0x403C36, 0.0], [0x4D473D, 0.34], [0x3D3A34, 1.0]]
})
.onChange((value: string) => {
this.devicePortArr[1] = value;
})
}.width('50%').height('14%')
}
}
}
.width('95%')
@ -172,7 +298,10 @@ struct Index {
centerPort: this.inputTextList1[3],
terType: this.selectedTerType,
cardType: this.selectedCardType,
netOpen: this.netOpen
netOpen: this.netOpen,
deviceType: this.deviceType,
deviceIpArr: this.deviceIpArr,
devicePortArr: this.devicePortArr,
}
fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param), '')
// upDateTableByArray('IpConfigTable',[])
@ -247,6 +376,9 @@ struct Index {
this.selectedTerType = result.terType
this.selectedCardType = result.cardType
this.netOpen= result.netOpen
this.deviceType= result.deviceType || 0
this.deviceIpArr= result.deviceIpArr || ['','']
this.devicePortArr= result.devicePortArr || ['','']
console.log('surenjun', this.selectedTerType + '');
}

View File

@ -91,6 +91,7 @@ struct UserInfo {
'Param398': '0', //考前上车准备
'Param835': '0', //考前上车准备
'Param850': '0', //考前上车准备
'Param853': '0', //未熄火不能开始考试
}
@State startExam: boolean = false
// 过程照片拍照
@ -537,6 +538,9 @@ struct UserInfo {
if (sys.v_no === '770') {
that.systemParam.Param770Str = sys.v_value;
}
if(sys.v_no === '853'){
that.systemParam.Param853 = sys.v_value;
}
if (sys.v_no === '835') {
that.systemParam.Param835 = sys.v_value;
}
@ -946,8 +950,10 @@ struct UserInfo {
const {isCheckFireOpen} = judgeConfig
const {systemParam,isBoardPrePareSetPopupOpen} = this;
const Param803Str = systemParam.Param803Str
if (Param803Str === '') {
const Param853Str = systemParam.Param853
if (Param803Str === '' && Param853Str != '1') {
return true
}
return new Promise((resolve, reject) => {
if (isCheckFireOpen) {
@ -963,6 +969,14 @@ struct UserInfo {
const ygd = msgArr[8];
const ssc = msgArr[13];
const dw = msgArr[28];
if(Param853Str == '1' && fdjzs * 1 > 0){
this.avPlayer.playAudio(['voice/熄火.mp3'])
promptAction.showToast({
message: '请熄火',
duration: 4000
})
reject(false)
}
// 开始考试信号检测
if (Param803Str !== '') {
//安全带
@ -1482,4 +1496,5 @@ type systemParam = {
'Param398': string, //考前上车准备
'Param835': string, //考前上车准备
'Param850': string, //考前上车准备
'Param853': string, //未熄火不能开始考试
}

View File

@ -69,6 +69,18 @@ export default struct SignDisplayCom {
})
}
Row() {
Text('雷达数据').fontColor(this.active == 3 ? '#FFAD33' : '#e7cba3').fontSize(20 * this.ratio)
}
.backgroundImage(this.active == 3 ? $r('app.media.signal_tabS') : $r('app.media.signal_tab'))
.width(144 * this.ratio)
.height(50 * this.ratio)
.backgroundImageSize({ width: '100%', height: '100%' })
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.active = 3
})
Row() {
Text('原始数据').fontColor(this.active == 2 ? '#FFAD33' : '#e7cba3').fontSize(20 * this.ratio)
}
@ -314,6 +326,30 @@ export default struct SignDisplayCom {
.backgroundImage($r('app.media.km_open'))
.backgroundImageSize({ width: '100%', height: '100%' })
.visibility(this.active == 1 ? Visibility.Visible : Visibility.None)
Row(){
Column() {
Column(){
Text('雷达').fontColor('#fff')
}
Column(){
Text('视觉').fontColor('#fff')
}
.height(436 * this.ratio)
}
.backgroundColor('#282828')
.width(this.ratio * 880)
.height(415 * this.ratio)
.margin({ left: 15 * this.ratio, top: 15 * this.ratio })
}
.width(936 * this.ratio)
.height(460 * this.ratio)
.margin({ left: 10 * this.ratio })
.padding({ left: 10 * this.ratio, right: 10 * this.ratio })
.backgroundImage($r('app.media.km_open'))
.backgroundImageSize({ width: '100%', height: '100%' })
.visibility(this.active == 3 ? Visibility.Visible : Visibility.None)
}
.width('100%')
.height('100%')
@ -323,6 +359,8 @@ export default struct SignDisplayCom {
aboutToDisappear() {
clearInterval(this.interval)
//TODO
console.info('surenjun','123')
}
async aboutToAppear() {

View File

@ -44,7 +44,7 @@ export default struct RealTime {
Row() {
Column() {
Row() {
Text('车道信息').fontColor(this.gpsActive == 0 ? '#2D3C5A' : '#fff').fontSize(20)
Text('车道信息').fontColor(this.gpsActive == 0 ? '#2D3C5A' : '#fff').fontSize(14)
}
.width('100%')
.height(37)

View File

@ -1 +1,86 @@
{"code":1,"data":{"videoChapterList":[{"chapterId":"8","chapterName":"第一章:驾驶证的基本信息、申领和使用","code":"1001","name":"驾驶证申领与使用机动车登记","subjectType":"1","count":"4","chapterVideoList":[{"videoId":"95","name":"第一课:准驾车型","title":"准驾车型是指什么样的驾驶证能开什么样的车我国总计有16种驾照按照ABCD的顺序划分。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822259WBGURTDW.png","videoUrl":"https://ddjdvideo.duolunxc.com/d8cca146136b4036a193ec1c72a1ad84/2e2c2ed873d24f239cd5ca1cb9756bd1-81fdf63dd56b4dfce8ee63e8807d291f-ld.m3u8?auth_key=1726196458-4dd8bdf313b945808f2a62032d00d846-0-14b7843e2ba491a1918177784e37d772","viewCount":50766,"questCount":0,"isView":"0"},{"videoId":"61","name":"第二课:驾驶证的申请条件","title":"驾驶证申请条件,分为年龄条件、身体条件和禁止条件。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/16588222718TK8QETW.png","videoUrl":"https://ddjdvideo.duolunxc.com/b95873736b3e4f1dbd94159c4f88d3c2/fb0562a3d19b40189f7dc2ce8d2b18f6-b8ca137e222c55292b19abeb9472f7b4-ld.m3u8?auth_key=1726196458-185f9fc53e614fd7bc117f2f16e87066-0-9b40a712d59de2385daf195af77df644","viewCount":55988,"questCount":0,"isView":"0"},{"videoId":"96","name":"第三课:初次申请及增加准驾车型","title":"准驾车型的16种车型中有三种是不可以初次申请的包括大型客车A1、牵引车A2、中型客车B1。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822248BLOG5F77.png","videoUrl":"https://ddjdvideo.duolunxc.com/583e26489a714e0c9713de49e297cd52/f8a0eb3a29924468a2be4278b82e84d1-39adbbdba4e730b4615416e186981d91-ld.m3u8?auth_key=1726196459-f37ddff500984ad9913a457914d4b7d9-0-33fa677f8c8e2f2c384d5a133a5a7511","viewCount":19449,"questCount":0,"isView":"0"},{"videoId":"97","name":"第四课:驾驶考试","title":"驾驶考试的内容及标准。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822237ECGG1PQV.png","videoUrl":"https://ddjdvideo.duolunxc.com/84b4a019330b41b48b93818596e1baa2/6a0b423ba95f41f5834ea3c6c4e7e6ab-184dc5731e236cb26fe1a6abf890ae4f-ld.m3u8?auth_key=1726196459-a1daf329320a49b0a19d36c16fbcd398-0-a99a54448590acfde0d26fa0de3dcdd3","viewCount":18434,"questCount":0,"isView":"0"}]},{"chapterId":"10","chapterName":"第一章:文明驾驶","code":"4001","name":"安全文明驾驶常识","subjectType":"4","count":"3","chapterVideoList":[{"videoId":"111","name":"第一课:安全驾驶基础知识","title":"驾驶机动车上道路行驶,驾驶人首先要确保自己处于良好的驾驶状态,避免不文明的驾驶状态和行为会为自己和他人的生命安全埋下隐患。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822228B0QUTOS9.png","videoUrl":"https://ddjdvideo.duolunxc.com/a9c572ca6fb24c0b86c4bb822bc9559d/3b9c3452052d48c695d3bc7701b7e0d2-beb7fa718d09f342c0343f248501ec10-ld.m3u8?auth_key=1726196459-c79a4890ea2745ceb312469186afdfa0-0-47b4001a778636678c70c2feb4d42586","viewCount":22494,"questCount":0,"isView":"0"},{"videoId":"112","name":"第二课:常见的不文明驾驶行为","title":"不遵守交通法律法规的行为,既属于违法行为,也是不文明的驾驶行为,驾驶人应该增加文明驾驶意识,自觉遵守交通规则,安全第一。","photoUrl":"https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822219GA9GTG2J.png","videoUrl":"https://ddjdvideo.duolunxc.com/1bdea813f93a456e890defd3f6d24a42/178aa73b657444989b543dfcd386b4ab-2045d439a68331e4c7b8b1a511d698e1-ld.m3u8?auth_key=1726196459-6d161bab98394c8f981a5df4b07ff77f-0-9527085c0efc3ca3befcb4025b1db1a5","viewCount":10562,"questCount":0,"isView":"0"},{"videoId":"113","name":"第三课:文明礼让驾驶","title":"
{
"code": 1,
"data": {
"videoChapterList": [
{
"chapterId": "8",
"chapterName": "第一章:驾驶证的基本信息、申领和使用",
"code": "1001",
"name": "驾驶证申领与使用机动车登记",
"subjectType": "1",
"count": "4",
"chapterVideoList": [
{
"videoId": "95",
"name": "第一课:准驾车型",
"title": "准驾车型是指什么样的驾驶证能开什么样的车我国总计有16种驾照按照ABCD的顺序划分。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822259WBGURTDW.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/d8cca146136b4036a193ec1c72a1ad84/2e2c2ed873d24f239cd5ca1cb9756bd1-81fdf63dd56b4dfce8ee63e8807d291f-ld.m3u8?auth_key=1726196458-4dd8bdf313b945808f2a62032d00d846-0-14b7843e2ba491a1918177784e37d772",
"viewCount": 50766,
"questCount": 0,
"isView": "0"
},
{
"videoId": "61",
"name": "第二课:驾驶证的申请条件",
"title": "驾驶证申请条件,分为年龄条件、身体条件和禁止条件。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/16588222718TK8QETW.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/b95873736b3e4f1dbd94159c4f88d3c2/fb0562a3d19b40189f7dc2ce8d2b18f6-b8ca137e222c55292b19abeb9472f7b4-ld.m3u8?auth_key=1726196458-185f9fc53e614fd7bc117f2f16e87066-0-9b40a712d59de2385daf195af77df644",
"viewCount": 55988,
"questCount": 0,
"isView": "0"
},
{
"videoId": "96",
"name": "第三课:初次申请及增加准驾车型",
"title": "准驾车型的16种车型中有三种是不可以初次申请的包括大型客车A1、牵引车A2、中型客车B1。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822248BLOG5F77.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/583e26489a714e0c9713de49e297cd52/f8a0eb3a29924468a2be4278b82e84d1-39adbbdba4e730b4615416e186981d91-ld.m3u8?auth_key=1726196459-f37ddff500984ad9913a457914d4b7d9-0-33fa677f8c8e2f2c384d5a133a5a7511",
"viewCount": 19449,
"questCount": 0,
"isView": "0"
},
{
"videoId": "97",
"name": "第四课:驾驶考试",
"title": "驾驶考试的内容及标准。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822237ECGG1PQV.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/84b4a019330b41b48b93818596e1baa2/6a0b423ba95f41f5834ea3c6c4e7e6ab-184dc5731e236cb26fe1a6abf890ae4f-ld.m3u8?auth_key=1726196459-a1daf329320a49b0a19d36c16fbcd398-0-a99a54448590acfde0d26fa0de3dcdd3",
"viewCount": 18434,
"questCount": 0,
"isView": "0"
}
]
},
{
"chapterId": "10",
"chapterName": "第一章:文明驾驶",
"code": "4001",
"name": "安全文明驾驶常识",
"subjectType": "4",
"count": "3",
"chapterVideoList": [
{
"videoId": "111",
"name": "第一课:安全驾驶基础知识",
"title": "驾驶机动车上道路行驶,驾驶人首先要确保自己处于良好的驾驶状态,避免不文明的驾驶状态和行为会为自己和他人的生命安全埋下隐患。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822228B0QUTOS9.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/a9c572ca6fb24c0b86c4bb822bc9559d/3b9c3452052d48c695d3bc7701b7e0d2-beb7fa718d09f342c0343f248501ec10-ld.m3u8?auth_key=1726196459-c79a4890ea2745ceb312469186afdfa0-0-47b4001a778636678c70c2feb4d42586",
"viewCount": 22494,
"questCount": 0,
"isView": "0"
},
{
"videoId": "112",
"name": "第二课:常见的不文明驾驶行为",
"title": "不遵守交通法律法规的行为,既属于违法行为,也是不文明的驾驶行为,驾驶人应该增加文明驾驶意识,自觉遵守交通规则,安全第一。",
"photoUrl": "https://duolunstorage.oss-cn-hangzhou.aliyuncs.com/archive/ddjd/202207/1658822219GA9GTG2J.png",
"videoUrl": "https://ddjdvideo.duolunxc.com/1bdea813f93a456e890defd3f6d24a42/178aa73b657444989b543dfcd386b4ab-2045d439a68331e4c7b8b1a511d698e1-ld.m3u8?auth_key=1726196459-6d161bab98394c8f981a5df4b07ff77f-0-9527085c0efc3ca3befcb4025b1db1a5",
"viewCount": 10562,
"questCount": 0,
"isView": "0"
},
{
"videoId": "113",
"name": "第三课:文明礼让驾驶",
"title": "

View File

@ -209,6 +209,18 @@ export async function examCalcGpsDistance(param:{
return await temp;
}
/**
* @desc
*
*/
/**
* @desc
*
*/
/*
* @desc通用处理函数

View File

@ -468,6 +468,8 @@ export default class Judge {
//所有的科目考试项目(大车&小车)
private testKmItems: any
private plcData: any
//特殊扣分标记
private specialkf:string = ''
// 获取plc数据
getPlcData = async (plc: string) => {
const {fileLog,mndgStr,rmndg} = this;
@ -526,7 +528,7 @@ export default class Judge {
const bytes = await this.getMessageHeartbeat();
bytes && globalThis.judgeUdp.send(bytes)
}, 50)
}, 1000)
globalThis.judgeTimer = judgeTimer;
}
@ -538,14 +540,14 @@ export default class Judge {
// 调代理接口是否断网了
private isJudgeDisConnect: boolean;
// 项目开始接口同步
beginProject = async (ksxm) => {
beginProject = async (ksxm,xmxh?:string) => {
const carInfo = globalThis.carInfo;
const { examSubject,plateNo } = carInfo;
const {judgeUI,fileLog,getSbbm,xmxh,filePath} = this;
const {judgeUI,fileLog,getSbbm,filePath} = this;
const {lsh,idCard,serialNumber,projectsObj,ksdd,kslx,xldm} = judgeUI
const time = await getCurrentTime();
const project = projectsObj[ksxm]
const sbxh = getSbbm(ksxm, xmxh)
const sbxh = getSbbm(ksxm, xmxh || this.xmxh)
const data = {
//系统类别 接口序列号 接口标识
xtlb: '17', jkxlh: serialNumber, jkid: '17C52',
@ -572,15 +574,15 @@ export default class Judge {
promptWxCode('17C52', code)
}
// 项目结束接口同步
endProject = async (ksxm) => {
endProject = async (ksxm,xmxh?:string) => {
const carInfo = globalThis.carInfo;
const deviceNo = globalThis.deviceNo;
const { examSubject,plateNo,carNo } = carInfo;
const {judgeUI,fileLog,getSbxh,xmxh,getSbbm,filePath} = this;
const {judgeUI,fileLog,getSbxh,getSbbm,filePath} = this;
const {lsh,idCard,serialNumber,projectsObj,cdsbInfoObj,ksdd,kslx,xldm,} = judgeUI
const time = await getCurrentTime();
const project = projectsObj[ksxm]
const sbxh = examSubject == 3 ? undefined : getSbbm(ksxm, xmxh)
const sbxh = examSubject == 3 ? undefined : getSbbm(ksxm, xmxh || this.xmxh)
const data = {
xtlb: '17', jkxlh: serialNumber, jkid: '17C55',
@ -600,6 +602,12 @@ export default class Judge {
}
}
const {code} = await this.sendWriteObjectOut(data, filePath)
//科三 & 432=3
if(examSubject == 3 && this.judgeUI.judgeConfigObj['432'] == 2){
this.judgeUI.uploadMileage()
}
if (code === 2300007) {
this.isJudgeDisConnect = true;
}
@ -833,15 +841,15 @@ export default class Judge {
xmdm: xmdm * 1, kfdm
}
})) : [],
//TODO 已考里程待修改
yklc: 0,
yklc: judgeUI.yklc,
special: [],
//TODO 科目三参数临时写死
sczb: (sczb === undefined || sczb == 0) ? 0 : 1,
sczbkf: kfdm,
dmndg: false,
mfxx: false,
mfxxn: false
mfxxn: false,
//科目三特殊扣分项
specialkf:judgeUI.specialkf,
}
console.info(judgeTag, '5.获取开始考试数据完成')
return beginInfo
@ -926,6 +934,8 @@ export default class Judge {
this.judgeUI.totalScore += thisKf.score * 1;
if (kf.xmdm != 20) {
const type = judgeUI.projectsObj[kf.xmdm].type;
console.info('surejun kf=>',JSON.stringify(kf))
console.info('surejun kf_type=>',type)
judgeUI.projectsObj[kf.xmdm].type = (type == 3 || type == 4) ? '4' : '5';
}
break;
@ -948,11 +958,11 @@ export default class Judge {
console.info(judgeTag, '项目取消');
const {examSubject} = this.judgeUI
const xmdm = xmqx.xmdm;
const xmmcCode = judgeUI.projectsObj[xmdm].projectCodeCenter;
const xmmcCode1 = judgeUI.projectsObj[xmdm].projectCodeCenter;
// const voiceCode = getKmProjectCancelVoice(examSubject, xmmcCode);
// avPlayer.playAudio([`voice/${voiceCode}.mp3`],true)
this.judgeUI.projectsObj[xmdm].type = '1';
this.testKmItems[xmmcCode].status = '1';
this.testKmItems[xmmcCode1].status = '1';
break;
}
@ -1066,7 +1076,7 @@ export default class Judge {
if (!isEnd) {
judgeTask.addTask(async () => {
console.info(judgeTag, `项目开始-${xmdm}-${projectsObj[xmdm].name}`)
await beginProject(xmdm)
await beginProject(xmdm,xmxh)
}, {
isDelay: true
})
@ -1095,7 +1105,7 @@ export default class Judge {
if (!projectIsEnd) {
judgeTask.addTask(async () => {
console.info(judgeTag, `项目结束-${xmdm}-${projectsObj[xmdm].name}`)
await endProject(xmdm);
await endProject(xmdm,xmxh)
this.xmmcSingleCode = 0;
this.xmmcEndCode = undefined;
}, {
@ -1173,8 +1183,8 @@ export default class Judge {
const {lsh,idCard,serialNumber,ksdd,projectsObj} = judgeUI
const time = await getCurrentTime();
const project = getProjectInfo(ksxm);
//科目三夜间行驶.模拟灯光、上车准备出现通用评判ksxm为当前进行的项目
const checkProjects = ['17', '41', '1'];
//科目三夜间行驶.模拟灯光、上车准备出现非本项目的扣分ksxm需转换为为当前进行的项目
const checkProjects = ['1', '41', '17'];
//获取正在进行的项目
const inProjects = Reflect.ownKeys(projectsObj).filter(projectKey => projectsObj[projectKey].type == 2);
@ -1184,7 +1194,8 @@ export default class Judge {
commonKsxm = projectCode
}
})
console.info(judgeTag, 'commonKsxm=>' + commonKsxm)
console.info(judgeTag, 'project=>' + project)
const data = {
xtlb: '17', jkxlh: serialNumber, jkid: '17C53',
drvexam: {
@ -1194,7 +1205,7 @@ export default class Judge {
? (commonKsxm
? (projectsObj[commonKsxm].projectCodeCenter)
: (examSubject == 3 ? 30000 : (xmmcEndCode == undefined ? 10000 : xmmcEndCode)))
: project.projectCodeCenter,
: (projectsObj[commonKsxm]?.projectCodeCenter || project.projectCodeCenter),
kfxm: kf.markcatalog,
kfxmmx: `${ksxm},${kf.markserial}`,
sfzmhm: idCard,
@ -1714,7 +1725,7 @@ export default class Judge {
// 检测差分状态
checkDwzt = async (type) => {
const {avPlayer} = this;
const judgeConfig = this.judgeUI.judgeConfig;
const config499 = this.judgeUI.judgeConfigObj['499'];
switch (type) {
case 0:
this.judgeUI.isDwztRight = true;
@ -1722,10 +1733,17 @@ export default class Judge {
case 1:
this.judgeUI.dwztErrorVisible = true;
clearInterval(this.judgeUI.timer);
clearInterval(globalThis.judgeTimer)
avPlayer.playAudio([`voice/差分状态异常.mp3`], true)
setTimeout(() => {
router.back()
}, 3000)
try {
this.checkExamIsEnd(true);
} catch (e) {
this.closeAllFiles()
router.back()
}
}, config499 * 1000)
break;
case 2:
@ -1810,6 +1828,7 @@ export default class Judge {
this.handleRealExam(strData, callBack)
})
await examJudgeSetPerformCallback(async (info) => {
console.info('评判实时数据', info)
const performInfo = JSON.parse(info)
@ -1821,6 +1840,11 @@ export default class Judge {
this.judgeUI.jl = jl
//TODO 待优化 跨组件传值不生效
globalThis.laneData = performInfo.lane;
//特殊扣分标记上传中心
if(performInfo.specialkf !== this.specialkf){
this.judgeUI.uploadMileage(performInfo.specialkf)
this.specialkf = performInfo.specialkf
}
})
// 3.开始考试

View File

@ -2,9 +2,9 @@
export const judgeConfig = {
version:'2024.08.21.01',
//本地目录开关
isTrajectoryOpen: false,
isTrajectoryOpen: true,
//是否开启拍照
isPhotoOpen: true,
isPhotoOpen: false,
//扣分语音是否强制开启
kfVoiceOpen: false,
//忽略的考试项目
@ -16,14 +16,12 @@ export const judgeConfig = {
// 本地模型地址
// modelPath: 'models/model_enc',
// 济南科目三
trajectoryPath: 'logs/2025_04_23_09_50_55_2504755332926_320924199111132926_陈静/judge_exam_data.txt',
trajectoryPath: 'logs/2025_06_20_08_20_09_2250107217821_340823199508126112_左江辉/judge_exam_data.txt',
//四合一画面配置
fourInOneScreen:{
//gps位数
gpsDigit:7
},
// 杭州科目二
// trajectoryPath: 'logs/2024_07_19/0000000000001_342323199501470011_测试学员1_2024_07_19_06_49_12/judge_exam_data.txt',
//TODO 济南临时特殊配置
systemParamConfig:{}
}

View File

@ -0,0 +1,42 @@
import socket from '@ohos.net.socket';
class SafetyOfficer{
// 是否开启安全员
private isOpen:boolean = false
// 心跳端口
private heartBeatPort:number = 8054
// 数据端口
private dataPort:number = 8052
// 本地端口
private localUdpPort:number = 19961
udpClient:socket.UDPSocket
//协议格式:帧头,数据长度,流水号,消息标识,数据区,保留,帧尾
constructor(context) {
let udp: socket.UDPSocket = socket.constructUDPSocketInstance();
this.udpClient = udp
}
//初始化指令
heartBeatFn = async ()=> {
//车牌号 时间戳 空 空 空 空 空 @
'$SBXS,85,20250603115529563,B202,赣A78QK6@360803200602253517@1@20250603115523132@@@@@李从星@001@@001@2506455453517,05,*SBJS'
}
//开始考试
beginExamFn = async ()=>{
//车牌号 考试身份证 状态 开始考试时间 考试次数 考车信息 窗户标注信息 方向盘标注信息 考生姓名 安全员编号 是否合格 安全员姓名 流水号
}
//结束考试
endExamFn = async ()=>{
//车牌号 考试身份证 状态 开始考试时间 考试次数 考车信息 窗户标注信息 方向盘标注信息 考生姓名 安全员编号 是否合格 安全员姓名 流水号
}
//obd&gps相关数据
sendObdData = async ()=>{
//考试员号 考试车型 车牌号 科目类型+考试开始时间 设备信号状态 速度 发动机转速 GPS纬度 GPS经度 主天线位置 GPS东向距离 GPS北向距离
//航向角 俯仰角 高程 项目状态 当前项目编号 场地设备编号 本次考试行驶总距离 扣分值 扣分项数量 n个扣分序号 考车车型 车牌号
//工控机是否在播报语音 安全员姓名
}
}

View File

@ -1,15 +1,13 @@
{
"lockfileVersion": 2,
"lockfileVersion": 1,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6"
},
"packages": {
"@ohos/hypium@1.0.6": {
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz",
"integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==",
"registryType": "ohpm",
"shasum": "3f5fed65372633233264b3447705b0831dfe7ea1"
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz",
"integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ=="
}
}
}