diff --git a/entry/src/main/ets/model/Worker.ets b/entry/src/main/ets/model/Worker.ets index edd89f5..f8f0852 100644 --- a/entry/src/main/ets/model/Worker.ets +++ b/entry/src/main/ets/model/Worker.ets @@ -3,7 +3,7 @@ import { CarInfoType, CenterCallBackMsgType, EnvironmentConfigurationType, UDPPa export interface WorkerMessage { config: EnvironmentConfigurationType; carInfo: CarInfoType; - udpParam?: UDPParamType; + centerUdpParam?: UDPParamType; otherMessage: OtherMessageType; } diff --git a/entry/src/main/ets/pages/Index/utils.ets b/entry/src/main/ets/pages/Index/utils.ets index 5db51f3..3f8a172 100644 --- a/entry/src/main/ets/pages/Index/utils.ets +++ b/entry/src/main/ets/pages/Index/utils.ets @@ -139,25 +139,25 @@ async function obtainSerialNumber(data: string) { } //设置流水号 -export async function SetSerialNumber() { - const data = AppStorage.get("liushuiNo") || ""; - const serialNumberTime = AppStorage.get("liushuiDate"); - obtainSerialNumber(data); - const date = dayTs().format('YYYY-MM-DD HH:mm:ss'); - - if (data && serialNumberTime) { - const diffDays = dayTs().diff(serialNumberTime, 'day'); - if (diffDays === 0) { - AppStorage.setOrCreate('liushuiDate', date); - AppStorage.setOrCreate('liushuiNo', '0'); - } else { - AppStorage.setOrCreate('liushuiNo', (Number(data) + 1).toString()); - } - } else { - AppStorage.setOrCreate('liushuiNo', '0'); - AppStorage.setOrCreate('liushuiDate', date); - } -} +// export async function SetSerialNumber() { +// const data = AppStorage.get("liushuiNo") || ""; +// const serialNumberTime = AppStorage.get("liushuiDate"); +// obtainSerialNumber(data); +// const date = dayTs().format('YYYY-MM-DD HH:mm:ss'); +// +// if (data && serialNumberTime) { +// const diffDays = dayTs().diff(serialNumberTime, 'day'); +// if (diffDays === 0) { +// AppStorage.setOrCreate('liushuiDate', date); +// AppStorage.setOrCreate('liushuiNo', '0'); +// } else { +// AppStorage.setOrCreate('liushuiNo', (Number(data) + 1).toString()); +// } +// } else { +// AppStorage.setOrCreate('liushuiNo', '0'); +// AppStorage.setOrCreate('liushuiDate', date); +// } +// } export function CreateAlbum(fileHelper: FileHelper) { const date = dayTs().format("YYYY-MM-DD") diff --git a/entry/src/main/ets/utils/business/CenterUdpBusiness.ets b/entry/src/main/ets/utils/business/CenterUdpBusiness.ets index c192260..a3045da 100644 --- a/entry/src/main/ets/utils/business/CenterUdpBusiness.ets +++ b/entry/src/main/ets/utils/business/CenterUdpBusiness.ets @@ -10,7 +10,7 @@ import { fillZero, string2Bytes } from '../../pages/judgeSDK/utils/Common'; import { NumberToByteArray } from '../Common'; import UdpClient from '../UdpUtils'; import { UDPTag } from '../../config'; -import { SetSerialNumber } from '../../pages/Index/utils'; +import { SerialNumberInstance } from '../SerialNumber'; // 中心UDP业务逻辑 class CenterUDPBusiness { @@ -20,8 +20,11 @@ class CenterUDPBusiness { private headLength: number = 9 private sendId: number = 0 private carInfo: CarInfoType = {} + // 指令 private signNum: number = -1 + // 状态 private statue: string = "" + // 学员流水号 private lsh: string = "" constructor() { @@ -41,11 +44,14 @@ class CenterUDPBusiness { console.log("心跳") // 组装消息,一秒发送一次 this.timer = setInterval(() => { - SetSerialNumber() + // 生成流水号 + SerialNumberInstance.generate() + // SetSerialNumber() const arr = [this.signNum || 0, this.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 = this.lsh || '0000000000000' for (let i = 0; i < str.length; i++) { tmpList.push(NumberToByteArray(str.charCodeAt(i), 1 * 8)[0]) @@ -70,12 +76,15 @@ class CenterUDPBusiness { this.udp.offMsg(cb) } + changeKeyValue(value: OtherMessageType) { + value.signNum && (this.signNum = value.signNum) + value.lsh && (this.lsh = value.lsh) + value.statue && (this.statue = value.statue) + } + // 初始化 async init(config: EnvironmentConfigurationType, carInfo: CarInfoType, otherMessage: OtherMessageType) { try { - // let result: EnvironmentConfigurationType = - // AppStorage.get("EnvironmentConfiguration")! - // const carInfo: CarInfoType = AppStorage.get('carInfo')! this.signNum = otherMessage.signNum || 0 this.statue = otherMessage.statue || '1' this.lsh = otherMessage.lsh || '0000000000000' @@ -137,8 +146,10 @@ class CenterUDPBusiness { } private setMsgHead(params: UDPParamType) { + // 自增流水号 + const lshNo = SerialNumberInstance.get() 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 b = string2Bytes(Number(`${fillZero(params.carNo, 4)}${lshNo}`), 4 * 8); let c = string2Bytes(params.list.length, 2 * 8); let result: number[] = [] a?.forEach(item => result.push(item)) diff --git a/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets b/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets index b911bfe..eb70ddd 100644 --- a/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets +++ b/entry/src/main/ets/utils/business/JudgeUdpBusiness.ets @@ -1,13 +1,14 @@ -import { CarInfoType, EnvironmentConfigurationType, Gps, Sensor, UDPParamType } from '../../model' +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 "../../config"; +import { JudgeConfig } from '../../config'; import { FillZero, StringToASCII } from '../Common'; -import UdpClient from '../UdpUtils' +import UdpClient from '../UdpUtils'; import { CenterUDPBusinessInstance } from './CenterUdpBusiness'; import { ObtainUdpBusinessInstance } from './ObtainUdpBusiness'; import systemTime from '@ohos.systemDateTime'; import { examCalcGpsDistance } from '../../pages/judgeSDK/api'; +import { SerialNumberInstance } from '../SerialNumber'; interface PLCDataType { sensor: Sensor, @@ -48,9 +49,9 @@ function string2Bytes(num: number | string, len: number) { class JudgeUdpBusiness { private static instance: JudgeUdpBusiness + public udpIndex = 0; private udp: UdpClient = new UdpClient() private currentUdpIndex = 0; - public udpIndex = 0; constructor() { if (!JudgeUdpBusiness.instance) { @@ -59,181 +60,6 @@ class JudgeUdpBusiness { 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); - let result: number[] = [] - a?.forEach(item => result.push(item)) - b?.forEach(item => result.push(item)) - c?.forEach(item => result.push(item)) - return result; - } - - 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] - } - } - async getMessageHeartbeat(msg: string): Promise { const carInfo: CarInfoType = AppStorage.get('carInfo')! let gpsDigit = JudgeConfig.fourInOneScreen.gpsDigit @@ -412,6 +238,182 @@ class JudgeUdpBusiness { } }) } + + 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) { + const lshNo = SerialNumberInstance.get() + let a = string2Bytes(Number(`${params.id}${fillZero(params.placeId, 3)}`), 2 * 8); + let b = string2Bytes(Number(`${fillZero(params.carNo, 4)}${lshNo}`), 4 * 8); + let c = string2Bytes(params.list.length, 2 * 8); + let result: number[] = [] + a?.forEach(item => result.push(item)) + b?.forEach(item => result.push(item)) + c?.forEach(item => result.push(item)) + return result; + } + + 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] + } + } } export const JudgeUdpBusinessInstance = new JudgeUdpBusiness() \ No newline at end of file diff --git a/entry/src/main/ets/workers/DifferentialCorrection.ets b/entry/src/main/ets/workers/DifferentialCorrection.ets index 5316e13..6c4180a 100644 --- a/entry/src/main/ets/workers/DifferentialCorrection.ets +++ b/entry/src/main/ets/workers/DifferentialCorrection.ets @@ -1,83 +1,84 @@ // 处理worker线程的消息tcp拿差分改正数,udp给后置机 import worker, { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope } from '@ohos.worker'; import { WorkerTag } from '../config'; -import { WorkerMessage } from '../model'; +import { CenterCallBackMsgType, WorkerBackMessage, WorkerMessage } from '../model'; import { CenterUDPBusinessInstance } from '../utils/business/CenterUdpBusiness'; import { DifferentialSignal } from '../utils/business/DifferentialSignal'; import { ObtainUdpBusinessInstance } from '../utils/business/ObtainUdpBusiness'; const workerPort: ThreadWorkerGlobalScope = worker.workerPort; -/** - * Defines the event handler to be called when the worker thread receives a message sent by the host thread. - * The event handler is executed in the worker thread. - * - * @param e message data - */ + workerPort.onmessage = (e: MessageEvents) => { console.log(WorkerTag, `Worker received message: ${e.data}`); const result: WorkerMessage = JSON.parse(e.data); - // 初始化TCP + initFn(result) + // TODO 内部已经实现,外部未实现 + // 如果外部有这个值就去更新中心这个值 + if (result.otherMessage) { + CenterUDPBusinessInstance.changeKeyValue(result.otherMessage) + } + // 如果外部有这个消息进来就开始给中心发送,暂时看不需要 + // if (result.centerUdpParam) { + // CenterUDPBusinessInstance.sendData(result.centerUdpParam); + // } + getDataFn() +} + +// 初始化函数 +function initFn(result: WorkerMessage) { + // 初始化差分校正TCP DifferentialSignal.init(result.config); + // 定时发送TCP消息 DifferentialSignal.sendData() // 初始化后置机UDP - // ObtainUdpBusinessInstance.init(result.config) + ObtainUdpBusinessInstance.init(result.config) // 初始化中心UDP CenterUDPBusinessInstance.init(result.config, result.carInfo, result.otherMessage) // 中心心跳 CenterUDPBusinessInstance.startHeartBeat() - // 如果外部有这个消息进来就开始给中心发送 - // if (result.udpParam) { - // CenterUDPBusinessInstance.sendData(result.udpParam); - // } +} + +function getDataFn() { // 获取TCP差分改正数信号 DifferentialSignal.getData((data: ArrayBuffer) => { console.log(WorkerTag, "Received differential signal data:", data.byteLength, "bytes") // TCP拿到差分改正数发给后置机 ObtainUdpBusinessInstance.sendData(data) }) - // 监听PLC和GPS信号 - // ObtainUdpBusinessInstance.onMsg((data: string) => { - // // TODO - // // 需要观察 - // console.log(WorkerTag, "后置机消息", data) - // // 收到后置机消息传出去提供给业务,data应该是个string - // workerPort.postMessage( - // JSON.stringify({ - // type: 'obtainUdpData', - // data: data - // } as WorkerBackMessage)) - // }) - // CenterUDPBusinessInstance.onMsg((data: CenterCallBackMsgType) => { - // // TODO - // // 需要观察 - // console.log(WorkerTag, "中心消息", data) - // // 收到中心指令发送出去 - // workerPort.postMessage( - // JSON.stringify({ - // type: 'centerUdpData', - // data: data - // } as WorkerBackMessage) - // ) - // }) + // 后置机回执PLC和GPS + ObtainUdpBusinessInstance.onMsg((data: string) => { + // TODO + // 需要观察 + console.log(WorkerTag, "后置机消息", data) + // 收到后置机消息传出去提供给业务,data应该是个string + workerPort.postMessage( + JSON.stringify({ + type: 'obtainUdpData', + data: data + } as WorkerBackMessage)) + }) + // 中心UDP回执消息 + CenterUDPBusinessInstance.onMsg((data: CenterCallBackMsgType) => { + // TODO + // 需要观察 + console.log(WorkerTag, "中心消息", data) + // 收到中心指令发送出去 + workerPort.postMessage( + JSON.stringify({ + type: 'centerUdpData', + data: data + } as WorkerBackMessage) + ) + }) } -/** - * Defines the event handler to be called when the worker receives a message that cannot be deserialized. - * The event handler is executed in the worker thread. - * - * @param e message data - */ + workerPort.onmessageerror = (e: MessageEvents) => { console.log(WorkerTag, `Worker received message error: ${e.data}`); } -/** - * Defines the event handler to be called when an exception occurs during worker execution. - * The event handler is executed in the worker thread. - * - * @param e error message - */ + workerPort.onerror = (e: ErrorEvent) => { console.log(WorkerTag, `Worker error: ${e.message}, filename: ${e.filename}, lineno: ${e.lineno}, colno: ${e.colno}`) } \ No newline at end of file