Compare commits

...

5 Commits

Author SHA1 Message Date
wangzhongjie
3999e1d32b fix: 优化一些公共方法 2025-06-18 15:24:10 +08:00
wangzhongjie
163793b5b1 fix: 优化一些公共方法 2025-06-18 14:42:01 +08:00
wangzhongjie
5ea66a4bae fix: 优化中心udp 2025-06-18 14:15:05 +08:00
wangzhongjie
59b95dc609 fix: 优化评判UDP 2025-06-17 09:10:16 +08:00
wangzhongjie
339dc43493 fix: 优化评判UDP 2025-06-17 09:06:18 +08:00
14 changed files with 244 additions and 238 deletions

View File

@ -32,3 +32,6 @@ export const EntryTag = '[Entry]';
//worker tag
export const WorkerTag = '[Worker]';
//中心udp
export const CenterUdpTag = '[CenterUdpBusiness]'

View File

@ -1,8 +1,6 @@
import common from '@ohos.app.ability.common';
// ------------------------------
// 基础共用类型
// ------------------------------
import { MA_SYSTEMPARMType } from './Table';
/** 基础考试字段 */
interface BaseExamFields {
@ -742,7 +740,7 @@ export interface JudgePerformInfo {
lane: PerLane
}
export interface PerLane {
export interface PerLane {
MapRoad_Code_No: string
MapRoad_Name: string
TouchLineType: number
@ -821,4 +819,17 @@ export interface WuxiExamType {
}
export interface PLCDataType {
sensor: Sensor,
gps: Gps,
}
export interface ProjectDataType {
code: string
status: number
}
export interface ProjectItemType {
code: ProjectDataType
status: string
}

View File

@ -5,6 +5,7 @@ export interface WorkerMessage {
carInfo: CarInfoType;
centerUdpParam?: UDPParamType;
otherMessage: OtherMessageType;
singlePlay?: boolean
}
export interface OtherMessageType {

View File

@ -11,7 +11,6 @@ import { BusinessError } from '@ohos.base';
import { delPic } from '../utils/Video';
import { FileHelper } from '../utils/FileHelp';
import { DrivingDataStorage } from '../utils/business/DrivingDataStorage';
import { JudgeUdpBusinessInstance } from '../utils/business/JudgeUdpBusiness';
import { JudgeEmitterInstance } from '../utils/business/UdpEvent';
import HeaderComponent from './compontents/Header';
import CardComponent from './Index/Card';
@ -38,6 +37,7 @@ struct Index {
@State fd: number = -1;
@State carInfo: CarInfoType = {};
@State num: number = 0;
@State isPlay: boolean = false;
// 请求网络表等待弹窗
customDialogController: CustomDialogController = new CustomDialogController({
builder: LoadingComponent(),
@ -78,7 +78,10 @@ struct Index {
async onPageShow(): Promise<void> {
console.log("首页 onPageShow")
await UseAuth(this.context)
this.avPlayer.playAudio(['welcome.wav'])
if (!this.isPlay) {
this.avPlayer.playAudio(['welcome.wav'])
this.isPlay = true
}
this.baseInfo = AppStorage.get<BaseInfoType>('baseInfo')!
this.initParams()
@ -184,7 +187,7 @@ struct Index {
this.timeInfo = AppStorage.get<TimeSynchronizationRspBody>('timeInfo')!
DrivingDataStorage.init(this.context)
DrivingDataStorage.initializeTheDrivingDataFolder()
JudgeUdpBusinessInstance.init()
// JudgeUdpBusinessInstance.init()
// TODO 摄像头遮挡
// takePhotoFn(this.context)
// TODO

View File

@ -43,8 +43,7 @@ import {
} from '../model';
import { GetSyncData } from '../utils/table/Operation';
import dayTs from '../utils/Date';
import { GetCurrentTime } from '../utils/Common';
import { chunkArr } from './judgeSDK/utils/Common';
import { CutArray, GetCurrentTime } from '../utils/Common';
import FileUtils from '../utils/FileUtils';
@ -812,7 +811,7 @@ struct Index {
if (this.examSubject == "2") {
Flex({ wrap: FlexWrap.Wrap, direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
List({}) {
ForEach(chunkArr(this.projects, 2), (item: [ProjectInfo, ProjectInfo]) => {
ForEach(CutArray(this.projects, 2), (item: [ProjectInfo, ProjectInfo]) => {
ListItem() {
Row() {
Row() {

View File

@ -28,7 +28,8 @@ export default struct SignalDisplayComponent {
aboutToAppear(): void {
DifferentialAndSignal.onMsg((data: string) => {
const result: WorkerBackMessage = JSON.parse(data)
if (result.type === "centerUdpData") {
console.log("wzj", data)
if (result.type === "obtainUdpData") {
this.getSignal(result.data as string)
this.rawData = result.data as string
}
@ -36,11 +37,11 @@ export default struct SignalDisplayComponent {
}
getSignal = (msg: string) => {
const strachArr = msg.split(',')
if (strachArr[0] != '#DN_GD') {
const newArr = msg.split(',')
if (newArr[0] != '#DN_GD') {
return
}
this.signArr = strachArr
this.signArr = newArr
for (let i = 0; i <= 12; i++) {
this.vehicleSignal[i].value = this.signArr[i+2]
@ -155,6 +156,7 @@ export default struct SignalDisplayComponent {
CoordinateComponent({
isItHorizontal: false,
heightNum: 40,
data: this.GPSColum
})
}.width("20%")
@ -358,7 +360,7 @@ struct TabItemComponent {
@Component
struct GPSComponent {
@State data: Array<string> = []
@Prop data: Array<string>
@State ip: string = ""
aboutToAppear(): void {
@ -439,7 +441,7 @@ struct GPSComponent {
@Component
struct CarComponent {
@State data: Array<SignalDataType> = SignalData
@Prop data: Array<SignalDataType>
build() {
Flex({
@ -457,7 +459,7 @@ struct CarComponent {
@Component
struct CoordinateComponent {
@State data: Array<SignalDataType> = GPSData
@Prop data: Array<SignalDataType>
@State isItHorizontal: boolean = true
@State heightNum: number = 65
@ -490,7 +492,7 @@ struct CoordinateComponent {
@Component
struct blockComponent {
@State label: string = "发送次数"
@State value: string = "1"
@Prop value: string = "1"
@State widthNum: number = 130
@State heightNum: number = 65
@State color: string = "#FDF5E7"

View File

@ -9,7 +9,7 @@ import FileModel from './utils/fileModel';
import FilePhoto from './utils/filePhoto';
import FileLog from './utils/fileLog';
import JudgeTask from './utils/judgeTask';
import { JudgeConfig } from "../../config";
import { JudgeConfig } from '../../config';
import { LANE } from '../judgeSDK/api/judgeSDK.d';
import { GetSyncData, SqlInsertTable } from '../../utils/table/Operation';
@ -33,8 +33,8 @@ import {
import { uploadExamProgressData, writeObjectOut } from '../../api/judge';
import { endRecordVideo, saveStartRecordVideo } from '../../utils/Video';
import common from '@ohos.app.ability.common';
import { convertGpsCoord2, deepClone } from './utils/Common';
import { GetCurrentTime } from '../../utils/Common';
import { ConvertDdmmToDecimalDegrees, GetCurrentTime,DeepClone } from '../../utils/Common';
import UsbService from '../../utils/USB';
import FileUtils from '../../utils/FileUtils';
import {
@ -49,7 +49,6 @@ import {
JudgeCallBackData,
JudgeConfigObj,
JudgeConfigObjKmItems,
JudgeEventKf,
JudgeInitObj,
JudgeKFXM,
JudgeKSJS,
@ -264,8 +263,8 @@ export default class Judge {
handDistance = async () => {
const dwzt = this.tempData?.gps?.dwzt || "";
const jdzt = this.tempData?.gps?.jdzt || "";
const tJD = convertGpsCoord2(this.tempData?.gps?.jd || 0)
const tWD = convertGpsCoord2(this.tempData?.gps?.wd || 0)
const tJD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.jd || 0)
const tWD = ConvertDdmmToDecimalDegrees(this.tempData?.gps?.wd || 0)
if (this.prevJd && dwzt == 4 && jdzt == 3) {
const distance = await examCalcGpsDistance({
jd1: this.prevJd,
@ -1052,7 +1051,7 @@ export default class Judge {
//更新UI
if (event == 1 || event == 2 || event == 3 || event == 6) {
const copyProjectsObj: object = this.judgeUI.projectsObj;
judgeUI.projectsObj = deepClone(copyProjectsObj);
judgeUI.projectsObj = DeepClone(copyProjectsObj);
}
}
// 更改考试状态

View File

@ -1,83 +0,0 @@
// 根据指定个数分割数组
export function chunkArr<T>(arr: T[], size: number): T[][] {
//判断如果不是数组(就没有length)或者size没有传值size小于1就返回空数组
if (!arr.length || !size || size < 1) {
return []
}
let start = 0
let end = 0
let result: T[][] = []
for (let i = 0; i < Math.ceil(arr.length / size); i++) {
start = i * size
end = start + size
result.push(arr.slice(start, end))
}
return result
}
//对象深拷贝
export function deepClone<T extends Object>(target: T): T {
// 如果是对象且不是原始值null
if (typeof target === 'object' && target !== null) {
// 创建容器
const result: ESObject = Array.isArray(target) ? [] : {};
const keys = Object.keys(target) as Array<keyof T>; //注解二
keys.forEach(key => {
Reflect.set(result, key, deepClone(Reflect.get(target, key)));
});
return result;
}
// 如果是原始值,则直接返回
return target;
}
export function fillZero(str: string | number, len: number): string {
if (!str) {
return ""
}
str = str.toString();
if (str.length >= len || len <= 0) {
return str;
}
const zeroStr = '0'.repeat(len - str.length);
return zeroStr + str;
}
//经纬度转换
export function convertGpsCoord2(num: number): number {
const tempNum = Math.floor(num);
const du = Math.floor(tempNum / 100);
const fen = tempNum % 100 + num - tempNum;
return du + fen / 60
}
export function Array2Byte(array: number[]): Uint8Array {
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;
}
export function string2Bytes(number: number, len: number): number[] | undefined {
let str = Math.floor(number).toString(2);
if (str.length > len) {
console.log('数据长度不对~~');
return;
}
const byteString = fillZero(str, len);
const arrBytes: number[] = [];
for (let i = byteString.length; i > 0; ) {
let j = i - 8;
if (j < 0) {
j = 0;
}
const s = byteString.slice(j, i);
const v = parseInt(s, 2);
arrBytes.push(v);
i -= 8;
}
return arrBytes;
}

View File

@ -1,10 +1,10 @@
import { testRealExam } from '../dataTest/index';
import { NumberToByteArray } from '../../../utils/Common';
import { ArrayToByteArray, NumberToByteArray } from '../../../utils/Common';
import systemTime from '@ohos.systemDateTime';
import { Array2Byte } from './Common';
import { CarInfoType } from '../../../model';
import { DefaultJudgeConfigObj, Gps, JudgeLane, Plc, Radar, Sensor, Vision } from '../../../model/Judge';
import { DefaultJudgeConfigObj, Gps, JudgeLane, Plc, Radar, Vision } from '../../../model/Judge';
interface Extend {}
@ -102,7 +102,7 @@ export function getKmProjectVoice(
xmxh: string
) {
const carInfo = AppStorage.get<CarInfoType>('carInfo')!;
const examSubject = carInfo.examSubject||"2";
const examSubject = carInfo.examSubject || "2";
const param506Str: number[] = (Reflect.get(judgeConfig, '506')?.split(',')) || []
const param512Str: number[] = (Reflect.get(judgeConfig, '512')?.split(',')) || []
const param544Str: number[] = (Reflect.get(judgeConfig, '544')?.split(',')) || []
@ -595,7 +595,7 @@ export const plcStrToWXJson = async (plc: string) => {
const p = plc.split(',').map((val, key) => {
if (key !== 27 && key !== 92) {
return Number(val)
}else{
} else {
return 0
}
});
@ -699,21 +699,21 @@ export const getTimeStr = async () => {
//蓝灯
export function sendBlue() {
const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00];
const arrBlueBuffer = Array2Byte(arrBlue).buffer
const arrBlueBuffer = ArrayToByteArray(arrBlue).buffer
// globalThis.lightLineUdp.send(arrBlueBuffer);
}
//绿灯
export function sendGreen() {
const arrGreen = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x00, 0x03, 0x01];
const arrGreenBuffer = Array2Byte(arrGreen).buffer
const arrGreenBuffer = ArrayToByteArray(arrGreen).buffer
// globalThis.lightLineUdp.send(arrGreenBuffer);
}
//红灯
export function sendRed() {
const arrRed = [0x55, 0xaa, 0x01, 0x01, 0x02, 0x00, 0x03, 0x00];
const arrRedBuffer = Array2Byte(arrRed).buffer
const arrRedBuffer = ArrayToByteArray(arrRed).buffer
// globalThis.lightLineUdp.send(arrRedBuffer);
}

View File

@ -69,13 +69,13 @@ export function ArrayToByteArray(array: number[]): Uint8Array {
}
/**
* 字符串转字节数组
* 字转字节数组
* @param number 要转换的数字
* @param len 字节数
* @returns 返回字节数组
*/
export function NumberToByteArray(number: number, len: number): number[] {
let str = Math.floor(number).toString(2);
export function NumberToByteArray(number: number | string, len: number): number[] {
let str = Math.floor(Number(number)).toString(2);
if (str.length > len) {
console.log('数据长度不对~~');
return [];
@ -96,6 +96,12 @@ export function NumberToByteArray(number: number, len: number): number[] {
return arrBytes;
}
/*
* 将字符串填充为指定长度的字符串前面补0
* @param str 要填充的字符串或数字
* @param len 目标长度
* @return 返回填充后的字符串
*/
export function FillZero(str: string | number, len: number): string {
str = str.toString();
if (str.length >= len || len <= 0) {
@ -104,3 +110,49 @@ export function FillZero(str: string | number, len: number): string {
const zeroStr = '0'.repeat(len - str.length);
return zeroStr + str;
}
/**
* 将数组按指定大小分块
* @param arr 原始数组
* @param size 每块大小(必须 >= 1
* @returns 分块后的二维数组
*/
export function CutArray<T>(arr: readonly T[], size: number): T[][] {
if (!Array.isArray(arr) || size < 1) return [];
const result: T[][] = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
/**
* 将GPS坐标从度分格式(DDMM.MMMM)转换为十进制度格式
* @param ddmm - 度分格式坐标(例如 11630.1234 表示116度30.1234分)
* @returns 十进制度格式坐标(例如 116.502056666...)
*/
export function ConvertDdmmToDecimalDegrees(ddmm: number): number {
// 提取度数部分除以100后取整
const degrees = Math.floor(ddmm / 100);
// 提取分数部分包含小数对100取模
const minutes = ddmm % 100;
// 将分数转换为度并相加1度=60分
return degrees + minutes / 60;
}
//对象深拷贝
export function DeepClone<T extends Object>(target: T): T {
// 如果是对象且不是原始值null
if (typeof target === 'object' && target !== null) {
// 创建容器
const result: ESObject = Array.isArray(target) ? [] : {};
const keys = Object.keys(target) as Array<keyof T>; //注解二
keys.forEach(key => {
Reflect.set(result, key, DeepClone(Reflect.get(target, key)));
});
return result;
}
// 如果是原始值,则直接返回
return target;
}

View File

@ -6,10 +6,9 @@ import {
OtherMessageType,
UDPParamType
} from '../../model';
import { fillZero, string2Bytes } from '../../pages/judgeSDK/utils/Common';
import { NumberToByteArray } from '../Common';
import { ArrayToByteArray, FillZero, NumberToByteArray } from '../Common';
import UdpClient from '../UdpUtils';
import { UDPTag } from '../../config';
import { CenterUdpTag, UDPTag } from '../../config';
import { SerialNumberInstance } from '../SerialNumber';
// 中心UDP业务逻辑
@ -41,29 +40,33 @@ class CenterUDPBusiness {
}
startHeartBeat() {
console.log("心跳")
console.log(CenterUdpTag, "心跳", JSON.stringify(this.carInfo))
// 组装消息,一秒发送一次
this.timer = setInterval(() => {
// 生成流水号
SerialNumberInstance.generate()
console.log(CenterUdpTag, "流水号生成")
// 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])
}
console.log(CenterUdpTag, "学员流水号", JSON.stringify(tmpList))
const data: UDPParamType = {
id: 31,
list: tmpList,
carNo: this.carInfo.carNo!,
placeId: this.carInfo.examinationRoomId!
}
console.log(CenterUdpTag, "查看生成的", JSON.stringify(data))
const param = this.setWholeMsg(data)
console.log("查看")
console.log(CenterUdpTag, "查看", JSON.stringify(param))
this.udp.sendMsg(param);
}, 1000);
}
@ -84,12 +87,16 @@ class CenterUDPBusiness {
// 初始化
async init(config: EnvironmentConfigurationType, carInfo: CarInfoType, otherMessage: OtherMessageType) {
console.log(CenterUdpTag, "初始化", JSON.stringify(otherMessage), JSON.stringify(carInfo))
try {
this.signNum = otherMessage.signNum || 0
this.statue = otherMessage.statue || '1'
this.lsh = otherMessage.lsh || '0000000000000'
this.carInfo = carInfo
this.udp.create(config.udplocalIp!, '8800', carInfo.udpAddress!, carInfo.messagePort!)
// TODO
// this.udp.create(config.udplocalIp!, '8800', carInfo.udpAddress!, carInfo.messagePort!)
this.udp.create(config.udplocalIp!, '8800', "112.80.35.83", "11056")
this.udp.setDealMethod(this.dealMsg)
} catch (e) {
console.error(UDPTag, "初始化中心 udp失败")
@ -108,8 +115,8 @@ class CenterUDPBusiness {
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 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])
@ -133,24 +140,15 @@ class CenterUDPBusiness {
params.list?.forEach(item => arr.push(item))
bodyJudge.forEach(item => arr.push(item))
end.forEach(item => arr.push(item))
return this.array2Byte(arr).buffer
}
private array2Byte(array: Array<number>) {
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;
return ArrayToByteArray(arr).buffer
}
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 a = NumberToByteArray(Number(`${params.id}${FillZero(params.placeId, 3)}`), 2 * 8);
let b = NumberToByteArray(Number(`${FillZero(params.carNo, 4)}${lshNo}`), 4 * 8);
let c = NumberToByteArray(params.list.length, 2 * 8);
let result: number[] = []
a?.forEach(item => result.push(item))
b?.forEach(item => result.push(item))

View File

@ -24,6 +24,7 @@ class differentialAndSignal {
const signNum = AppStorage.get<number>('signNum')
const statue = AppStorage.get<string>('statue')
const lsh = AppStorage.get<string>('lsh')
const singlePlay = AppStorage.get<boolean>("singlePlay")
const data: WorkerMessage = {
config: config,
carInfo: carInfo,
@ -31,7 +32,8 @@ class differentialAndSignal {
signNum: signNum || 0,
statue: statue || "",
lsh: lsh || ""
}
},
singlePlay: singlePlay || false
}
this.workerInstance.postMessage(JSON.stringify(data))
this.getMessage()

View File

@ -1,8 +1,17 @@
import { CarInfoType, EnvironmentConfigurationType, Gps, Sensor, UDPParamType } from '../../model';
import {
CarInfoType,
EnvironmentConfigurationType,
Gps,
PLCDataType,
ProjectDataType,
ProjectItemType,
Sensor,
UDPParamType
} from '../../model';
import { testKm2Items, testKm3Items } from '../../pages/judgeSDK/dataTest';
import { fillZero, } from '../../pages/judgeSDK/utils/Common';
import { JudgeConfig } from '../../config';
import { FillZero, StringToASCII } from '../Common';
import { FillZero, NumberToByteArray, StringToASCII } from '../Common';
import UdpClient from '../UdpUtils';
import { CenterUDPBusinessInstance } from './CenterUdpBusiness';
import { ObtainUdpBusinessInstance } from './ObtainUdpBusiness';
@ -10,48 +19,16 @@ import systemTime from '@ohos.systemDateTime';
import { examCalcGpsDistance } from '../../pages/judgeSDK/api';
import { SerialNumberInstance } from '../SerialNumber';
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
public udpIndex = 0;
private udp: UdpClient = new UdpClient()
private currentUdpIndex = 0;
private carInfo: CarInfoType = {}
private singlePlay: boolean = false
private lsh: string = ""
private serialIndex: number = 0
constructor() {
if (!JudgeUdpBusiness.instance) {
@ -61,16 +38,16 @@ class JudgeUdpBusiness {
}
async 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")
this.singlePlay
? '1111111111111'
: AppStorage.get<string>("lsh")!,
: this.lsh,
13));
const ascksyhArr = StringToASCII(carInfo.examSubject === '2' ? '0000000000000' : '1111111111111')
const ascksyhArr = StringToASCII(this.carInfo.examSubject === '2' ? '0000000000000' : '1111111111111')
const ascsbxhArr = StringToASCII('00000000')
const serialIndex = AppStorage.get<number>("serialIndex")!
// const serialIndex = AppStorage.get<number>("serialIndex")!
const plcData = await this.getPlcData(msg);
let param: number[] = Object.entries(plcData.sensor)
.filter((item: [string, number]) => {
@ -85,70 +62,71 @@ class JudgeUdpBusiness {
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])
const translateProjects = translateProject.map(numStr => NumberToByteArray(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]),
asclshArr.map(lsh => NumberToByteArray(lsh, 8)[0]),
//考试员号
ascksyhArr.map(ksyh => string2Bytes(ksyh, 8)[0]),
ascksyhArr.map(ksyh => NumberToByteArray(ksyh, 8)[0]),
//科目类型(0:未考试 1:科目二 2:科目三) + 考试开始时间
string2Bytes(`${0}${'00:00:000'}`, 4 * 8),
NumberToByteArray(`${0}${'00:00:000'}`, 4 * 8),
// 消息序号
string2Bytes(serialIndex, 2 * 8),
NumberToByteArray(this.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),
NumberToByteArray(tempSd * 100, 2 * 8),
NumberToByteArray(plcData.sensor.fdjzs / 100, 8),
NumberToByteArray(translateJd, 4 * 8),
NumberToByteArray(translateWd, 4 * 8), NumberToByteArray(1, 8),
//GPS东向距离
string2Bytes(0, 4 * 8),
NumberToByteArray(0, 4 * 8),
//GPS北向距离
string2Bytes(0, 4 * 8),
NumberToByteArray(0, 4 * 8),
//航向角
string2Bytes(plcData.gps.hxj * 100, 2 * 8),
NumberToByteArray(plcData.gps.hxj * 100, 2 * 8),
//俯仰角
string2Bytes(plcData.gps.fyj * 100, 2 * 8),
NumberToByteArray(plcData.gps.fyj * 100, 2 * 8),
// 高程(海拔)
string2Bytes(plcData.gps.hbg * 100, 4 * 8),
NumberToByteArray(plcData.gps.hbg * 100, 4 * 8),
//dddd
translateProjects,
//当前项目编号
string2Bytes(0, 8),
NumberToByteArray(0, 8),
//场地设备编号
ascsbxhArr.map(sbxh => string2Bytes(sbxh, 8)[0]),
ascsbxhArr.map(sbxh => NumberToByteArray(sbxh, 8)[0]),
//本次考试行驶距离
string2Bytes(0, 2 * 8),
NumberToByteArray(0, 2 * 8),
//扣分值
string2Bytes(0, 2 * 8),
NumberToByteArray(0, 2 * 8),
//扣分数
string2Bytes(0, 2 * 8),
NumberToByteArray(0, 2 * 8),
//扣分项数量
string2Bytes(0, 8),
NumberToByteArray(0, 8),
//n个扣分序号
// [].map(kf => string2Bytes(kf.markcatalog, 8)),
[],
//牵引车第二gps精度、纬度
string2Bytes(0, 4 * 8), string2Bytes(0, 4 * 8),
NumberToByteArray(0, 4 * 8), NumberToByteArray(0, 4 * 8),
//牵引车第二航向角
string2Bytes(0, 2 * 8),
NumberToByteArray(0, 2 * 8),
//摩托压线 Byte[20],
string2Bytes(0, 20 * 8),
NumberToByteArray(0, 20 * 8),
//考试用时
string2Bytes(FillZero(0, 4), 4 * 8),
NumberToByteArray(FillZero(0, 4), 4 * 8),
//项目用时
string2Bytes(FillZero(0, 2), 2 * 8),
NumberToByteArray(FillZero(0, 2), 2 * 8),
//设备信号状态
string2Bytes(0, 4 * 8),
NumberToByteArray(0, 4 * 8),
]
let result: number[] = [];
arr.forEach(itemArr => {
result = result.concat(itemArr)
})
AppStorage.setOrCreate("serialIndex", 0)
// AppStorage.setOrCreate("serialIndex", 0)
this.serialIndex = 0
return [...new Uint8Array(result)]
}
@ -158,13 +136,12 @@ class JudgeUdpBusiness {
}
sendData(bytes: number[]) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')!
if (this.udpIndex > this.currentUdpIndex) {
this.udp.sendMsgExt({
id: 45,
list: bytes,
carNo: carInfo.carNo!,
placeId: carInfo.examinationRoomId!
carNo: this.carInfo.carNo!,
placeId: this.carInfo.examinationRoomId!
})
this.currentUdpIndex = this.udpIndex
}
@ -172,35 +149,34 @@ class JudgeUdpBusiness {
//申请远程扣分查询
askKf(directives: number) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')!
CenterUDPBusinessInstance.sendData({
id: 35,
list: [directives],
carNo: carInfo.carNo!,
placeId: carInfo.examinationRoomId!,
carNo: this.carInfo.carNo!,
placeId: this.carInfo.examinationRoomId!,
})
console.info('surenjun', `考车查询扣分项目内容,请求指令为:${directives}`)
}
//确定远程扣分
confirmKf(directives: number, code: number) {
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')!
CenterUDPBusinessInstance.sendData({
id: 37,
list: [directives, code],
carNo: carInfo.carNo!,
placeId: carInfo.examinationRoomId!
carNo: this.carInfo.carNo!,
placeId: this.carInfo.examinationRoomId!
})
console.info('surenjun', `考车发送确定扣分指令,指令为:${directives}`)
}
async init(): Promise<void> {
// 初始化
async init(config: EnvironmentConfigurationType, carInfo: CarInfoType, singlePlay: boolean, lsh: string): Promise<void> {
this.lsh = lsh
this.carInfo = carInfo
this.singlePlay = singlePlay
return new Promise((resolve, reject) => {
try {
let result: EnvironmentConfigurationType =
AppStorage.get<EnvironmentConfigurationType>("EnvironmentConfiguration")!
const carInfo: CarInfoType = AppStorage.get<CarInfoType>('carInfo')!
this.udp.create(result.udplocalIp!, '8080', carInfo.udpAddress!, carInfo.hintPort!).then(resolve).catch(reject)
this.udp.create(config.udplocalIp!, '8080', carInfo.udpAddress!, carInfo.hintPort!).then(resolve).catch(reject)
ObtainUdpBusinessInstance.onMsg(async (msg: string) => {
let prevJd = 0, preWd = 0
@ -228,7 +204,7 @@ class JudgeUdpBusiness {
prevJd = jd;
preWd = wd;
}
AppStorage.set("udpIndex", udpIndex + 1)
// AppStorage.setOrCreate("udpIndex", udpIndex + 1)
})
setInterval(() => {
this.udpIndex += 1
@ -259,9 +235,9 @@ class JudgeUdpBusiness {
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 a = NumberToByteArray(Number(`${params.id}${FillZero(params.placeId, 3)}`), 2 * 8);
let b = NumberToByteArray(Number(`${FillZero(params.carNo, 4)}${lshNo}`), 4 * 8);
let c = NumberToByteArray(params.list.length, 2 * 8);
let result: number[] = []
a?.forEach(item => result.push(item))
b?.forEach(item => result.push(item))
@ -291,14 +267,14 @@ class JudgeUdpBusiness {
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])
return arr.map(numStr => parseInt(numStr, 2)).map(item => NumberToByteArray(item, 8)[0])
}
// 中心所有项目转换
private getTranslateProject(): string[] {
const examSubject = AppStorage.get<string>("examSubject");
this.carInfo.examSubject
const tempItems: ProjectItemType[] =
(examSubject === '2' ? testKm2Items : testKm3Items).map((code: ProjectDataType) => {
(this.carInfo.examSubject === '2' ? testKm2Items : testKm3Items).map((code: ProjectDataType) => {
let data: ProjectItemType = {
code,
status: '0'
@ -310,7 +286,7 @@ class JudgeUdpBusiness {
const temp = tempItems.slice(i * 4, (i + 1) * 4);
let tempArr = temp.map(item => item.status)
if (i === 4) {
tempArr = examSubject === '2'
tempArr = this.carInfo.examSubject === '2'
//bit36-bit39保留
? tempArr.concat(['00', '00'])
//bit30-bit39保留
@ -328,34 +304,59 @@ class JudgeUdpBusiness {
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],
// 点火1
dh1: p[5],
// 点火2
dh2: p[6],
// 发动机转速
fdjzs: p[25],
// 档位
dw: p[28],
// 车速
cs: p[23],
// 方向盘角度
fxp: Number(origin[27].split('_')[0]),
//累计脉冲 溜车脉冲 超声波左后 超声波右后 超声波右前 超声波左前 座椅 仪表盘 后视镜 倒车镜 光照 雨量
//累计脉冲
ljmc: p[24],
// 溜车脉冲
lcmc: 0,
// 超声波4 左后
csbzh: p[32],
// 超声波2 右后
csbyh: p[30],
// 超声波3 右前
csbyq: p[31],
// 超声波1 左前
csbzq: p[29],
zy: 0,
tbp: 0,
@ -371,20 +372,34 @@ class JudgeUdpBusiness {
mndg: ''
}
let gps: Gps = {
// GPS板卡类型
bklx: p[56],
// GPS状态
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])
}
@ -416,4 +431,5 @@ class JudgeUdpBusiness {
}
}
export const JudgeUdpBusinessInstance = new JudgeUdpBusiness()

View File

@ -37,6 +37,9 @@ function initFn(result: WorkerMessage) {
CenterUDPBusinessInstance.init(result.config, result.carInfo, result.otherMessage)
// 中心心跳
CenterUDPBusinessInstance.startHeartBeat()
// 初始化考试过程UDP
// JudgeUdpBusinessInstance.init(result.config, result.carInfo, result?.singlePlay || false, result.otherMessage.lsh)
}
function getDataFn() {
@ -44,7 +47,7 @@ function getDataFn() {
DifferentialSignal.getData((data: ArrayBuffer) => {
console.log(WorkerTag, "Received differential signal data:", data.byteLength, "bytes")
// TCP拿到差分改正数发给后置机
ObtainUdpBusinessInstance.sendData(data)
// ObtainUdpBusinessInstance.sendData(data)
})
// 后置机回执PLC和GPS
ObtainUdpBusinessInstance.onMsg((data: string) => {