diff --git a/entry/src/main/ets/pages/judgeSDK/utils/fileLog.ts b/entry/src/main/ets/pages/judgeSDK/utils/fileLog.ts new file mode 100644 index 00000000..8cbf69b2 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/fileLog.ts @@ -0,0 +1,117 @@ +import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl' +import promptAction from '@ohos.promptAction' +import fileAccess from '@ohos.file.fileAccess' +import common from '@ohos.app.ability.common' +import Want from '@ohos.app.ability.Want' +import fs from '@ohos.file.fs' +import FileUtil from '../../../common/utils/File' +import {getCurrentTime} from '../../../common/utils/tools' + +interface StuInfo{ + name:string + lsh:string + idCard:string +} + +const LOGTAG = 'LOGTAG' +export default class FileLog { + + //后续文件路径待替换 + private fileUtil: FileUtil + private stuInfo: StuInfo + public folderPath: string + + constructor(context) { + const fileUtil = new FileUtil(context) + this.fileUtil = fileUtil + } + + // 设置文件夹 + public initFileLogo = async (stuInfo:StuInfo) => { + const {fileUtil,setExamLineData} = this + const {name,lsh,idCard} = stuInfo; + this.stuInfo = stuInfo; + const time = await getCurrentTime() + const date = time.split(' ')[0].split('-').join('_') + const hourTime = time.split(' ')[1].split(':').join('_') + const folderPath = await fileUtil.initFolder(`/logs/${date}/${lsh}_${idCard}_${name}_${date}_${hourTime}`); + this.folderPath = folderPath; + } + + // 过程文件数据 + public setExamProgressData = async (str:Object) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/exam_progress_data.txt`,JSON.stringify(str)); + } + + // 无锡所接口数据 + public setExamJudgeWuxiData = async (str) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/wuxi_exam_data.txt`,str); + } + + // 无锡所过程数据 + public setExamJudgeWuxiProgressData = async (str)=>{ + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/wuxi_progress_data.txt`,str); + } + + // plc文件数据 + public setPlcProgressData = async (str:Object) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/plc_data.txt`,JSON.stringify(str)); + } + + // 过程评判json数据 + public setExamJudgeData = async (str:Object) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/judge_exam_data.txt`,JSON.stringify(str)); + } + + // 过程评判回调数据 + public setExamJudgeCallbackData = async (str:string) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/judge_progress_callback_data.txt`,str); + } + + // 过程评判日志调数据 + public setExamJudgeLogData = async (str:string) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/judge_log_data.txt`,str); + } + + // 无锡所轨迹数据 + public setExamLineData = async (plcStr) => { + const {fileUtil,folderPath} = this; + const plcData = plcStr.split(','); + const time = await getCurrentTime(); + + const lineData = [ + /*帧头*/ time, + /*卫星时间*/time, + /*经度*/ plcData[95], + /*纬度*/ plcData[95], + /*高度*/ plcData[86], + /*方位角*/ 0, + /*俯仰角*/ plcData[91], + /*速度角*/'', + /*速度*/ plcData[97], + /*横滚*/'', + /*卫星定位状态*/'', + /*卫星定向状态*/'', + /*前天线可用星数*/'', + /*后天线可用星数*/'', + /*东向位置坐标*/'', + /*北向位置坐标*/'', + /*天向位置坐标*/'', + /*东向速度*/'', + /*北向速度*/'', + /*评判信号1*/[plcData[14],plcData[19],plcData[5],'',plcData[2],plcData[3],plcData[7],plcData[8],plcData[13],plcData[12],plcData[17],'',plcData[4],plcData[11],plcData[20],plcData[9],0].join(','), + /*评判信号2*/['',plcData[28],'','',plcData[10],'','','','','','','','','','','','',''].join(','), + /*发动机转速*/ plcData[25], + /*结束符*/ time, + ]; + + await fileUtil.editFile(`${folderPath}/exam_wuxi_data.txt`,JSON.stringify(lineData)); + }; +} diff --git a/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts b/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts new file mode 100644 index 00000000..a935a7fd --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/fileModel.ts @@ -0,0 +1,54 @@ +import FileUtil from '../../../common/utils/File' +import zlib from '@ohos.zlib'; +export default class FileModel{ + + //后续文件路径待替换 + private fileUtil: FileUtil + public folderPath: string + + constructor(context){ + (async ()=>{ + const fileUtil = new FileUtil(context) + this.fileUtil = fileUtil + })() + + } + + // 设置文件夹 + public initFolder = async () => { + const {fileUtil} = this + await fileUtil.initFolder(`/models/model_enc`); + const folderPath = await fileUtil.initFolder(`/models`); + this.folderPath = folderPath; + } + + // 存储zip文件并解压 + public storingFiles = async (str) => { + const {fileUtil,folderPath} = this; + await fileUtil.editFile(`${folderPath}/model.zip`,str,'overWrite') + + let options = { + level: zlib.CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION, + memLevel: zlib.MemLevel.MEM_LEVEL_DEFAULT, + strategy: zlib.CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY + }; + + zlib.unzipFile( + `${folderPath}/model.zip`, + `${folderPath}`, + options).then((data) => { + console.log("unzipFile result:" + data); + }).catch((err)=>{ + console.log("catch((err)=>" + err); + }) + + } + + //获取文件内容 + public getModelContent = (folderPath,fileName) => { + const {fileUtil} = this; + const content = fileUtil.getFileContent(`${folderPath}/${fileName}`) + return content; + } + +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts b/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts new file mode 100644 index 00000000..58aac620 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/filePhoto.ts @@ -0,0 +1,71 @@ +import mediaLibrary from '@ohos.multimedia.mediaLibrary' +import onvifclient from '@ohos.onvifclient'; +import fs from '@ohos.file.fs' +import util from '@ohos.util'; +import FileUtil from '../../../common/utils/File' + +interface Params{ + userName:string + pwd:string + ip:string + port:string + rlls:string +} + +export default class FilePhoto{ + + private params:Params + private context:any + private fileUtil:FileUtil + public mediaTest + + constructor(context) { + (async ()=>{ + const fileUtil = new FileUtil(context) + const strConfig = await fileUtil.readFile('/mnt/hmdfs/100/account/device_view/local/files/logs/config/config3.txt'); + const config = JSON.parse(strConfig) + const {userName,ip,pwd,port,rlls} = config + this.params = {userName,pwd,ip,port,rlls} + this.context = context + this.fileUtil = fileUtil + })() + } + + public async getPhoto(){ + const {params,context,fileUtil} = this; + const {userName,pwd,ip,port,rlls} = params; + const mediaTest = mediaLibrary.getMediaLibrary(context); + let mediaType = mediaLibrary.MediaType.IMAGE; + let DIR_DOCUMENTS = mediaLibrary.DirectoryType.DIR_IMAGE; + const path = await mediaTest.getPublicDirectory(DIR_DOCUMENTS); + + return new Promise(async (resolve)=>{ + mediaTest.createAsset(mediaType, 'judge_face.jpg', path,(error,asset)=>{ + asset.open('rw', (error, fd) => { + if (fd > 0) { + const file_path = "/mnt/hmdfs/100/account/device_view/local/files/Pictures/judge_face.jpg" + const result3 = onvifclient.getVideoSnapshot(`rtsp://${userName}:${pwd}@${ip}:${port}/h264/ch${rlls}/main/av_stream`,file_path,fd); + fs.closeSync(fd); + asset.close(fd); + fs.lstat(file_path).then((stat) => { + console.info("get link status succeed, the size of file is" + stat.size); + let file = fs.openSync(file_path, fs.OpenMode.READ_WRITE); + const size=Number(stat.size)+100 + let buf = new ArrayBuffer(size); + let num = fs.readSync(file.fd, buf); + const that = new util.Base64(); + const array = new Uint8Array(buf); + const result = that.encodeToStringSync(array);//base64圖片 + fileUtil.deleteF(file_path,3) + resolve(result) + }).catch((err) => { + console.info("get link status failed with error message: " + err.message + ", error code: " + err.code); + }); + } else { + console.error('baoyihu getVideoSnapshot File Open failed with error: ' + error); + } + }); + }); + }) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts new file mode 100644 index 00000000..fafeaeca --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeCommon.ts @@ -0,0 +1,397 @@ +import {string2Bytes,Array2Byte,getCurrentTime} from '../../../common/utils/tools' +import {testMarkRules,testRealExam,testKmItems} from '../dataTest/index' + +import promptAction from '@ohos.promptAction' +import systemTime from '@ohos.systemDateTime'; + +//获取本地扣分项 +export const getTestMarkRules = () =>{ + testMarkRules.map((mark:any) => { + return { + itemno:mark.itemno*1, + markcatalog:mark.markcatalog, + markshow:mark.markshow, + markreal:mark.markreal*1, + markserial:mark.markserial, + kfxh:mark.kfxh + } + }) +} + +// 中心信号转换 +export const getTranslateSignals = (tempItems) => { + const len = Math.floor(tempItems.length / 8); + const arr = []; + for(let i = 0;i < len;i++){ + const temp = tempItems.slice( i*8 , (i+1)*8 ); + arr.push(temp.join('')); + } + const temp = arr.map(numStr => parseInt(numStr,2)) + return temp.map(item => string2Bytes(item , 8)[0]) +} + +// c++评判考车行驶状态转换 +export function getCarStatus(status: -1 | 0 | 1):string { + switch (status){ + case -1:return '后退' + case 0:return '停车' + case 1:return '前进' + default :return '' + } +} + +// 当前考车中心状态转换 +export function getCarStatusType(carzt){ + switch (carzt){ + case -1:return [1,0] + case 0: return [0,0] + case 1: return [0,1] + } +} + + +// 中心实时项目状态转换 +export function getCenterProjectStatus(status){ + switch (status){ + //不考 + case 0:return '00' + //未考 + case 1:return '01' + //已考 + case 2:return '10' + } +} + +//获取科目三开始项目、结束项目语音 + +export function getKmProjectVoice( + projectCode, + // 1:项目开始 2:项目结束 + type: 1 | 2 +) { + const carInfo = globalThis.carInfo; + const { examSubject } = carInfo; + + if(examSubject == 2){ + return projectCode + } + + switch (projectCode*1){ + //直线行驶 + case 40300: return type === 1 ? 403001 : 403002 + //变更车道 + case 40500: return type === 1 ? 405001 : 405002 + //超车 + case 41400 : return type === 1 ? 414001 : undefined + //直线行驶 + case 40700 : return type === 1 ? 407001 : undefined + //左转 + case 40800 : return type === 1 ? 408001 : undefined + //右转 + case 40900 : return type === 1 ? 409001 : undefined + //通过人行横道 + case 41000 : return type === 1? 410001:undefined + //通过学校 + case 41100 : return type === 1 ? 411001:undefined + //通过车站 + case 41200 : return type === 1 ? 412001 : undefined + //会车 + case 41300 : return type === 1 ? 413001: 413002 + //靠边停车 + case 40600 : return type === 1 ? 406001 : undefined + //掉头 + case 41500 : return type === 1 ? 415001:undefined + //超车 + case 40400 : return type === 1 ? 404001:undefined + + default :return undefined + } + +} + +// 上传监管数据code转换 +export function promptWxCode( + jkid:'17C52' | '17C54' |'17C55' | '17C53' | '17C56', + code:number +){ + let toast = ''; + const singlePlay = globalThis.singlePlay + if(singlePlay){ + return + } + switch (jkid){ + //项目开始 + case '17C52': + switch (code){ + case 0:toast = '存在作弊嫌疑,已被取消或暂停考试';break; + case -1:toast = '无考生身份比对信息';break; + case -2:toast = '考试项目与考试安排信息不符';break; + case -3:toast = '考试设备未备案';break; + case -4:toast = '考试设备与考试项目不符';break; + case -5:toast = '考试设备使用状态异常';break; + case -6:toast = '考生考试车型与考试设备使用准驾车型范围不符';break; + case -7:toast = '该考生存在作弊嫌疑,已被暂停/取消考试';break; + case -8:toast = '项目开始时间不能小于科目开始时间';break; + case -9:toast = '存在未结束的考试项目、不能开始新的项目考试!';break; + case -10:toast = '科目三考车号牌不能为空';break; + case -11:toast = '同一考车存在未结束考试,不能开始应用于新的考试';break; + case -12:toast = '未找到考场记录';break; + case -13:toast = '未找到考车信息';break; + case -14:toast = '随机抽取考生的考车与当前考车不一致';break; + default:toast = '';break; + } + break; + //过程照片 + case '17C54': + switch (code){ + case -1:toast = '无当前科目考试信息';break; + case -2:toast = '考生身份证明号码与考生预约信息不符';break; + case -3:toast = '考试项目不正确';break; + case -4:toast = '考试过程中拍摄照片数量少于3张!';break; + case -5:toast = '考试项目不符合要求';break; + case -6:toast = '存在未结束的考试项目!';break; + } + break; + //项目结束 + case '17C55': + switch (code){ + case -1:toast = '无当前考试项目开始信息';break; + case -2:toast = '考生身份证明号码与考生预约信息不符';break; + case -3:toast = '考试项目不正确';break; + case -4:toast = '考试设备序号不正确!';break; + case -5:toast = '考试项目结束时间写入错误';break; + case -6:toast = '考生未进行身份认证';break; + case -7:toast = '项目考试过程信息记录被非法篡改';break; + case -8:toast = '每个考试项目中必须至少抓拍一张照片';break; + case -12:toast = '未找到考场记录';break; + case -13:toast = '未找到考车信息';break; + case -15:toast = '考试过程信息必须由考车上传';break; + case -90:toast = '考试项目已经结束、无需重传';break; + case -91:toast = '实际道路考试,在完成科目考试时统一结束';break; + default:break; + } + break; + //扣分 + case '17C53': + switch (code){ + case 0:toast = '已存在同一时间的同一扣分记录';break + case -1:toast = '无当前考试项目开始信息';break; + case -2:toast = '扣分时间大于项目开始时间!';break; + case -3:toast = '考试项目与扣分项不符';break; + case -4:toast = '项目考试过程中,请传入当前考试项目代码';break; + case -5:toast = '考生未进行身份认证';break; + case -6:toast = '扣分时间写入错误';break; + case -7:toast = '项目考试过程信息记录被非法篡改';break; + case -12:toast = '未找到考场记录';break; + case -13:toast = '未找到考车信息';break; + case -15:toast = '考试过程信息必须由考车上传';break; + default:toast = '';break + } + break; + //考试结束 + case '17C56': + switch (code){ + case -1:toast = '无当前科目考试信息';break; + case -2:toast = '考生身份证明号码与考生预约信息不符';break; + case -3:toast = '考试结束时间不正确';break; + case -4:toast = '考试过程中拍摄照片数量少于3张!';break; + case -5:toast = '考试项目不符合要求';break; + case -6:toast = '存在未结束的考试项目!';break; + case -7:toast = '传输的考试成绩非空';break; + case -91:toast = '考试成绩计算不一致';break; + case -91:toast = '日间考试已结束等待进行夜间考试';break; + default: toast = '';break + } + break; + default :break; + } + promptAction.showToast({ + message: decodeURIComponent(toast), + duration: 4000 + }); +} + +// 获取plc数据 +export const plcStrToJson = async (plc:string) =>{ + + const p = plc.split(',').map((val,key)=>{ + if(key !== 27 && key !== 92){ + //@ts-ignore + return val*1 + }else{ + return val + } + }); + let data:any = testRealExam; + const time = await systemTime.getCurrentTime() + const tempData = { + 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], + //@ts-ignore 方向盘 + fxp:p[27].split('_')[0]*1, + //累计脉冲 溜车脉冲 超声波左后 超声波右后 超声波右前 超声波左前 座椅 仪表盘 后视镜 倒车镜 光照 雨量 + 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, + //TODO 数据待替换 油压 闪灯 信号灯 + yy:0, sde:0, xhd:'',rmndg:0, wav:0 , mndg:'' + }, + gps:{ + //办卡类型 定位差分状态 + bklx:p[56], dwzt:p[83], + //@ts-ignore 角度差分状态 + jdzt:p[92].split('-')[0]*1, + //gps数据 + //gps时间 经度 纬度 航向角 俯仰角 海拔高 高度差 速度 + 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] || 0, + //@ts-ignore 角度搜星数 + jdsxs:p[92].split('-')[1]*1 || 0 + }, + gps2:data.gps, + vision:data.vision, + radar:data.radar, + extend:{} + } + return tempData +} + +export const plcStrToWXJson = async (plc:string) =>{ + const p = plc.split(',').map((val,key)=>{ + if(key !== 27 && key !== 92){ + //@ts-ignore + return val*1 + }else{ + return val + } + }); + const timeStr = p[93] + '' + p[94]; + const gps = { + //办卡类型 定位差分状态 + bklx:p[56], dwzt:p[83], + // 经度 纬度 航向角 俯仰角 海拔高 高度差 速度 + 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], + } + const judgeSignal = [ + // 车门 安全带 熄火 发动机启动 左转向 右转向 前照灯近灯 前照灯远灯 + p[14], p[19], p[5], p[6], p[2], p[3], p[7], p[8], + // 注车制动 行车制动 离合器 副制动 喇叭 雨刷 危险报警灯 示廓灯 系统未涉及的传感器信号 + p[13], p[12], p[17], p[18], p[4], p[11], p[20], p[9], 0 + ] + const judgeAnotherSignal = [ + // 低三挡位 左侧单边桥1 左侧单边桥2 右侧单边桥1 右侧单边桥2 雾灯 + '000', '0', '0', '0', '0', p[10], + // 桩杆全无信号 左后绕车 右后绕车 右前绕车 左前绕车 + '000', '0', '0', '0', '0' + ] + const wuXiData = [ + // 卫星时间 精度 纬度 高度 方位角 俯仰角 速度角 速度 横滚 卫星定位状态 + '$KSXT', timeStr, gps.jd, gps.wd, gps.hbg, gps.hxj, gps.fyj, '' , gps.sd, '', gps.dwzt, gps.dwzt, + //前天线可用星数 后天线可用星数 东向坐标位置 北向位置坐标 天向位置坐标 东向速度 北向速度 天向速度 + '', '', '', '', '', '', '', '', + //@ts-ignore 评判信号1 评判信号2 发动机转速 + (judgeSignal.join('')*1).toString(16), (judgeAnotherSignal.join('')*1).toString(16) , p[25], + '0xFFFFFFF' + ] + const wuXiDataStr = wuXiData.join(',') + return wuXiDataStr +} + +export const senorToWXDataStr= async (tempData) => { + const {sensor,gps} = tempData; + const timeStr = await getTimeStr() + + const {mkg,aqd,dh1,dh2, zfxd, yfxd, jgd, ygd,ssc , jsc, lhq, fsc, lb, ygq,wd} = sensor + const judgeSignal = [ + //车门 安全带 熄火 发动机启动 左转向 右转向 前照灯近灯 前照灯远灯 + mkg, aqd, dh1, dh2, zfxd, yfxd, jgd, ygd, + // 注车制动 行车制动 离合器 副制动 喇叭 雨刷 危险报警灯 示廓灯 系统未涉及的传感器信号 + ssc , jsc, lhq, fsc, lb, ygq, 0, 0, 0 + ] + + const judgeAnotherSignal = [ + // 低三挡位 左侧单边桥1 左侧单边桥2 右侧单边桥1 右侧单边桥2 雾灯 + '000', '0', '0', '0', '0', '0',,'0', + // 桩杆全无信号 左后绕车 右后绕车 右前绕车 左前绕车 + '000', '0', '0', '0', '0', '0','0' + ] + //@ts-ignore + const str1 = (judgeSignal.join('')*1).toString(16); + //@ts-ignore + const str2 = (judgeAnotherSignal.join('')*1).toString(16); + + const wuXiData = [ + // 卫星时间 精度 纬度 高度 方位角 俯仰角 速度角 速度 横滚 卫星定位状态 + '$KSXT', timeStr, gps.jd, gps.wd, gps.hbg, gps.hxj, gps.fyj, '0' , gps.sd, '0', gps.dwzt, + //前天线可用星数 后天线可用星数 东向坐标位置 北向位置坐标 天向位置坐标 东向速度 北向速度 天向速度 + '0', '0', '0', '0', '0', '0', '0', '0','0', + //@ts-ignore 评判信号1 评判信号2 发动机转速 + // (judgeSignal.join('')*1).toString(16), (judgeAnotherSignal.join('')*1).toString(16) , sensor.fdjzs, + '0006', '0001' , sensor.fdjzs, + '0xFFFFFFF' + ] + return wuXiData.map(d => (d + '')).join(','); + // console.log('wuXiData',wuXiData.join(',')); +} + +export const getTimeStr = async () =>{ + const date = await systemTime.getDate() + const timeStr = ''; + const Y = date.getFullYear(); + const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) ; + const D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()); + const h = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()); + const m = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()); + const s = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds()); + const ss = (date.getMilliseconds() +'').slice(0,2); + return timeStr + Y + M +D +h +m +s +'.' + ss +} + +//蓝灯 +export function sendBlue(){ + const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00]; + const arrBlueBuffer= Array2Byte(arrBlue).buffer + globalThis.lightLineUdp.send(arrBlueBuffer); +} + +//绿灯 +export function sendGreen(){ + const arrGreen = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x00, 0x03, 0x01]; + const arrGreenBuffer= Array2Byte(arrGreen).buffer + globalThis.lightLineUdp.send(arrGreenBuffer); +} + +//红灯 +export function sendRed(){ + const arrRed= [0x55, 0xaa, 0x01, 0x01, 0x02, 0x00, 0x03, 0x00]; + const arrRedBuffer= Array2Byte(arrRed).buffer + globalThis.lightLineUdp.send(arrRedBuffer); +} + +export const defaultJudgeConfigObj = { +//结束考试方式 0-不合格继续 1-考试不合格报靠边停车 2-不合格不报靠边 3-训练不合格报靠边 4-自动退出 5-不合格自动退出 + 302:'5', + 332:'', +//是否能进行人工操作 0-不能人工评判 1-不能人工进项目 3-都不能 + 342:'', +//有项目未结束时可以靠边停车 0-否 1-是 + 343:'1', +//考试未结束且有扣分,是否可以退出 + 344:'0', +//直线行驶中是否可以进其它项目 0-否 1-是 + 348:'0', +//车上是否能点结束考试 0:否 1:是 + 353:'0', +//是否启动断电续考 0:否 1:是 + 369:'1', +//是否显示应考里程 + 375:'0', +//里程不够允许手工点靠边停车 + 387:'0', +//监管模式有扣分续考(0-否++1-是+把上次未考完的扣分带下来重新考试) + 432:'1' +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts new file mode 100644 index 00000000..d8fed5ac --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts @@ -0,0 +1,17 @@ + + +//考试回放开关 +export const judgeConfig = { + //本地目录开关 + isTrajectoryOpen: false, + //是否开启Udp + udpOpen:false, + // 本地模型地址 + modelPath: 'models/model_enc', + // 轨迹回放地址 + trajectoryPath: 'logs/2024_07_06/0000000000001_342323199501470011_测试学员1_2024_07_06_16_22_35/judge_exam_data.txt', + //TODO 济南临时特殊配置 + systemParamConfig:{ + + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeReal.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeReal.ts new file mode 100644 index 00000000..931cb599 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeReal.ts @@ -0,0 +1,48 @@ +import { + examJudgeMapSetParam, + examJudgeMapSetScaling +} from '../api/index' +import systemTime from '@ohos.systemDateTime'; + +import FileUtil from '../../../common/utils/File' +import FileModel from './fileModel' +import {testRealExam} from '../dataTest/index' + +const judgeTag = 'SURENJUN_JUDGE' + +export default class JudgeImg { + + private judgeUI + private modelPath:string + private fileModel:FileModel + private fileUtil:FileUtil + private plcData:any + + constructor(judgeUI) { + this.modelPath = 'models/model_enc' + this.judgeUI = judgeUI + this.fileUtil = new FileUtil(judgeUI.context) + this.fileModel = new FileModel(judgeUI.context) + this.init() + } + + async init(){ + const isJudgeInitBool = globalThis.isJudgeInitBool; + const {judgeUI} = this; + + //TODO 临时处理 + setTimeout(async ()=>{ + console.info(judgeTag,'1.进入评判入口') + await examJudgeMapSetParam(640, 480); //设置参数宽、高 + await examJudgeMapSetScaling(120); //设置缩放比例,一般默认填100(就是100%的意思) ,数字越大视野越大,数字越小视野越小,不能为0 + }) + + judgeUI.draw = true + + } + + //获取评判初始化数据 + getInitInfo = () =>{ + + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts new file mode 100644 index 00000000..7925f759 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeTask.ts @@ -0,0 +1,42 @@ +import Prompt from '@system.prompt' + +const TAG = 'SURENJUN_JUDGE' + +export default class JudgeTask{ + private queue = [] + private status:string + constructor() { + this.queue = [] + this.status = 'end' + } + + executeQueue = async ()=>{ + const {queue,executeQueue} = this + if(queue.length){ + for (const currentTask of queue) { + const {status} = this + try { + await currentTask(); + }catch (e){ + // console.info(TAG,'过程数据接口解析错误') + Prompt.showToast({ + message: '过程数据接口解析错误', + duration: 3000 + }); + } + this.queue.shift() + await executeQueue() + } + }else{ + this.status = 'end' + } + } + + addTask = async (fn) =>{ + this.queue.push(fn); + if(this.status == 'end' && this.queue.length === 1){ + await this.executeQueue(); + } + } + +} diff --git a/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts new file mode 100644 index 00000000..7be0b853 --- /dev/null +++ b/entry/src/main/ets/pages/judgeSDK/utils/voiceAnnouncements.ts @@ -0,0 +1,150 @@ +import media from '@ohos.multimedia.media'; +import Prompt from '@system.prompt'; + +const TAG = 'VoiceAnnounce' + +export default class VoiceAnnounce{ + + //队列时候立马终止 + private isStopped:Boolean + private queue:String[] + private newQueue:String[] + private pendingQueue:String[] + private callback:Function; + constructor() { + this.isStopped = false; + this.queue = [] + } + + async playAudio(urls:string[],shit?:boolean,callback?:Function){ + const {isStopped,queue} = this; + this.callback = callback + if(shit){ + //队列清空,重新初始化 + this.isStopped = true; + this.newQueue = urls + } + if(queue.length){ + //队列续上 + this.queue = this.queue.concat(urls); + + }else{ + this.queue = urls + await this.executeQueue() + } + } + + async executeQueue(){ + const avPlayer = new AVPlayer(); + const go = async () => { + const {queue,callback,isStopped,newQueue} = this; + if(isStopped){ + //清空原来队列 + this.queue = newQueue + this.isStopped = false; + await go() + return + } + + await avPlayer.play(queue[0],callback); + this.queue.shift(); + console.info(TAG,JSON.stringify(this.queue),'堆栈弹出'); + if(this.queue.length){ + await go() + } + } + await go() + avPlayer.avPlayerStop(); + } + +} + + +class AVPlayer { + + public avPlayer:any = null; + + private voiceUrl: string[]; + private voiceStatus: 'completed' | 'playing' + private endCallback:Function + constructor() {} + + // 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放示例 + async play(name,callback) { + this.endCallback = callback + const avPlayer = await media.createAVPlayer(); + this.avPlayer = avPlayer; + return new Promise(async (resolve,reject) => { + let url = '' + await this.setAVPlayerCallback(()=>{ + //@ts-ignore + resolve() + }); + try { + url = await globalThis.context.resourceManager.getRawFd(name); + this.avPlayer.fdSrc = url; + } catch (e) { + Prompt.showToast({ + message: `${name}语音文件不存在`, + duration: 4000 + }); + resolve(1) + } + }) + } + //音频播放队列 + public releasePlayer() { + this.avPlayer.release(); + } + + avPlayerStop() { + this.avPlayer && this.avPlayer.stop() + this.avPlayer && this.avPlayer.reset() + this.avPlayer && this.avPlayer.release() + } + // 注册avplayer回调函数 + setAVPlayerCallback(callBack) { + + this.avPlayer.on('error', (err) => { + this.avPlayer && this.avPlayer.stop() + this.avPlayer && this.avPlayer.reset() + this.avPlayer && this.avPlayer.release() + }) + + let num = 0; + // 状态机变化回调函数 + this.avPlayer.on('stateChange', async (state, reason) => { + const {endCallback} = this; + switch (state) { + case 'idle': // 成功调用reset接口后触发该状态机上报 + break; + case 'initialized': // avplayer 设置播放源后触发该状态上报 + this.avPlayer.prepare() + break; + case 'prepared': // prepare调用成功后上报该状态机 + this.avPlayer.play(); + this.voiceStatus = 'playing' + break; + case 'playing': // play成功调用后触发该状态机上报 + break; + case 'paused': // pause成功调用后触发该状态机上报 + break; + case 'completed': // 播放结束后触发该状态机上报 + this.voiceStatus = 'completed' + this.avPlayer.stop(); //调用播放结束接口 + if(endCallback){ + endCallback() + } + break; + case 'stopped': // stop接口成功调用后触发该状态机上报 + this.avPlayer.reset(); // 调用reset接口初始化avplayer状态 + callBack() + break; + case 'released': + break; + default: + break; + } + }) + } +} \ No newline at end of file