diff --git a/entry/src/main/ets/pages/CarCheck.ets b/entry/src/main/ets/pages/CarCheck.ets index c8c8afee..8b1626fe 100644 --- a/entry/src/main/ets/pages/CarCheck.ets +++ b/entry/src/main/ets/pages/CarCheck.ets @@ -8,7 +8,7 @@ import { CarCheckDataType, CarConfigurationParams, CarInfoType, SpzdType } from import { BusinessError } from '@ohos.base'; import { voiceService } from '../utils/Voice'; import dayTs from '../utils/Date'; -import { ObtainSignalData } from '../utils/business/ObtainSignalData'; +import { ObtainUdpBusinessInstance } from '../utils/business/ObtainUdpBusiness'; @Entry @Component @@ -180,7 +180,7 @@ struct Index { getPLCInfo() { const that = this - ObtainSignalData.getData((msg) => { + ObtainUdpBusinessInstance.onMsg((msg) => { if (!this.breakFlag) { return } diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index f87d5d76..e370160b 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -20,8 +20,8 @@ import { BusinessError } from '@ohos.base'; import { delPic } from '../utils/Video'; import { FileHelper } from '../utils/FileHelp'; import { GetCurrentTime } from '../utils/Common'; -import { ObtainSignalData } from '../utils/business/ObtainSignalData'; -import { CentralHeartbeat } from '../utils/business/CentralHeartbeat'; +import { ObtainUdpBusinessInstance } from '../utils/business/ObtainUdpBusiness'; +import { CenterUDPClientInstance } from '../utils/business/CenterUdpBusiness'; import { DrivingDataStorage } from '../utils/business/DrivingDataStorage'; import { initJudgeUdp } from '../utils/business/UdpJudge'; import { centerUDPClient, judgeUDPClient, lightUDPClient, objUDPClient } from '../utils/UdpUtils'; @@ -64,6 +64,181 @@ struct Index { private timeInfo: TimeSynchronizationRspBody private context = getContext(this) as common.UIAbilityContext; + async aboutToAppear() { + this.avPlayer = new VoiceAnnounce(); + this.ratio = AppStorage.get('ratio') + this.initParamFlag = false + this.delLoading = false + this.dialogVisiable = false + this.angle = 0 + this.loading = false + AppStorage.set('lsh', '1111111111111') + // TODO 未改 + // globalThis.errorDialog = this.errorDialog + // globalThis.udpEvent = new UdpEvent(); + GetSyncData("MA_SYSSET").then((res: MASYSSETTableType[]) => { + res.forEach((element) => { + if (element.v_no === "305") { + delPic(Number(element.v_value), 1, this.context) + delPic(Number(element.v_value), 2, this.context) + } + }); + }); + this.singlePlay = AppStorage.get('singlePlay') + this.baseInfo = AppStorage.get('baseInfo') + + UseAuth(this.context).then(() => { + this.initParams() + }).catch(() => { + }); + + if (this.singlePlay == undefined || this.singlePlay == null) { + this.context.resourceManager.getRawFileContent("welcome.wav") + .then(() => { + this.avPlayer.playAudio(['welcome.wav']) + + // this.vocObj.playAudio({ + // type: 1, + // name: 'welcome.wav' + // }) + // let rawFile = value; + }) + .catch((error: BusinessError) => { + console.log("getRawFileContent promise error is " + error); + }); + + this.singlePlay = false + AppStorage.setOrCreate('singlePlay', false) + } + this.num = 0 + AppStorage.setOrCreate('lsh', '1111111111111') + } + + async testXMLToJSONInWorker() { + if (this.loading) { + return + } + // let mode=globalThis.timeInfo?.mode?globalThis.timeInfo?.mode:1 + + // console.log('mode',mode) + + const param: InitializeTheCentralTableType = { + carId: this.carInfo?.carId, + examinationRoomId: this.carInfo?.examinationRoomId, + judgeVersion: this.baseInfo.judgeVersion, + shellVersion: this.baseInfo.version, + paraKdid: this.timeInfo?.paraKdid || this.timeInfo?.kdid, + kdid: this.timeInfo?.kdid || this.timeInfo?.paraKdid, + mode: this.timeInfo?.mode, + context: this.context, + host: AppStorage.get('host'), + centerHost: this.timeInfo?.url, + singlePlay: this.singlePlay + } + this.loading = true + + // getSingleCenterTable(param).then((ret) => { + InitializeTheCentralTable(param).then((ret) => { + if (ret) { + GetSyncData("MA_SYSSET").then(data => { + data.forEach(sys => { + //判断是否能点开始考试 + if (sys.v_no === '854') { + AppStorage.setOrCreate('param854Str', sys.v_value) + } + if (sys.v_no === '824' && decodeURIComponent(sys.v_value) == '0') { + router.pushUrl({ + url: 'pages/CarCheck', + params: { + 'fromIndex': true + } + }, router.RouterMode.Single) + } else { + router.pushUrl({ + url: 'pages/ExaminerLogin', + }, router.RouterMode.Single) + } + }) + }); + + } + }) + + } + + async heartMsg() { + // const signNum = AppStorage.get('signNum') + // const statue = AppStorage.get('statue') + // const lsh = AppStorage.get('lsh') + // const arr = [signNum || 0, statue || 1] + // let tmpList: number[] = []; + // tmpList.push(NumberToByteArray(Number(arr[0]), 1 * 8)[0]) + // tmpList.push(NumberToByteArray(Number(arr[1]), 1 * 8)[0]) + // const str = lsh || '0000000000000' + // for (let i = 0; i < str.length; i++) { + // tmpList.push(NumberToByteArray(str.charCodeAt(i), 1 * 8)[0]) + // } + // TODO 未改 + // const param = { + // id: 31, + // list: tmpList, + // carNo: this.carInfo.carNo, + // placeId: this.carInfo.examinationRoomId + // } + // globalThis.udpClient2.initHeartSendMsg(param,this.context) + // if (globalThis.udpClient2.getStatus()) { + // globalThis.udpClient2.sendMsgExt(param, this.context) + // } + } + + async createAlbum() { + this.fileHelper = new FileHelper(); + const time = GetCurrentTime() + const date = time.split(' ')[0] + this.fileHelper.createAlbum('jt') + // this.fileHelper.createAlbum('2025-01-02') + this.fileHelper.createAlbum('pz'); + this.fileHelper.createAlbum(date); + } + + async initParams() { + //设置plc udp 同步requesthost + + ObtainUdpBusinessInstance.init(); + CenterUDPClientInstance.init(); + CenterUDPClientInstance.startHeartBeat() + CenterUDPClientInstance.onMsg((data: centerCallBackMsgType) => { + if (data.id == 32) { + AppStorage.setOrCreate('signNum', data.body[1]) + } + },) + this.loading = false + await GetDeviceInfo(this.context) + await GetCarInfo() + // getTCP() + this.carInfo = AppStorage.get('carInfo') + this.deviceId = this.carInfo.carNo + await SetCurrentTime() + this.timeInfo = AppStorage.get('timeInfo') + DrivingDataStorage.init(this.context) + DrivingDataStorage.initializeTheDrivingDataFolder() + setTimeout(() => { + this.initParamFlag = true + }, 3000) + initJudgeUdp() + // TODO 摄像头遮挡 + // takePhotoFn(this.context) + clearInterval(this.interval) + this.interval = setInterval(() => { + this.num++ + SetSerialNumber() + if (this.num >= 3) { + this.heartMsg() + } + }, 1000) + this.createAlbum() + } + @Styles commStyle(){ .width(220 * this.ratio * this.dialogRatio) @@ -355,188 +530,4 @@ struct Index { .backgroundImage($r('app.media.index_bg')) .backgroundImageSize({ width: '100%', height: '100%' }) } - - async aboutToAppear() { - this.avPlayer = new VoiceAnnounce(); - this.ratio = AppStorage.get('ratio') - this.initParamFlag = false - this.delLoading = false - this.dialogVisiable = false - this.angle = 0 - this.loading = false - AppStorage.set('lsh', '1111111111111') - // TODO 未改 - // globalThis.errorDialog = this.errorDialog - // globalThis.udpEvent = new UdpEvent(); - GetSyncData("MA_SYSSET").then((res: MASYSSETTableType[]) => { - res.forEach((element) => { - if (element.v_no === "305") { - delPic(Number(element.v_value), 1, this.context) - delPic(Number(element.v_value), 2, this.context) - } - }); - }); - - } - - async testXMLToJSONInWorker() { - if (this.loading) { - return - } - // let mode=globalThis.timeInfo?.mode?globalThis.timeInfo?.mode:1 - - // console.log('mode',mode) - - const param: InitializeTheCentralTableType = { - carId: this.carInfo?.carId, - examinationRoomId: this.carInfo?.examinationRoomId, - judgeVersion: this.baseInfo.judgeVersion, - shellVersion: this.baseInfo.version, - paraKdid: this.timeInfo?.paraKdid || this.timeInfo?.kdid, - kdid: this.timeInfo?.kdid || this.timeInfo?.paraKdid, - mode: this.timeInfo?.mode, - context: this.context, - host: AppStorage.get('host'), - centerHost: this.timeInfo?.url, - singlePlay: this.singlePlay - } - this.loading = true - - // getSingleCenterTable(param).then((ret) => { - InitializeTheCentralTable(param).then((ret) => { - if (ret) { - GetSyncData("MA_SYSSET").then(data => { - data.forEach(sys => { - //判断是否能点开始考试 - if (sys.v_no === '854') { - AppStorage.setOrCreate('param854Str', sys.v_value) - } - if (sys.v_no === '824' && decodeURIComponent(sys.v_value) == '0') { - router.pushUrl({ - url: 'pages/CarCheck', - params: { - 'fromIndex': true - } - }, router.RouterMode.Single) - } else { - router.pushUrl({ - url: 'pages/ExaminerLogin', - }, router.RouterMode.Single) - } - }) - }); - - } - }) - - } - - async heartMsg() { - // const signNum = AppStorage.get('signNum') - // const statue = AppStorage.get('statue') - // const lsh = AppStorage.get('lsh') - // const arr = [signNum || 0, statue || 1] - // let tmpList: number[] = []; - // tmpList.push(NumberToByteArray(Number(arr[0]), 1 * 8)[0]) - // tmpList.push(NumberToByteArray(Number(arr[1]), 1 * 8)[0]) - // const str = lsh || '0000000000000' - // for (let i = 0; i < str.length; i++) { - // tmpList.push(NumberToByteArray(str.charCodeAt(i), 1 * 8)[0]) - // } - // TODO 未改 - // const param = { - // id: 31, - // list: tmpList, - // carNo: this.carInfo.carNo, - // placeId: this.carInfo.examinationRoomId - // } - // globalThis.udpClient2.initHeartSendMsg(param,this.context) - // if (globalThis.udpClient2.getStatus()) { - // globalThis.udpClient2.sendMsgExt(param, this.context) - // } - } - - async onPageShow() { - this.singlePlay = AppStorage.get('singlePlay') - this.baseInfo = AppStorage.get('baseInfo') - // await this.userAuth(); - UseAuth(this.context).then(() => { - this.initParams() - }).catch(() => { - }); - if (this.singlePlay == undefined || this.singlePlay == null) { - // setVideoParam() - this.context.resourceManager.getRawFileContent("welcome.wav") - .then(() => { - this.avPlayer.playAudio(['welcome.wav']) - - // this.vocObj.playAudio({ - // type: 1, - // name: 'welcome.wav' - // }) - // let rawFile = value; - }) - .catch((error: BusinessError) => { - console.log("getRawFileContent promise error is " + error); - }); - - this.singlePlay = false - AppStorage.setOrCreate('singlePlay', false) - } - // this.loading = false - this.num = 0 - AppStorage.setOrCreate('lsh', '1111111111111') - } - - async createAlbum() { - this.fileHelper = new FileHelper(); - const time = GetCurrentTime() - const date = time.split(' ')[0] - this.fileHelper.createAlbum('jt') - // this.fileHelper.createAlbum('2025-01-02') - this.fileHelper.createAlbum('pz'); - this.fileHelper.createAlbum(date); - } - - async initParams() { - //设置plc udp 同步requesthost - objUDPClient.init() - centerUDPClient.init() - lightUDPClient.init() - judgeUDPClient.init() - - ObtainSignalData.init(); - CentralHeartbeat.init(); - CentralHeartbeat.sendHeartData() - CentralHeartbeat.getData((data: centerCallBackMsgType) => { - if (data.id == 32) { - AppStorage.setOrCreate('signNum', data.body[1]) - } - },) - this.loading = false - await GetDeviceInfo(this.context) - await GetCarInfo() - // getTCP() - this.carInfo = AppStorage.get('carInfo') - this.deviceId = this.carInfo.carNo - await SetCurrentTime() - this.timeInfo = AppStorage.get('timeInfo') - DrivingDataStorage.init(this.context) - DrivingDataStorage.initializeTheDrivingDataFolder() - setTimeout(() => { - this.initParamFlag = true - }, 3000) - initJudgeUdp() - // TODO 摄像头遮挡 - // takePhotoFn(this.context) - clearInterval(this.interval) - this.interval = setInterval(() => { - this.num++ - SetSerialNumber() - if (this.num >= 3) { - this.heartMsg() - } - }, 1000) - this.createAlbum() - } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/UserInfo.ets b/entry/src/main/ets/pages/UserInfo.ets index 2b00c2d9..98dfe7ff 100644 --- a/entry/src/main/ets/pages/UserInfo.ets +++ b/entry/src/main/ets/pages/UserInfo.ets @@ -43,7 +43,7 @@ import { GetCurrentUserKeyValue } from './UserInfo/utils'; import dayTs from '../utils/Date'; import { GetCurrentTime, NumberToByteArray } from '../utils/Common'; import DB from '../utils/DbSql'; -import { CentralHeartbeat } from '../utils/business/CentralHeartbeat'; +import { CenterUDPClientInstance } from '../utils/business/CenterUdpBusiness'; @Entry @Component @@ -208,6 +208,20 @@ struct UserInfo { { label: '考试员名', key: 'ksy2' }, ] + private onCenterMsg = (val: centerCallBackMsgType) => { + if (val.id == 32) { + AppStorage.setOrCreate('signNum', val.body[1]) + if (val.body[0] == 7) { + //缺考处理 + this.getqkFn() + this.signNum = val.body[1] + } + } else if (val.id == 42) { + //收到中心缺考确认消息 + this.qkFn() + } + } + aboutToAppear() { this.avPlayer = new VoiceAnnounce(); } @@ -306,6 +320,10 @@ struct UserInfo { } + async onPageHide(): Promise { + CenterUDPClientInstance.offMsg(this.onCenterMsg) + } + //身份证读卡器初始化 openDeviceByIDCard() { AppStorage.setOrCreate('indexComponent', this) @@ -464,19 +482,7 @@ struct UserInfo { } async heartMsg() { - CentralHeartbeat.getData((val: centerCallBackMsgType) => { - if (val.id == 32) { - AppStorage.setOrCreate('signNum', val.body[1]) - if (val.body[0] == 7) { - //缺考处理 - this.getqkFn() - this.signNum = val.body[1] - } - } else if (val.id == 42) { - //收到中心缺考确认消息 - this.qkFn() - } - },) + CenterUDPClientInstance.onMsg(this.onCenterMsg) } //考点端查询缺考指令内容消息请求 @@ -490,7 +496,7 @@ struct UserInfo { placeId: this.carInfo.examinationRoomId as string } // globalThis.udpClient2.sendMsgExt(param, this.context) - CentralHeartbeat.sendData(param) + CenterUDPClientInstance.sendData(param) } async initSysset() { @@ -814,7 +820,7 @@ struct UserInfo { carNo: this.carInfo.carNo, placeId: this.carInfo.examinationRoomId } - CentralHeartbeat.sendData(param) + CenterUDPClientInstance.sendData(param) // globalThis.udpClient2.sendMsgExt(param, this.context) if (res.examinationStuAbsentRsp.head.resultCode == '0') { this.pageIndex = 0 diff --git a/entry/src/main/ets/pages/compontents/FaceCompare.ets b/entry/src/main/ets/pages/compontents/FaceCompare.ets index a56a330a..c09087fc 100644 --- a/entry/src/main/ets/pages/compontents/FaceCompare.ets +++ b/entry/src/main/ets/pages/compontents/FaceCompare.ets @@ -9,7 +9,7 @@ import { VideoConfigData } from '../../mock'; import { CarInfoType, UDPParamType, VideoConfig } from '../../model'; import { NumberToByteArray } from '../../utils/Common'; import FileUtils from '../../utils/FileUtils'; -import { CentralHeartbeat } from '../../utils/business/CentralHeartbeat'; +import { CenterUDPClientInstance } from '../../utils/business/CenterUdpBusiness'; interface ParamType { id?: number; @@ -242,7 +242,7 @@ export default struct FaceCompare { this.callBackFlag = true } } - CentralHeartbeat.sendData(param) + CenterUDPClientInstance.sendData(param) // UDP缺失 // globalThis.udpClient2 && globalThis.udpClient2.sendMsgExt(param, this.context) clearInterval(this.interval) @@ -254,10 +254,10 @@ export default struct FaceCompare { carNo: this.carInfo.carNo, placeId: this.carInfo.examinationRoomId, } - CentralHeartbeat.sendData(param2) + CenterUDPClientInstance.sendData(param2) } }, 1000) - CentralHeartbeat.getData((val)=>{ + CenterUDPClientInstance.getData((val)=>{ if (AppStorage.get('statue') != 3) { return } diff --git a/entry/src/main/ets/utils/UdpUtils.ets b/entry/src/main/ets/utils/UdpUtils.ets index 66671af2..9418d22c 100644 --- a/entry/src/main/ets/utils/UdpUtils.ets +++ b/entry/src/main/ets/utils/UdpUtils.ets @@ -5,8 +5,6 @@ import { UDPTag } from '../config' import { BusinessError } from '@ohos.base' import { FillZero, StringToBytes, StringToASCII } from './Common' -type DealMethod = (value: ArrayBuffer) => string - interface MsgExt { id: number, list: number[], @@ -30,15 +28,18 @@ function exclusive(target: number[]): number[] { return [result]; } +type DealMethod = (value: ArrayBuffer) => T + + export default class UdpClient { private localIp: string = '' private localIpPort: string = '' private oppositeIp: string = '' private oppositeIpPort: string = '' - private udp: socket.UDPSocket = null + protected udp: socket.UDPSocket = null private messageEvents: Array = [] private errorEvents: Array = [] - private dealMethod: DealMethod + private dealMethod: DealMethod bindUdp(): Promise { return this.udp.bind({ @@ -59,18 +60,10 @@ export default class UdpClient { return this.udp?.close() } - setDealMethod(fun: DealMethod) { + setDealMethod(fun: DealMethod) { this.dealMethod = fun } - onMsg(callback: Function) { - this.messageEvents.push(callback) - } - - onError(callback: Function) { - this.errorEvents.push(callback) - } - sendMsg(data: ArrayBuffer | string): Promise { return this.udp.send({ data, @@ -95,7 +88,7 @@ export default class UdpClient { this.sendMsg(msgData) } - async create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { + create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { this.localIp = udpLocalIp this.oppositeIp = udpOppositeIp this.localIpPort = udpLocalIpPort @@ -105,13 +98,24 @@ export default class UdpClient { return this.bindUdp() } + onMsg(callback: Function) { + if (this.messageEvents.findIndex(cb => cb === callback)) { + return + } + this.messageEvents.push(callback) + } + + onError(callback: Function) { + this.errorEvents.push(callback) + } + offMsg(callback: Function) { this.messageEvents = this.messageEvents.filter(cb => cb !== callback) } private bindEvent() { this.udp?.on("message", value => { - let result = this?.dealMethod(value.message) + let result = this.dealMethod(value.message) this.messageEvents.forEach(cb => { cb(result) }) @@ -248,9 +252,6 @@ class JudgeUdpClient extends UdpClient { } } catch (e) { reject(e) - promptAction.showToast({ - message: "初始化评判 udp失败" - }) } }) } diff --git a/entry/src/main/ets/utils/business/CentralHeartbeat.ets b/entry/src/main/ets/utils/business/CenterUdpBusiness.ets similarity index 51% rename from entry/src/main/ets/utils/business/CentralHeartbeat.ets rename to entry/src/main/ets/utils/business/CenterUdpBusiness.ets index 6890db59..c1d0d1ae 100644 --- a/entry/src/main/ets/utils/business/CentralHeartbeat.ets +++ b/entry/src/main/ets/utils/business/CenterUdpBusiness.ets @@ -3,66 +3,53 @@ import { CarInfoType, centerCallBackMsgType, EnvironmentConfigurationType, UDPPa import { fillZero, string2Bytes } from '../../pages/judgeSDK/utils/Common'; import { NumberToByteArray } from '../Common'; import UdpClient from '../UdpUtils'; +import { UDPTag } from '../../config'; -class centralHeartbeat { - private centralHeartbeatUdp: UdpClient; +// 中心UDP业务逻辑 +class CenterUDPBusiness { + private static instance: CenterUDPBusiness + private udp: UdpClient private timer: number = -1 - private headLenth: number = 9 + private headLength: number = 9 private sendId: number = 0 constructor() { + if (!CenterUDPBusiness.instance) { + CenterUDPBusiness.instance = this + } + return CenterUDPBusiness.instance } - // 初始化 - init() { - let config: EnvironmentConfigurationType = - AppStorage.get("EnvironmentConfiguration") - this.centralHeartbeatUdp = new UdpClient(); - this.centralHeartbeatUdp.create(config.udplocalIp, config.udplocalIpPort, config.udpOppositeIp, - config.udpOppositeIpPort); + private dealMsg(msg: ArrayBuffer): centerCallBackMsgType { + let arr: number[] = [] + let dataView = new DataView(msg) + for (let i = 0; i < dataView?.byteLength; ++i) { + arr[i] = dataView?.getUint8(i) + } + let id = Math.floor(Number('0x' + fillZero(arr[1].toString(16), 2) + fillZero(arr[0].toString(16), 2)) / 1000) + let length = Number('0x' + fillZero(arr[7].toString(16), 2) + fillZero(arr[6].toString(16), 2)); + let list: number[] = [] + for (let i = this.headLength; i <= this.headLength + length - 1; i++) { + list.push(arr[i]) + } + return { + id, + length, + body: list, + sendId: this.sendId + } } - // 接受中心远程指令 - getData(callback: (data: centerCallBackMsgType) => void) { - this.centralHeartbeatUdp.onMsg((data: ArrayBuffer) => { - let arr: number[] = [] - let dataView = new DataView(data) - for (let i = 0; i < dataView?.byteLength; ++i) { - arr[i] = dataView?.getUint8(i) - } - let idNum = '0x' + fillZero(arr[1].toString(16), 2) + fillZero(arr[0].toString(16), 2); - let id = Math.floor(Number(idNum) / 1000) - - let lengthNum = '0x' + fillZero(arr[7].toString(16), 2) + fillZero(arr[6].toString(16), 2); - let length = Number(lengthNum); - let list: number[] = [] - for (let i = this.headLenth; i <= this.headLenth + length - 1; i++) { - list.push(arr[i]) - } - const result: centerCallBackMsgType = { - id, - length, - body: list, - sendId: this.sendId - } - callback(result) - - // callback(data); - }); - } - - setWholeMsg(params: UDPParamType) { + private setWholeMsg(params: UDPParamType) { let head: Array = this.setMsgHead(params); let headJudge = this.setMessageExclusive(head); let bodyJudge = this.setMessageExclusive(params.list); let end = [13, 10]; const arr: Array = [...head, ...headJudge, ...params.list, ...bodyJudge, ...end] - return this.Array2Byte(arr).buffer + return this.array2Byte(arr).buffer } - //length消息体bufferlength id消息类型id bodyStr消息体string - // setMsyBody(id,bodyByte){ - Array2Byte(array: Array) { + private array2Byte(array: Array) { const buf = new ArrayBuffer(array.length); const view = new Uint8Array(buf); for (let i = 0; i != array.length; ++i) { @@ -71,15 +58,14 @@ class centralHeartbeat { return view; } - setMsgHead(params: UDPParamType) { + private setMsgHead(params: UDPParamType) { let a = string2Bytes(Number(`${params.id}${fillZero(params.placeId, 3)}`), 2 * 8); let b = string2Bytes(Number(`${fillZero(params.carNo, 4)}${AppStorage.get('lshNo')}`), 4 * 8); let c = string2Bytes(params.list.length, 2 * 8); return [...a, ...b, ...c]; } - //异或运算 - setMessageExclusive(tmpList: Array) { + private setMessageExclusive(tmpList: Array) { let result: number = tmpList[0]; for (let i = 1; i < tmpList.length; i++) { result = result ^ tmpList[i] @@ -90,13 +76,11 @@ class centralHeartbeat { sendData(data: UDPParamType) { this.sendId = data.id const param = this.setWholeMsg(data) - this.centralHeartbeatUdp.sendMsg(param); + this.udp.sendMsg(param); } - // 发送消息 - sendHeartData() { + startHeartBeat() { // 组装消息,一秒发送一次 - // let data = "1"; this.timer = setInterval(() => { const signNum = AppStorage.get('signNum') const statue = AppStorage.get('statue') @@ -117,15 +101,40 @@ class centralHeartbeat { placeId: carInfo.examinationRoomId } const param = this.setWholeMsg(data) - this.centralHeartbeatUdp.sendMsg(param); + this.udp.sendMsg(param); }, 1000); } - // 关闭所有动作 - close() { - clearInterval(this.timer); - this.centralHeartbeatUdp.close() + onMsg(cb: (param: centerCallBackMsgType) => void) { + this.udp.onMsg(cb) + } + + offMsg(cb: (param: centerCallBackMsgType) => void) { + this.udp.offMsg(cb) + } + + async init(): Promise { + return new Promise((resolve, reject) => { + try { + let result: EnvironmentConfigurationType = + AppStorage.get("EnvironmentConfiguration") + const carInfo: CarInfoType = AppStorage.get('carInfo') + this.udp.create(result.udplocalIp, '8800', carInfo?.udpAddress, carInfo?.messagePort) + .then(resolve) + .catch(reject) + this.udp.setDealMethod(this.dealMsg) + } catch (e) { + reject(e) + console.error(UDPTag, "初始化中心 udp失败") + } + }) + } + + // 关闭所有动作 + async close() { + clearInterval(this.timer) + return this.udp.close() } } -export const CentralHeartbeat = new centralHeartbeat(); \ No newline at end of file +export const CenterUDPClientInstance = new CenterUDPBusiness(); \ No newline at end of file diff --git a/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets b/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets new file mode 100644 index 00000000..4a6b1e72 --- /dev/null +++ b/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets @@ -0,0 +1,414 @@ +import { CarInfoType, EnvironmentConfigurationType, Gps, Sensor, UDPParamType } from '../../model' +import { testKm2Items, testKm3Items } from '../../pages/judgeSDK/dataTest'; +import { fillZero, } from '../../pages/judgeSDK/utils/Common'; +import { judgeConfig } from '../../pages/judgeSDK/utils/judgeConfig'; +import { FillZero, StringToASCII } from '../Common'; +import UdpClient from '../UdpUtils' +import { CenterUDPClientInstance } from './CenterUdpBusiness'; +import { ObtainUdpBusinessInstance } from './ObtainUdpBusiness'; +import systemTime from '@ohos.systemDateTime'; +import { examCalcGpsDistance } from '../../pages/judgeSDK/api'; + +interface PLCDataType { + sensor: Sensor, + gps: Gps, +} + +interface ProjectDataType { + code: string + status: number +} + +interface ProjectItemType { + code: ProjectDataType + status: string +} + +function string2Bytes(num: number | string, len: number) { + let str = (Math.floor(Number(num))).toString(2); + if (str.length > len) { + console.log('数据长度不对~~'); + return + } + let byteString = FillZero(str, len); + + let arrBytes: number[] = []; + for (let i = byteString.length; i > 0; ) { + let j = i - 8; + if (j < 0) { + j = 0 + } + let s = byteString.slice(j, i); + let v = parseInt(s, 2); + arrBytes.push(v); + i = i - 8 + } + return arrBytes; +} + +class JudgeUdpBusiness { + private static instance: JudgeUdpBusiness + private udp: UdpClient + private udpIndex = 0; + private currentUdpIndex = 0; + + constructor() { + if (!JudgeUdpBusiness.instance) { + JudgeUdpBusiness.instance = this + } + return JudgeUdpBusiness.instance + } + + private setWholeMsg(params: UDPParamType) { + let head: Array = this.setMsgHead(params); + let headJudge = this.setMessageExclusive(head); + let bodyJudge = this.setMessageExclusive(params.list); + let end = [13, 10]; + const arr: Array = [...head, ...headJudge, ...params.list, ...bodyJudge, ...end] + return this.array2Byte(arr).buffer + } + + private array2Byte(array: Array) { + const buf = new ArrayBuffer(array.length); + const view = new Uint8Array(buf); + for (let i = 0; i != array.length; ++i) { + view[i] = array[i] & 0xFF; + } + return view; + } + + private setMsgHead(params: UDPParamType) { + let a = string2Bytes(Number(`${params.id}${fillZero(params.placeId, 3)}`), 2 * 8); + let b = string2Bytes(Number(`${fillZero(params.carNo, 4)}${AppStorage.get('lshNo')}`), 4 * 8); + let c = string2Bytes(params.list.length, 2 * 8); + return [...a, ...b, ...c]; + } + + private setMessageExclusive(tmpList: Array) { + let result: number = tmpList[0]; + for (let i = 1; i < tmpList.length; i++) { + result = result ^ tmpList[i] + } + return [result]; + } + + private convertGpsCoord2(num: number) { + const tempNum = Math.floor(num); + const du = Math.floor(tempNum / 100); + const fen = tempNum % 100 + num - tempNum; + return du + fen / 60 + } + + // 中心plc实时信号转换成字节 + private getTranslateSignals(tempItems: number[]) { + const len = Math.floor(tempItems.length / 8); + const arr: string[] = []; + for (let i = 0; i < len; i++) { + arr.push(tempItems.slice(i * 8, (i + 1) * 8).join('')); + } + return arr.map(numStr => parseInt(numStr, 2)).map(item => string2Bytes(item, 8)[0]) + } + + // 中心所有项目转换 + private getTranslateProject(): string[] { + const examSubject = AppStorage.get("examSubject"); + const tempItems: ProjectItemType[] = + (examSubject === '2' ? testKm2Items : testKm3Items).map((code: ProjectDataType) => { + let data: ProjectItemType = { + code, + status: '0' + } + return data + }) + const arr: string[] = []; + for (let i = 0; i <= 4; i++) { + const temp = tempItems.slice(i * 4, (i + 1) * 4); + let tempArr = temp.map(item => item.status) + if (i === 4) { + tempArr = examSubject === '2' + //bit36-bit39保留 + ? tempArr.concat(['00', '00']) + //bit30-bit39保留 + : tempArr.concat(['00', '00', '00']) + } + + arr.push(tempArr.join('')); + } + return arr + } + + // plc数据转换成对象 + private async getPlcData(plc: string): Promise { + const time = await systemTime.getCurrentTime() + let origin = plc.split(",") + let p = origin.map(item => Number(item)) + let sensor: Sensor = { + aqd: p[19], + mkg: p[14], + ssc: p[13], + jsc: p[12], + fsc: p[18], + lhq: p[17], + lb: p[4], + skd: p[9], + jgd: p[7], + ygd: p[8], + //左方向灯 右方向灯 双跳灯 雾灯 雨刮器 点火1 点火2 发动机转速 档位 车速 + zfxd: p[2], + yfxd: p[3], + shtd: p[20], + wd: p[10], + ygq: p[11], + dh1: p[5], + dh2: p[6], + fdjzs: p[25], + dw: p[28], + cs: p[23], + fxp: Number(origin[27].split('_')[0]), + //累计脉冲 溜车脉冲 超声波左后 超声波右后 超声波右前 超声波左前 座椅 仪表盘 后视镜 倒车镜 光照 雨量 + ljmc: p[24], + lcmc: 0, + csbzh: p[32], + csbyh: p[30], + csbyq: p[31], + csbzq: p[29], + zy: 0, + tbp: 0, + hsj: 0, + dcj: 0, + gx: 0, + yl: 0, + yy: 0, + sde: 0, + xhd: '', + rmndg: 0, + wav: 0, + mndg: '' + } + let gps: Gps = { + bklx: p[56], + dwzt: p[83], + jdzt: Number(origin[92].split('-')[0]), + sj: time, + jd: p[96], + wd: p[95], + hxj: p[90], + fyj: p[91], + hbg: p[85], + gdc: p[86], + sd: p[97], + age: p[87], + jdyz: p[89], + wdyz: p[88], + dwsxs: p[84], + jdsxs: Number(origin[92].split('-')[1]) + } + + return { + sensor, + gps, + } + } + + private getDwStatusType(dw: number) { + switch (dw) { + case 0: + return [0, 0, 0, 0] + case 1: + return [0, 0, 0, 1] + case 2: + return [0, 0, 1, 0] + case 3: + return [0, 0, 1, 1] + case 4: + return [0, 1, 0, 0] + case 5: + return [0, 1, 0, 1] + case 9: + return [1, 0, 0, 1] + default: + return [0, 0, 0, 0] + } + } + + private async getMessageHeartbeat(msg: string): Promise { + const carInfo: CarInfoType = AppStorage.get('carInfo') + let gpsDigit = judgeConfig.fourInOneScreen.gpsDigit + const asclshArr = StringToASCII(FillZero( + AppStorage.get("singlePlay") + ? '1111111111111' + : AppStorage.get("lsh"), + 13)); + const ascksyhArr = StringToASCII(carInfo.examSubject === '2' ? '0000000000000' : '1111111111111') + const ascsbxhArr = StringToASCII('00000000') + const serialIndex = AppStorage.get("serialIndex") + const plcData = await this.getPlcData(msg); + let param: number[] = Object.entries(plcData.sensor) + .filter((item: [string, number]) => { + let keys = + ["zfxd", "yfxd", "shtd", "ygd", "jgd", "skd", "dh1", "dh2", "lhq", "jsc", "ssc", "fsc", "lb", "mkg", "aqd"] + return keys.indexOf(item[0]) + }) + .map((item: [string, number]) => item[1]) + .concat(this.getDwStatusType(plcData.sensor.dw)) + .concat([0, 0, plcData.sensor.ygq, plcData.sensor.wd, 0]) + const translateSignals = this.getTranslateSignals(param) + const translateProject = this.getTranslateProject(); + const translateJd = Number(this.convertGpsCoord2(plcData.gps.wd).toFixed(gpsDigit)) * Math.pow(10, gpsDigit); + const translateWd = Number(this.convertGpsCoord2(plcData.gps.jd).toFixed(gpsDigit)) * Math.pow(10, gpsDigit) + const translateProjects = translateProject.map(numStr => string2Bytes(parseInt(numStr, 2), 8)[0]) + let tempSd = Number((plcData.gps.sd * 1.852).toFixed(0)) + if (tempSd < 1) { + tempSd = 0 + } + const arr: number[][] = [ + //考生号 + asclshArr.map(lsh => string2Bytes(lsh, 8)[0]), + //考试员号 + ascksyhArr.map(ksyh => string2Bytes(ksyh, 8)[0]), + //科目类型(0:未考试 1:科目二 2:科目三) + 考试开始时间 + string2Bytes(`${0}${'00:00:000'}`, 4 * 8), + // 消息序号 + string2Bytes(serialIndex, 2 * 8), + translateSignals, + string2Bytes(tempSd * 100, 2 * 8), + string2Bytes(plcData.sensor.fdjzs / 100, 8), + string2Bytes(translateJd, 4 * 8), + string2Bytes(translateWd, 4 * 8), string2Bytes(1, 8), + //GPS东向距离 + string2Bytes(0, 4 * 8), + //GPS北向距离 + string2Bytes(0, 4 * 8), + //航向角 + string2Bytes(plcData.gps.hxj * 100, 2 * 8), + //俯仰角 + string2Bytes(plcData.gps.fyj * 100, 2 * 8), + // 高程(海拔) + string2Bytes(plcData.gps.hbg * 100, 4 * 8), + //dddd + translateProjects, + //当前项目编号 + string2Bytes(0, 8), + //场地设备编号 + ascsbxhArr.map(sbxh => string2Bytes(sbxh, 8)[0]), + //本次考试行驶距离 + string2Bytes(0, 2 * 8), + //扣分值 + string2Bytes(0, 2 * 8), + //扣分数 + string2Bytes(0, 2 * 8), + //扣分项数量 + string2Bytes(0, 8), + //n个扣分序号 + // [].map(kf => string2Bytes(kf.markcatalog, 8)), + [], + //牵引车第二gps精度、纬度 + string2Bytes(0, 4 * 8), string2Bytes(0, 4 * 8), + //牵引车第二航向角 + string2Bytes(0, 2 * 8), + //摩托压线 Byte[20], + string2Bytes(0, 20 * 8), + //考试用时 + string2Bytes(FillZero(0, 4), 4 * 8), + //项目用时 + string2Bytes(FillZero(0, 2), 2 * 8), + //设备信号状态 + string2Bytes(0, 4 * 8), + ] + let result: number[] = []; + arr.forEach(itemArr => { + result = result.concat(itemArr) + }) + AppStorage.setOrCreate("serialIndex", 0) + return [...new Uint8Array(result)] + } + + send(data: UDPParamType) { + const param = this.setWholeMsg(data) + this.udp.sendMsg(param); + } + + sendData(bytes: number[]) { + const carInfo: CarInfoType = AppStorage.get('carInfo') + if (this.udpIndex > this.currentUdpIndex) { + this.udp.sendMsgExt({ + id: 45, + list: bytes, + carNo: carInfo.carNo, + placeId: carInfo.examinationRoomId + }) + this.currentUdpIndex = this.udpIndex + } + } + + //申请远程扣分查询 + askKf(directives: number) { + const carInfo: CarInfoType = AppStorage.get('carInfo') + CenterUDPClientInstance.sendData({ + id: 35, + list: [directives], + carNo: carInfo.carNo, + placeId: carInfo.examinationRoomId, + }) + console.info('surenjun', `考车查询扣分项目内容,请求指令为:${directives}`) + } + + //确定远程扣分 + confirmKf(directives: number, code: number) { + const carInfo: CarInfoType = AppStorage.get('carInfo') + CenterUDPClientInstance.sendData({ + id: 37, + list: [directives, code], + carNo: carInfo.carNo, + placeId: carInfo.examinationRoomId + }) + console.info('surenjun', `考车发送确定扣分指令,指令为:${directives}`) + } + + async init(): Promise { + return new Promise((resolve, reject) => { + try { + let result: EnvironmentConfigurationType = + AppStorage.get("EnvironmentConfiguration") + const carInfo: CarInfoType = AppStorage.get('carInfo') + this.udp.create(result.udplocalIp, '8080', carInfo.udpAddress, carInfo.hintPort).then(resolve).catch(reject) + ObtainUdpBusinessInstance.onMsg(async (msg: string) => { + let prevJd = 0, preWd = 0 + + const stashArr = msg.split(',') + if (stashArr[0] != '#DN_GD') { + return + } + const udpIndex = AppStorage.get("udpIndex"); + const isJudge = AppStorage.get("isJudge"); + if (udpIndex % 5 === 0 && !isJudge) { + const bytes = await this.getMessageHeartbeat(msg); + const msgArr: string[] = msg.split(','); + const jd = this.convertGpsCoord2(Number(msgArr[96])); + const wd = this.convertGpsCoord2(Number(msgArr[95]) || 0); + this.sendData(bytes) + if (prevJd && Number(msgArr[83]) === 4) { + await examCalcGpsDistance({ + jd1: prevJd, + wd1: preWd, + jd2: jd, + wd2: wd, + h: Number(msgArr[90]) || 1, + }) + } + prevJd = jd; + preWd = wd; + } + AppStorage.set("udpIndex", udpIndex + 1) + }) + setInterval(() => { + this.udpIndex += 1 + }, 1000) + } catch (e) { + reject(e) + } + }) + } +} + +export const JudgeUdpBusinessInstance = new JudgeUdpBusiness() \ No newline at end of file diff --git a/entry/src/main/ets/utils/business/ObtainSignalData.ets b/entry/src/main/ets/utils/business/ObtainSignalData.ets deleted file mode 100644 index 47081385..00000000 --- a/entry/src/main/ets/utils/business/ObtainSignalData.ets +++ /dev/null @@ -1,70 +0,0 @@ -import { GlobalConfig } from '../../config' -import { EnvironmentConfigurationType } from '../../model' -import UdpClient from '../UdpUtils' - -// 获取PLC GPS信号 -class obtainSignalData { - // 三代机UDP - private thirdGenerationMachineUdp: UdpClient - // 几代机 - private modelNo: string = "3" - - constructor() { - this.modelNo = GlobalConfig.modelNo - } - - // 一些初始化 - init() { - if (this.modelNo === "0") { - } else if (this.modelNo === "1") { - } else if (this.modelNo === "2") { - } else if (this.modelNo === "3") { - // 初始化UDP - let config: EnvironmentConfigurationType = - AppStorage.get("EnvironmentConfiguration") - this.thirdGenerationMachineUdp = new UdpClient() - this.thirdGenerationMachineUdp.create(config.udplocalIp, config.udplocalIpPort, config.udpOppositeIp, - config.udpOppositeIpPort) - } - - } - - // 获取信号 - getData(callback: (data: string) => void) { - // 一代机 - - // 二代机 - - // 三代机 通过UDP onMessage获取信号 - if (this.modelNo === "3") { - this.thirdGenerationMachineUdp.onMsg((data: ArrayBuffer) => { - const dataView = new DataView(data); - let str = "" - for (let i = 0; i < dataView?.byteLength; ++i) { - let c = String.fromCharCode(dataView?.getUint8(i)) - if (c !== "\n") { - str += c - } - } - callback(str) - }) - } - // 一体机 - } - - // 发送数据 - sendData(data: string) { - // 一代机 - - // 二代机 - - // 三代机 通过UDP发送数据 - if (this.modelNo === "3") { - this.thirdGenerationMachineUdp.sendMsg(data) - } - // 一体机 - - } -} - -export const ObtainSignalData = new obtainSignalData() \ No newline at end of file diff --git a/entry/src/main/ets/utils/business/ObtainUdpBusiness.ets b/entry/src/main/ets/utils/business/ObtainUdpBusiness.ets new file mode 100644 index 00000000..ed0cbd1c --- /dev/null +++ b/entry/src/main/ets/utils/business/ObtainUdpBusiness.ets @@ -0,0 +1,168 @@ +import { GlobalConfig } from '../../config' +import { EnvironmentConfigurationType } from '../../model' +import UdpClient from '../UdpUtils' + +// 获取PLC GPS信号 +class ObtainUdpBusiness { + // 三代机UDP + private thirdGenerationMachineUdp: UdpClient + // 几代机 + private modelNo: string = "3" + + constructor() { + this.modelNo = GlobalConfig.modelNo + } + + private initSecondaryBoard() { + + } + + private initFirstGeneration() { + + } + + private initSecondGeneration() { + + } + + private initThirdGeneration() { + let config: EnvironmentConfigurationType = + AppStorage.get("EnvironmentConfiguration") + this.thirdGenerationMachineUdp = new UdpClient() + this.thirdGenerationMachineUdp.create(config.udplocalIp, config.udplocalIpPort, config.udpOppositeIp, + config.udpOppositeIpPort) + this.thirdGenerationMachineUdp.setDealMethod(this.dealThirdGenerationMsg) + } + + private dealSecondaryBoardMsg() { + + } + + private dealFirstGenerationMsg() { + + } + + private dealSecondGenerationMsg() { + + } + + private dealThirdGenerationMsg(data: ArrayBuffer) { + const dataView = new DataView(data); + let str = "" + for (let i = 0; i < dataView?.byteLength; ++i) { + let c = String.fromCharCode(dataView?.getUint8(i)) + if (c !== "\n") { + str += c + } + } + return str + } + + private onSecondaryBoardMsg(cb: Function) { + + } + + private onFirstGenerationMsg(cb: Function) { + + } + + private onSecondGenerationMsg(cb: Function) { + + } + + private onThirdGenerationMsg(cb: Function) { + this.thirdGenerationMachineUdp.onMsg(cb) + } + + private sendSecondaryBoardMsg(data: string) { + + } + + private sendFirstGenerationMsg(data: string) { + + } + + private sendSecondGenerationMsg(data: string) { + + } + + private sendThirdGenerationMsg(data: string) { + this.thirdGenerationMachineUdp.sendMsg(data) + } + + init() { + switch (this.modelNo) { + case "0": + this.initSecondaryBoard() + break + case "1": + this.initFirstGeneration() + break + case "2": + this.initSecondGeneration() + break + case "3": + this.initThirdGeneration() + break + default: + this.initFirstGeneration() + break + } + } + + onMsg(callback: (data: string) => void) { + switch (this.modelNo) { + case "0": + this.onSecondaryBoardMsg(callback) + break + case "1": + this.onFirstGenerationMsg(callback) + break + case "2": + this.onSecondGenerationMsg(callback) + break + case "3": + this.onThirdGenerationMsg(callback) + break + default: + break + } + } + + offMsg(cb: Function) { + switch (this.modelNo) { + case "0": + break + case "1": + break + case "2": + break + case "3": + this.thirdGenerationMachineUdp.offMsg(cb) + break + default: + break + } + } + + sendData(data: string) { + switch (this.modelNo) { + case "0": + this.sendSecondaryBoardMsg(data) + break + case "1": + this.sendFirstGenerationMsg(data) + break + case "2": + this.sendSecondGenerationMsg(data) + break + case "3": + this.sendThirdGenerationMsg(data) + break + default: + break + } + } +} + +export const ObtainUdpBusinessInstance = new ObtainUdpBusiness() \ No newline at end of file