评判udp优化

This commit is contained in:
lixiao 2025-04-07 14:05:15 +08:00
parent 89a192408a
commit d3eee4a3a5
10 changed files with 3157 additions and 2798 deletions

View File

@ -115,6 +115,7 @@ export interface CarInfoType {
isNeedCheck?: string; isNeedCheck?: string;
udpAddress?: string udpAddress?: string
messagePort?: string messagePort?: string
hintPort?: string
} }
export interface ExaminerInfoType { export interface ExaminerInfoType {

View File

@ -8,6 +8,7 @@ import {
ObtainCarExamInfoParams, ObtainCarExamInfoParams,
ObtainCarExamInfoRspBody, ObtainCarExamInfoRspBody,
TimeSynchronizationParams, TimeSynchronizationParams,
TimeSynchronizationRspBody,
VideoConfig VideoConfig
} from '../../model'; } from '../../model';
import dayTs from '../../utils/Date'; import dayTs from '../../utils/Date';

View File

@ -6,6 +6,7 @@ import { GlobalConfig } from '../config';
import Prompt from '@system.prompt'; import Prompt from '@system.prompt';
import FileUtils from '../utils/FileUtils'; import FileUtils from '../utils/FileUtils';
import { EnvironmentConfigurationType } from '../model/Common'; import { EnvironmentConfigurationType } from '../model/Common';
import { BusinessError } from '@ohos.base';
@Entry @Entry
@ -14,24 +15,14 @@ struct Index {
@State textList1: string[] = @State textList1: string[] =
['差分服务器Ip', '响应端口', '中心服务器IP', '响应端口', '子网掩码', '默认网关', 'dns', '后置机IP ', '响应端口', ['差分服务器Ip', '响应端口', '中心服务器IP', '响应端口', '子网掩码', '默认网关', 'dns', '后置机IP ', '响应端口',
'前置机IP', '本地端口'] '前置机IP', '本地端口']
// @State textList2: string[] = []
@State ratio: number = 1700 / 960 @State ratio: number = 1700 / 960
@State inputFontSize: number = 12 //12 @State inputFontSize: number = 12
// @State inputTextList1: string[] = ['172.37.55.191','18782','192.168.7.1','8082','255.255.255.0','192.168.7.170','114.114.114.114','192.168.7.124','20022','172.37.55.59','20122']
@State inputTextList1: string[] = @State inputTextList1: string[] =
['172.37.55.191', '18782', '172.37.55.191', '8082', '255.255.255.0', '192.168.7.1', '114.114.114.114', ['172.37.55.191', '18782', '172.37.55.191', '8082', '255.255.255.0', '192.168.7.1', '114.114.114.114',
'192.168.7.124', '20022', '192.168.7.170', '20122'] '192.168.7.124', '20022', '192.168.7.170', '20122']
//
// @State inputTextList1: string[] = ['192.168.7.170','8084','192.168.7.170','20122','255.255.255.0','192.168.7.1','','','114.114.114.114','112.80.35.83','11055' +
// '',]
// @State inputTextList2: string[] = ['192.168.7.124','20022']
// @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']
@State @Watch('outClick') outFlag: boolean = false; @State @Watch('outClick') outFlag: boolean = false;
// @State inputTextList2: string[] = []
// 112.80.35.83 11052
scroller: Scroller = new Scroller() scroller: Scroller = new Scroller()
private fileUtil: FileUtils private fileUtil: FileUtils
// @State inputTextList2: string[] = ['192.168.36.139','20022']
private context = getContext(this) as common.UIAbilityContext; private context = getContext(this) as common.UIAbilityContext;
build() { build() {
@ -103,15 +94,15 @@ struct Index {
} }
this.fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param)) this.fileUtil.addFile(`${folderPath}/ipConfig.txt`, JSON.stringify(param))
AppStorage.setOrCreate<EnvironmentConfigurationType>("EnvironmentConfiguration", param) AppStorage.setOrCreate<EnvironmentConfigurationType>("EnvironmentConfiguration", param)
// upDateTableByArray('IpConfigTable',[])
ethernet.setIfaceConfig("eth0", { ethernet.setIfaceConfig("eth0", {
mode: 0, mode: ethernet.IPSetMode.STATIC,
ipAddr: this.inputTextList1[9], ipAddr: this.inputTextList1[9],
route: "0.0.0.0", route: "0.0.0.0",
gateway: this.inputTextList1[5], //value.gateway网关 gateway: this.inputTextList1[5], //value.gateway网关
netMask: this.inputTextList1[4], //value.netMask网络掩码 netMask: this.inputTextList1[4], //value.netMask网络掩码
dnsServers: this.inputTextList1[6], dnsServers: this.inputTextList1[6],
}, (error) => { domain: ""
}, (error: BusinessError) => {
if (error) { if (error) {
Prompt.showToast({ Prompt.showToast({
message: '设置失败' + JSON.stringify(error), message: '设置失败' + JSON.stringify(error),
@ -171,21 +162,16 @@ struct Index {
this.inputTextList1[3] = result.centerPort this.inputTextList1[3] = result.centerPort
} }
ethernet.getIfaceConfig("eth0").then(value => {
ethernet.getIfaceConfig("eth0", (error, value) => { console.log("boot_up getIp_new callback ipAddr = " + JSON.stringify(value.ipAddr)); //
if (error) { console.log(" boot_up getIp_new callback mode = " + JSON.stringify(value.mode));
// that.errorMsg='error' console.log("boot_up getIp_new callback route = " + JSON.stringify(value.route));
console.log("boot_up getIp_new callback error = " + JSON.stringify(error)); console.log("boot_up getIp_new callback gateway = " + JSON.stringify(value.gateway));
} else { console.log("boot_up getIp_new callback netMask = " + JSON.stringify(value.netMask));
console.log("boot_up getIp_new callback ipAddr = " + JSON.stringify(value.ipAddr)); // console.log("boot_up getIp_new callback dnsServers = " + JSON.stringify(value.dnsServers));
console.log(" boot_up getIp_new callback mode = " + JSON.stringify(value.mode)); }).catch((error: BusinessError) => {
console.log("boot_up getIp_new callback route = " + JSON.stringify(value.route)); console.log("boot_up getIp_new callback error = " + JSON.stringify(error));
console.log("boot_up getIp_new callback gateway = " + JSON.stringify(value.gateway));
console.log("boot_up getIp_new callback netMask = " + JSON.stringify(value.netMask));
console.log("boot_up getIp_new callback dnsServers = " + JSON.stringify(value.dnsServers));
}
}) })
} }
onPageShow() { onPageShow() {

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,6 @@ export function ArrayToByteArray(array: number[]): Uint8Array {
return view; return view;
} }
/** /**
* 字符串转字节数组 * 字符串转字节数组
* @param number 要转换的数字 * @param number 要转换的数字

View File

@ -2,14 +2,32 @@ import socket from '@ohos.net.socket'
import promptAction from '@ohos.promptAction' import promptAction from '@ohos.promptAction'
import { CarInfoType, EnvironmentConfigurationType } from '../model' import { CarInfoType, EnvironmentConfigurationType } from '../model'
import { UDPTag } from '../config' import { UDPTag } from '../config'
import { BusinessError } from '@ohos.base'
import { FillZero, StringToBytes, StringToASCII } from './Common'
type DealMethod = (value: ArrayBuffer) => string type DealMethod = (value: ArrayBuffer) => string
interface IPConfig { interface MsgExt {
udplocalIp: string id: number,
udplocalIpPort: string list: number[],
udpOppositeIp: string carNo: string,
udpOppositeIpPort: string placeId: string,
}
function generateHead(param: MsgExt): number[] {
let lshNo = AppStorage.get<string>("lsh")
let a = new Uint16Array(StringToASCII(`${param.id}${FillZero(param.placeId, 3)}`))
let b = new Uint32Array(StringToASCII(`${FillZero(param.carNo, 4)}${lshNo}`))
let c = new Uint16Array(param.list.length)
return [...a, ...b, ...c];
}
function exclusive(target: number[]): number[] {
let result = target[0]
for (let i = 1; i < target.length; i++) {
result = result ^ target[i]
}
return [result];
} }
export default class UdpClient { export default class UdpClient {
@ -45,7 +63,7 @@ export default class UdpClient {
this.dealMethod = fun this.dealMethod = fun
} }
onMessage(callback: Function) { onMsg(callback: Function) {
this.messageEvents.push(callback) this.messageEvents.push(callback)
} }
@ -54,24 +72,37 @@ export default class UdpClient {
} }
sendMsg(data: ArrayBuffer | string): Promise<void> { sendMsg(data: ArrayBuffer | string): Promise<void> {
return this.udp?.getState().then(() => { return this.udp.send({
return this.udp.send({ data,
data, address: {
address: { address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1
address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1 }
}
})
}) })
} }
create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { setWholeMsg(params: MsgExt): ArrayBuffer {
let head = generateHead(params);
let headJudge = exclusive(head);
let body = params.list;
let bodyJudge = exclusive(body);
let end = [13, 10];
const arr = [...head, ...headJudge, ...body, ...bodyJudge, ...end]
return new Uint8Array(arr).buffer
}
sendMsgExt(param: MsgExt) {
const msgData = this.setWholeMsg(param)
this.sendMsg(msgData)
}
async create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) {
this.localIp = udpLocalIp this.localIp = udpLocalIp
this.oppositeIp = udpOppositeIp this.oppositeIp = udpOppositeIp
this.localIpPort = udpLocalIpPort this.localIpPort = udpLocalIpPort
this.oppositeIpPort = udpOppositeIpPort this.oppositeIpPort = udpOppositeIpPort
this.udp = socket.constructUDPSocketInstance(); this.udp = socket.constructUDPSocketInstance();
this.bindEvent() this.bindEvent()
this.bindUdp() return this.bindUdp()
} }
offMsg(callback: Function) { offMsg(callback: Function) {
@ -94,70 +125,143 @@ export default class UdpClient {
} }
} }
// 获取后置机信号 // 获取后置机信号
// class ObjUdpClient extends UdpClient { class ObjUdpClient extends UdpClient {
// async init(context: common.UIAbilityContext) { async init(): Promise<void> {
// try { return new Promise((resolve, reject) => {
// const fileUtil = new FileUtils(context) try {
// const data = await fileUtil.readFile("" + '/config/ipConfig.txt'); let result: EnvironmentConfigurationType =
// if (data?.length > 0) { AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")
// const result: IPConfig = JSON.parse(data) if (result) {
// this.create(result.udplocalIp, result.udplocalIpPort, result.udpOppositeIp, result.udpOppositeIpPort) this.create(result.udplocalIp, result.udplocalIpPort, result.udpOppositeIp, result.udpOppositeIpPort)
// } .then(resolve)
// } catch (e) { .catch(reject)
// promptAction.showToast({ }
// message: "初始化obj udp失败" } catch (e) {
// }) promptAction.showToast({
// } message: "初始化obj udp失败"
// } })
// } }
})
}
}
// 给中心发送GPS消息 // 给中心发送GPS消息
class centerUDPClient extends UdpClient { class CenterUDPClient extends UdpClient {
async init() { async init(): Promise<void> {
try { return new Promise((resolve, reject) => {
// const fileUtil = new FileUtils(context) try {
// const data = await fileUtil.readFile("" + '/config/ipConfig.txt'); let result: EnvironmentConfigurationType =
let result: EnvironmentConfigurationType = AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")
AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration") const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo') if (result) {
if (result) { this.create(result.udplocalIp, '8800', carInfo?.udpAddress, carInfo?.messagePort).then(resolve).catch(reject)
this.create(result.udplocalIp, '8800', carInfo?.udpAddress, carInfo?.messagePort) }
} catch (e) {
reject(e)
promptAction.showToast({
message: "初始化中心 udp失败"
})
} }
} catch (e) { })
promptAction.showToast({
message: "初始化中心 udp失败"
})
}
} }
} }
// 顶灯 // 顶灯
class LightUDPClient extends UdpClient { class LightUDPClient extends UdpClient {
async init() { async init(): Promise<void> {
try { return new Promise((resolve, reject) => {
// const fileUtil = new FileUtils(context) try {
// const data = await fileUtil.readFile("" + '/config/ipConfig.txt'); let result: EnvironmentConfigurationType =
let result: EnvironmentConfigurationType = AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")
AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration") if (result) {
if (result) { this.create(result.udplocalIp, '55509', result.udpOppositeIp, result.udpOppositeIpPort)
// const result: IPConfig = JSON.parse(data) .then(resolve)
this.create(result.udplocalIp, '55509', result.udpOppositeIp, result.udpOppositeIpPort) .catch(reject)
}
} catch (e) {
reject(e)
promptAction.showToast({
message: "初始化灯光 udp失败"
})
} }
} catch (e) { })
promptAction.showToast({ }
message: "初始化灯光 udp失败" }
// 评判udp
class JudgeUdp extends UdpClient {
private udpIndex = 0;
private currentUdpIndex = 0;
async init(): Promise<void> {
return new Promise((resolve, reject) => {
try {
let result: EnvironmentConfigurationType =
AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
if (result) {
this.create(result.udplocalIp, '8080', carInfo.udpAddress, carInfo.hintPort).then(resolve).catch(reject)
setInterval(() => {
this.udpIndex += 1
}, 1000)
}
} catch (e) {
reject(e)
promptAction.showToast({
message: "初始化评判 udp失败"
})
}
})
}
send(bytes: number[]) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
if (this.udpIndex > this.currentUdpIndex) {
this.sendMsgExt({
id: 45,
list: bytes,
carNo: carInfo.carNo,
placeId: carInfo.examinationRoomId
}) })
this.currentUdpIndex = this.udpIndex
} }
} }
//申请远程扣分查询
askKf(directives: number) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
centerUDPClient.sendMsgExt({
id: 35,
list: [directives],
carNo: carInfo.carNo,
placeId: carInfo.examinationRoomId,
})
console.info('surenjun', `考车查询扣分项目内容,请求指令为:${directives}`)
}
//确定远程扣分
confirmKf(directives: number, code: number) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
centerUDPClient.sendMsgExt({
id: 37,
list: [directives, code],
carNo: carInfo.carNo,
placeId: carInfo.examinationRoomId
})
console.info('surenjun', `考车发送确定扣分指令,指令为:${directives}`)
}
} }
// obj // obj
// export const objUDPClient = new ObjUdpClient() export const objUDPClient = new ObjUdpClient()
// 中心GPS // 中心GPS
export const CenterUDPClient = new centerUDPClient() export const centerUDPClient = new CenterUDPClient()
// 顶灯 // 顶灯
export const lightUDPClient = new LightUDPClient() export const lightUDPClient = new LightUDPClient()
// 评判
export const judgeUDPClient = new JudgeUdp()

View File

@ -16,7 +16,7 @@ class centralHeartbeat {
// 初始化 // 初始化
init() { init() {
let config: EnvironmentConfigurationType = let config: EnvironmentConfigurationType =
AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration") AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")
this.centralHeartbeatUdp = new UdpClient(); this.centralHeartbeatUdp = new UdpClient();
this.centralHeartbeatUdp.create(config.udplocalIp, config.udplocalIpPort, config.udpOppositeIp, this.centralHeartbeatUdp.create(config.udplocalIp, config.udplocalIpPort, config.udpOppositeIp,
config.udpOppositeIpPort); config.udpOppositeIpPort);
@ -24,7 +24,7 @@ class centralHeartbeat {
// 接受中心远程指令 // 接受中心远程指令
getData(callback: (data: centerCallBackMsgType) => void) { getData(callback: (data: centerCallBackMsgType) => void) {
this.centralHeartbeatUdp.onMessage((data: ArrayBuffer) => { this.centralHeartbeatUdp.onMsg((data: ArrayBuffer) => {
let arr: number[] = [] let arr: number[] = []
let dataView = new DataView(data) let dataView = new DataView(data)
for (let i = 0; i < dataView?.byteLength; ++i) { for (let i = 0; i < dataView?.byteLength; ++i) {

View File

@ -37,7 +37,7 @@ class obtainSignalData {
// 三代机 通过UDP onMessage获取信号 // 三代机 通过UDP onMessage获取信号
if (this.modelNo === "3") { if (this.modelNo === "3") {
this.thirdGenerationMachineUdp.onMessage((data: ArrayBuffer) => { this.thirdGenerationMachineUdp.onMsg((data: ArrayBuffer) => {
const dataView = new DataView(data); const dataView = new DataView(data);
let str = "" let str = ""
for (let i = 0; i < dataView?.byteLength; ++i) { for (let i = 0; i < dataView?.byteLength; ++i) {

View File

@ -1,62 +1,78 @@
import emitter from '@ohos.events.emitter'; import emitter from '@ohos.events.emitter';
import { judgeUDPClient } from '../UdpUtils';
export const EVENTID = { enum EventId {
//远程扣分处理 //远程扣分处理
kfEventId: 35, kfEventId = 35,
//远程扣分查询 //远程扣分查询
kfAskEventId: 36, kfAskEventId = 36,
//远程扣分确认 //远程扣分确认
kfConfirmEventId: 37, kfConfirmEventId = 37,
//远程开始考试 //远程开始考试
beginExamEventId: 11, beginExamEventId = 11,
//远程结束考试 //远程结束考试
endExamEventId: 12 endExamEventId = 12
} }
export default class JudgeEmitter { export default class JudgeEmitter {
private beginExamCallBack: Function = () => {
}
private endExamCallBack: Function = () => {
}
private kfContent: Function = () => {
}
private directives: string
constructor() {
this.init()
}
//监听开始考试 //监听开始考试
public onBeginExam = async (callBack?: Function) => { public onBeginExam(callBack?: Function) {
console.info('surenjun', '注册远程开始考试事件') console.info('surenjun', '注册远程开始考试事件')
this.beginExamCallBack = callBack this.beginExamCallBack = callBack
} }
//监听结束考试 //监听结束考试
public onEndExam = async (callBack?: Function) => { public onEndExam(callBack?: Function) {
console.info('surenjun', '注册远程结束考试事件') console.info('surenjun', '注册远程结束考试事件')
this.endExamCallBack = callBack this.endExamCallBack = callBack
} }
//监听扣分处理 //监听扣分处理
public onKfExam = async (callBack?: Function) => { public onKfExam(callBack?: Function) {
console.info('surenjun', '注册远程扣分考试事件') console.info('surenjun', '注册远程扣分考试事件')
this.kfContent = callBack this.kfContent = callBack
} }
//开始考试 //开始考试
public sendBeginExam = async (content: string) => { public sendBeginExam(content: string) {
emitter.emit({ emitter.emit({
eventId: EVENTID.beginExamEventId eventId: EventId.beginExamEventId
}, { }, {
data: { data: {
directives: content directives: content
} }
}); });
} }
//结束考试 //结束考试
public sendEndExam = async (content: string) => { public sendEndExam(content: string) {
emitter.emit({ emitter.emit({
eventId: EVENTID.endExamEventId eventId: EventId.endExamEventId
}, { }, {
data: { data: {
directives: content directives: content
} }
}); });
} }
private directives: string
//扣分 //扣分
public sendKfContent = async (kfxh: string) => { public sendKfContent(kfxh: string) {
const directives = this.directives const directives = this.directives
console.info('surenjun', `udpEvent收到扣分事件。kfxh=>${kfxh};directives=>${directives}`) console.info('surenjun', `udpEvent收到扣分事件。kfxh=>${kfxh};directives=>${directives}`)
emitter.emit({ emitter.emit({
eventId: EVENTID.kfEventId eventId: EventId.kfEventId
}, { }, {
data: { data: {
directives, directives,
@ -64,17 +80,18 @@ export default class JudgeEmitter {
} }
}); });
} }
//监听扣分指令 //监听扣分指令
public sendOnKf = async (directives: string) => { public sendOnKf(directives: string) {
//TODO 临时存储指令编号
this.directives = directives this.directives = directives
globalThis.judgeUdp.askKf(directives) judgeUDPClient.askKf(Number(directives))
} }
// 获取扣分项目编号 // 获取扣分项目编号
public onConfirmKf = async (kfxh: string) => { public onConfirmKf(kfxh: string) {
const directives = this.directives; const directives = this.directives;
emitter.emit({ emitter.emit({
eventId: EVENTID.kfConfirmEventId eventId: EventId.kfConfirmEventId
}, { }, {
data: { data: {
kfxh, directives kfxh, directives
@ -82,48 +99,28 @@ export default class JudgeEmitter {
}); });
} }
constructor() { public init() {
this.init()
}
init = async () => {
console.info('surenjun', '开始注册udp事件') console.info('surenjun', '开始注册udp事件')
emitter.off(EVENTID.beginExamEventId) emitter.off(EventId.beginExamEventId)
emitter.off(EVENTID.endExamEventId) emitter.off(EventId.endExamEventId)
emitter.off(EVENTID.kfConfirmEventId) emitter.off(EventId.kfConfirmEventId)
emitter.off(EVENTID.kfEventId) emitter.off(EventId.kfEventId)
emitter.on({ emitter.on({
eventId: EVENTID.beginExamEventId eventId: EventId.beginExamEventId
}, () => { }, () => {
this?.beginExamCallBack() this?.beginExamCallBack()
}); });
emitter.on({ emitter.on({
eventId: EVENTID.endExamEventId eventId: EventId.endExamEventId
}, () => { }, () => {
this?.endExamCallBack() this?.endExamCallBack()
}); });
emitter.on({ emitter.on({
eventId: EVENTID.kfEventId eventId: EventId.kfEventId
}, (data) => { }, (data) => {
console.info('surenjun EVENTID.kfEvent' + JSON.stringify(data)) console.info('surenjun EventId.kfEvent' + JSON.stringify(data))
this?.kfContent(data) this?.kfContent(data)
}); });
}
private beginExamCallBack: Function = () => {
}
private endExamCallBack: Function = () => {
}
private confirmExamCallBack: Function = () => {
}
private kfContent: Function = () => {
} }
} }

View File

@ -3,286 +3,166 @@ import systemTime from '@ohos.systemDateTime';
import { testKm2Items, testKm3Items } from '../../pages/judgeSDK/dataTest/index'; import { testKm2Items, testKm3Items } from '../../pages/judgeSDK/dataTest/index';
import { judgeConfig } from '../../pages/judgeSDK/utils/judgeConfig'; import { judgeConfig } from '../../pages/judgeSDK/utils/judgeConfig';
import { examCalcGpsDistance } from '../../pages/judgeSDK/api'; import { examCalcGpsDistance } from '../../pages/judgeSDK/api';
import { judgeUDPClient, lightUDPClient, objUDPClient } from '../UdpUtils';
import { CarInfoType, Gps, Sensor } from '../../model';
import { FillZero, StringToASCII } from '../Common';
export const initJudgeUdp = async () => { interface PLCDataType {
globalThis.serialIndex = 0; sensor: Sensor,
globalThis.udpIndex = 0; gps: Gps,
const udp = await setJudgeUdp()
globalThis.judgeUdp = udp
const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00];
const arrBlueBuffer = Array2Byte(arrBlue).buffer
const lightLineUdp = await setTopLineUdp();
if (lightLineUdp) {
lightLineUdp.send(arrBlueBuffer);
}
globalThis.lightLineUdp = lightLineUdp
let [prevJd, preWd] = [0, 0]
globalThis.udpClient.onMessage_1(async (msg) => {
const stachArr = msg.split(',')
if (stachArr[0] != '#DN_GD') {
return
}
const udpIndex = globalThis.udpIndex;
const isJudge = globalThis.isJudge;
if (udpIndex % 5 === 0 && !isJudge) {
const bytes = await getMessageHeartbeat(msg);
const msgArr = msg.split(',');
const jd = convertGpsCoord2(msgArr[96] * 1);
const wd = convertGpsCoord2(msgArr[95] * 1 || 0);
udp.send(bytes)
if (prevJd && msgArr[83] == 4) {
const distance = await examCalcGpsDistance({
jd1: prevJd,
wd1: preWd,
jd2: jd,
wd2: wd,
h: msgArr[90] * 1 || 1,
})
//@ts-ignore
// globalThis.distanceClass?.setTimeData(((distance / 100).toFixed(2)) * 1)
}
prevJd = jd;
preWd = wd;
}
globalThis.udpIndex += 1
})
} }
export const getMessageHeartbeat = async (msg) => { interface ProjectDataType {
const carInfo = globalThis.carInfo; code: string
const { examSubject, plateNo } = carInfo; status: number
const ksyh = '0000000000000' }
const { fourInOneScreen:{ gpsDigit } } = judgeConfig
const asclshArr = stringToASC(fillZero( interface ProjectItemType {
globalThis.singlePlay code: ProjectDataType
? '1111111111111' status: string
: globalThis.lsh, }
13));
const ascksyhArr = stringToASC(fillZero(examSubject == 2 ? '0000000000000' : '1111111111111', 13)) function convertGpsCoord2(num: number) {
const ascsbxhArr = stringToASC('00000000') const tempNum = Math.floor(num);
// const ascsbxhArr = stringToASC('153216400880') const du = Math.floor(tempNum / 100);
const serialIndex = globalThis.serialIndex const fen = tempNum % 100 + num - tempNum;
const tempData = await getPlcData(msg); return du + fen / 60
const examType = examSubject == 2 ? 2 : 3 }
const { sensor, gps } = tempData;
const { zfxd, yfxd, shtd, ygd, jgd, skd, dh1, dh2, lhq, jsc, ssc, fsc, lb, mkg, aqd, ygq, cs, fdjzs, dw } = sensor function string2Bytes(num: number | string, len: number) {
const { jd, wd, hxj, fyj, hbg, sd } = gps let str = (Math.floor(Number(num))).toString(2);
const translateSignals = getTranslateSignals( if (str.length > len) {
[zfxd, yfxd, shtd, ygd, jgd, skd, dh1, dh2, lhq, jsc, ssc, fsc, lb, mkg, aqd].concat(getDwStatusType(dw)) console.log('数据长度不对~~');
.concat([0, 0, ygq, sensor.wd, 0]) return
)
const translateProject = getTranslateProject();
//@ts-ignore
const translateJd = convertGpsCoord2(wd).toFixed(gpsDigit) * Math.pow(10, gpsDigit);
//@ts-ignore
const translateWd = convertGpsCoord2(jd).toFixed(gpsDigit) * Math.pow(10, gpsDigit)
//@ts-ignore
const translateProjects = translateProject.map(numStr => string2Bytes(parseInt(numStr, 2), 8)[0])
//@ts-ignore
let tempSd = (sd * 1.852).toFixed(0) * 1
if (tempSd < 1) {
tempSd = 0
} }
let byteString = FillZero(str, len);
const arr = [ let arrBytes: number[] = [];
//考生号 for (let i = byteString.length; i > 0; ) {
asclshArr.map(lsh => string2Bytes(lsh, 8)[0]), let j = i - 8;
//考试员号 if (j < 0) {
ascksyhArr.map(ksyh => string2Bytes(ksyh, 8)[0]), j = 0
//科目类型(0:未考试 1:科目二 2:科目三) + 考试开始时间 }
string2Bytes(`${0}${'00:00:000'}`, 4 * 8), let s = byteString.slice(j, i);
// 消息序号 let v = parseInt(s, 2);
string2Bytes(serialIndex, 2 * 8), arrBytes.push(v);
translateSignals, i = i - 8
//@ts-ignore }
string2Bytes(tempSd * 100, 2 * 8), string2Bytes(fdjzs / 100, 8), string2Bytes(translateJd, 4 * 8), return arrBytes;
string2Bytes(translateWd, 4 * 8), string2Bytes(1, 8),
//GPS东向距离
string2Bytes(0, 4 * 8),
//GPS北向距离
string2Bytes(0, 4 * 8),
//航向角 俯仰角 高程(海拔)
//@ts-ignore
string2Bytes((hxj) * 100, 2 * 8), string2Bytes(fyj * 100, 2 * 8), string2Bytes(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 tempArr = [];
arr.forEach(itemArr => {
tempArr = tempArr.concat(itemArr)
})
globalThis.serialIndex = 0;
return Array2Byte(tempArr)
} }
// 中心plc实时信号转换成字节 // 中心plc实时信号转换成字节
const getTranslateSignals = (tempItems) => { function getTranslateSignals(tempItems: number[]) {
const len = Math.floor(tempItems.length / 8); const len = Math.floor(tempItems.length / 8);
const arr = []; const arr: string[] = [];
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const temp = tempItems.slice(i * 8, (i + 1) * 8); arr.push(tempItems.slice(i * 8, (i + 1) * 8).join(''));
arr.push(temp.join(''));
} }
const temp = arr.map(numStr => parseInt(numStr, 2)) return arr.map(numStr => parseInt(numStr, 2)).map(item => string2Bytes(item, 8)[0])
return temp.map(item => string2Bytes(item, 8)[0])
} }
// 中心所有项目转换 // 中心所有项目转换
const getTranslateProject = () => { function getTranslateProject(): string[] {
const examSubject = globalThis.examSubject; const examSubject = AppStorage.get<string>("examSubject");
const tempItems: ProjectItemType[] =
const tempItems = (examSubject == 2 ? testKm2Items : testKm3Items).map(code => { (examSubject === '2' ? testKm2Items : testKm3Items).map((code: ProjectDataType) => {
return { let data: ProjectItemType = {
code, status: '0' code,
} status: '0'
}) }
const arr = []; return data
})
const arr: string[] = [];
for (let i = 0; i <= 4; i++) { for (let i = 0; i <= 4; i++) {
const temp = tempItems.slice(i * 4, (i + 1) * 4); const temp = tempItems.slice(i * 4, (i + 1) * 4);
let tempArr = temp.map(item => item.status) let tempArr = temp.map(item => item.status)
if (i === 4) { if (i === 4) {
tempArr = examSubject == 2 tempArr = examSubject === '2'
//bit36-bit39保留 //bit36-bit39保留
? tempArr.concat(['00', '00']) ? tempArr.concat(['00', '00'])
//bit30-bit39保留 //bit30-bit39保留
: tempArr.concat(['00', '00', '00']) : tempArr.concat(['00', '00', '00'])
} }
// if (i === 3 && examSubject == 3) {
// tempArr = tempArr.concat(['00'])
// }
arr.push(tempArr.join('')); arr.push(tempArr.join(''));
} }
return arr return arr
} }
// 中心实时项目状态转换
const getCenterProjectStatus = (status) => {
switch (status) {
//不考
case 0:
return '00'
//未考
case 1:
return '01'
//已考
case 2:
return '10'
}
}
// plc数据转换成对象 // plc数据转换成对象
const getPlcData = async (plc: string) => { async function getPlcData(plc: string): Promise<PLCDataType> {
const time = await systemTime.getCurrentTime() const time = await systemTime.getCurrentTime()
const p = plc.split(',').map((val, key) => { let origin = plc.split(",")
if (key !== 27 && key !== 92) { let p = origin.map(item => Number(item))
//@ts-ignore let sensor: Sensor = {
return val * 1 aqd: p[19],
} else { mkg: p[14],
return val ssc: p[13],
} jsc: p[12],
}); fsc: p[18],
lhq: p[17],
const tempData = { lb: p[4],
sensor: { skd: p[9],
//安全带 车门门开关 手刹 脚刹 副刹 离合器 喇叭 示宽灯 近光灯 远光灯 jgd: p[7],
aqd: p[19], ygd: p[8],
mkg: p[14], //左方向灯 右方向灯 双跳灯 雾灯 雨刮器 点火1 点火2 发动机转速 档位 车速
ssc: p[13], zfxd: p[2],
jsc: p[12], yfxd: p[3],
fsc: p[18], shtd: p[20],
lhq: p[17], wd: p[10],
lb: p[4], ygq: p[11],
skd: p[9], dh1: p[5],
jgd: p[7], dh2: p[6],
ygd: p[8], fdjzs: p[25],
//左方向灯 右方向灯 双跳灯 雾灯 雨刮器 点火1 点火2 发动机转速 档位 车速 dw: p[28],
zfxd: p[2], cs: p[23],
yfxd: p[3], fxp: Number(origin[27].split('_')[0]),
shtd: p[20], //累计脉冲 溜车脉冲 超声波左后 超声波右后 超声波右前 超声波左前 座椅 仪表盘 后视镜 倒车镜 光照 雨量
wd: p[10], ljmc: p[24],
ygq: p[11], lcmc: 0,
dh1: p[5], csbzh: p[32],
dh2: p[6], csbyh: p[30],
fdjzs: p[25], csbyq: p[31],
dw: p[28], csbzq: p[29],
cs: p[23], zy: 0,
//@ts-ignore 方向盘 tbp: 0,
fxp: p[27].split('_')[0] * 1, hsj: 0,
//累计脉冲 溜车脉冲 超声波左后 超声波右后 超声波右前 超声波左前 座椅 仪表盘 后视镜 倒车镜 光照 雨量 dcj: 0,
ljmc: p[24], gx: 0,
lcmc: 0, yl: 0,
csbzh: p[32], yy: 0,
csbyh: p[30], sde: 0,
csbyq: p[31], xhd: '',
csbzq: p[29], rmndg: 0,
zy: 0, wav: 0,
tbp: 0, mndg: ''
hsj: 0, }
dcj: 0, let gps: Gps = {
gx: 0, bklx: p[56],
yl: 0 dwzt: p[83],
}, jdzt: Number(origin[92].split('-')[0]),
gps: { sj: time,
//TODO 办卡类型 定位差分状态 jd: p[96],
bklx: p[56], wd: p[95],
dwzt: p[83], hxj: p[90],
//@ts-ignore 角度差分状态 fyj: p[91],
jdzt: p[92].split('-')[0] * 1, hbg: p[85],
//TODO gps数据 gdc: p[86],
//gps时间 经度 纬度 航向角 俯仰角 海拔高 高度差 速度 sd: p[97],
sj: time, age: p[87],
jd: p[96], jdyz: p[89],
wd: p[95], wdyz: p[88],
hxj: p[90], dwsxs: p[84],
fyj: p[91], jdsxs: Number(origin[92].split('-')[1])
hbg: p[85],
gdc: p[86],
sd: p[97],
//龄期 经度因子 纬度因子 定位搜星数
age: p[87],
jdyz: p[89],
wdyz: p[88],
dwsxs: p[84],
//@ts-ignore 角度搜星数
jdsxs: p[92].split('-')[1] * 1
},
} }
return tempData return {
sensor,
gps,
}
} }
const getDwStatusType = (dw) => { function getDwStatusType(dw: number) {
switch (dw) { switch (dw) {
case 0: case 0:
return [0, 0, 0, 0] return [0, 0, 0, 0]
@ -301,4 +181,134 @@ const getDwStatusType = (dw) => {
default: default:
return [0, 0, 0, 0] return [0, 0, 0, 0]
} }
} }
export async function initJudgeUdp() {
AppStorage.setOrCreate("serialIndex", 0)
AppStorage.setOrCreate("udpIndex", 0)
const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00];
const arrBlueBuffer = new Uint8Array(arrBlue).buffer
lightUDPClient.sendMsg(arrBlueBuffer);
let prevJd = 0, preWd = 0
objUDPClient.onMsg(async (msg: string) => {
const stashArr = msg.split(',')
if (stashArr[0] != '#DN_GD') {
return
}
const udpIndex = AppStorage.get<number>("udpIndex");
const isJudge = AppStorage.get<boolean>("isJudge");
if (udpIndex % 5 === 0 && !isJudge) {
const bytes = await getMessageHeartbeat(msg);
const msgArr: string[] = msg.split(',');
const jd = convertGpsCoord2(Number(msgArr[96]));
const wd = convertGpsCoord2(Number(msgArr[95]) || 0);
judgeUDPClient.send(bytes)
if (prevJd && Number(msgArr[83]) === 4) {
const distance = await examCalcGpsDistance({
jd1: prevJd,
wd1: preWd,
jd2: jd,
wd2: wd,
h: Number(msgArr[90]) || 1,
})
//@ts-ignore
// globalThis.distanceClass?.setTimeData(((distance / 100).toFixed(2)) * 1)
}
prevJd = jd;
preWd = wd;
}
AppStorage.set("udpIndex", udpIndex + 1)
})
}
export async function getMessageHeartbeat(msg: string): Promise<number[]> {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')
let gpsDigit = judgeConfig.fourInOneScreen.gpsDigit
const asclshArr = StringToASCII(FillZero(
AppStorage.get<boolean>("singlePlay")
? '1111111111111'
: AppStorage.get<string>("lsh"),
13));
const ascksyhArr = StringToASCII(carInfo.examSubject === '2' ? '0000000000000' : '1111111111111')
const ascsbxhArr = StringToASCII('00000000')
const serialIndex = AppStorage.get<number>("serialIndex")
const plcData = await 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(getDwStatusType(plcData.sensor.dw))
.concat([0, 0, plcData.sensor.ygq, plcData.sensor.wd, 0])
const translateSignals = getTranslateSignals(param)
const translateProject = getTranslateProject();
const translateJd = Number(convertGpsCoord2(plcData.gps.wd).toFixed(gpsDigit)) * Math.pow(10, gpsDigit);
const translateWd = Number(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)]
}