Compare commits

..

5 Commits

Author SHA1 Message Date
wangzhongjie
5910f134a2 Merge branch 'api10' of http://88.22.24.105:3000/harmony_car/subject-two into api10 2025-03-26 17:30:40 +08:00
wangzhongjie
4912419089 refactor: MD5 2025-03-26 17:30:38 +08:00
wangzhongjie
13ea6937b3 refactor: 增加注释以完善UDP信号处理逻辑 2025-03-26 17:10:22 +08:00
wangzhongjie
a7a9bd1acc refactor: 完善全局配置类型,优化UDP信号获取逻辑 2025-03-26 16:07:39 +08:00
wangzhongjie
8cf0419e12 refactor: 补全类型 2025-03-26 15:00:27 +08:00
9 changed files with 371 additions and 52 deletions

View File

@ -1,3 +1,5 @@
import { GlobalConfigType } from '../model';
/* /*
* @Author: wangzhongjie * @Author: wangzhongjie
* @Date: 2024-03-07 10:54:53 * @Date: 2024-03-07 10:54:53
@ -6,36 +8,36 @@
* @Description: 全局配置 * @Description: 全局配置
* @Email: shutdown0630@163.com * @Email: shutdown0630@163.com
*/ */
export const GlobalConfig={ export const GlobalConfig: GlobalConfigType = {
comoonfileWriteAddress:'/mnt/hmdfs/100/account/device_view/local/files/duolun', comoonfileWriteAddress: '/mnt/hmdfs/100/account/device_view/local/files/duolun',
picSavePath:'/storage/cloud/100/files/Photo/', picSavePath: '/storage/cloud/100/files/Photo/',
videoSavePath:'/storage/cloud/100/files/Videos/', videoSavePath: '/storage/cloud/100/files/Videos/',
host:'http://172.37.55.192:8082', host: 'http://172.37.55.192:8082',
modelNo: "3",
version:{ version: {
//杭州 //杭州
hz:{ hz: {
km2:['2022.03.14.01','2022.03.17.1'], km2: ['2022.03.14.01', '2022.03.17.1'],
km3:[], km3: [],
}, },
//黑龙江 //黑龙江
hlg:{ hlg: {
km2:['2024.03.19.01','2024.01.05.1'], km2: ['2024.03.19.01', '2024.01.05.1'],
km3:['2023.09.23.01','2023.09.23.01'], km3: ['2023.09.23.01', '2023.09.23.01'],
}, },
//济南 //济南
jn:{ jn: {
km2:[], km2: [],
km3:['2023.12.13.01','2023.09.30.1'] km3: ['2023.12.13.01', '2023.09.30.1']
}, },
//洛阳 //洛阳
ly:{ ly: {
km2:['2022.06.29.01','2022.12.18.1'], km2: ['2022.06.29.01', '2022.12.18.1'],
km3:['2022.08.13.01','2022.12.05.1'], km3: ['2022.08.13.01', '2022.12.05.1'],
}, },
sz:{ sz: {
km2:['2024.08.21.01','2024.08.24.1'], km2: ['2024.08.21.01', '2024.08.24.1'],
km3:[], km3: [],
}, },
} }
} }

View File

@ -7,8 +7,8 @@ import { centerUDPClient, lightUDPClient, objUDPClient } from '../utils/UdpUtils
import Want from '@ohos.app.ability.Want'; import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import { BaseInfoType, CarInfoType, ExaminerInfoType } from '../model'; import { BaseInfoType, CarInfoType, ExaminerInfoType } from '../model';
import DB from '../utils/DbSql';
import { tcpUtil } from '../utils/TcpRequest'; import { tcpUtil } from '../utils/TcpRequest';
import DB from '../utils/DbSql';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {

View File

@ -132,4 +132,28 @@ export interface EnvironmentConfigurationType {
centerIp?: string, centerIp?: string,
centerPort?: string, centerPort?: string,
terType?: string terType?: string
}
//全局配置
export interface GlobalConfigType {
comoonfileWriteAddress?: string
picSavePath?: string
videoSavePath?: string
host?: string
version?: VersionType
// 几代机
modelNo?: string
}
interface VersionType {
hz: VersionInfo;
hlg: VersionInfo;
jn: VersionInfo;
ly: VersionInfo;
sz: VersionInfo;
}
interface VersionInfo {
km2: string[];
km3: string[];
} }

View File

@ -1,4 +1,14 @@
export interface TakePhotoCallbackData { export interface TakePhotoCallbackData {
fileSize: number; fileSize: number;
errorCode: number errorCode: number
}
export interface ObtainSignalDataConfigType {
// UDP配置
udpLocalIp?: string
udpLocalIpPort?: string
udpOppositeIp?: string
udpOppositeIpPort?: string
} }

View File

@ -90,7 +90,7 @@ export async function SetCurrentTime(): Promise<void> {
judgeVersion: baseInfo.judgeVersion judgeVersion: baseInfo.judgeVersion
} }
let res: ApiResponseType = await timeSynchronization(params); let res: ApiResponseType = await timeSynchronization(params);
AppStorage.setOrCreate<ApiResponseType.timeSynchronizationRsp.body>('timeInfo', res.timeSynchronizationRsp.body) AppStorage.setOrCreate<TimeSynchronizationRspBody>('timeInfo', res.timeSynchronizationRsp.body)
let currentTime = res.timeSynchronizationRsp.head.time; let currentTime = res.timeSynchronizationRsp.head.time;
let times = new Date(currentTime).getTime(); let times = new Date(currentTime).getTime();
try { try {
@ -110,7 +110,6 @@ export async function TakePhoto(context: common.UIAbilityContext) {
spzd3: false, spzd3: false,
spzd4: false, spzd4: false,
} }
let map = {}
const fileUtil = new FileUtils(context) const fileUtil = new FileUtils(context)
const fileData = await fileUtil.readFile(GlobalConfig.comoonfileWriteAddress + '/config/config3.txt'); const fileData = await fileUtil.readFile(GlobalConfig.comoonfileWriteAddress + '/config/config3.txt');
param = JSON.parse(fileData) param = JSON.parse(fileData)

View File

@ -0,0 +1,227 @@
class Md5 {
private static _inst: Md5;
A = 0x67452301;
B = 0xefcdab89;
C = 0x98badcfe;
D = 0x10325476;
S = [
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
]
public static get Instance(): Md5 {
return this._inst || (this._inst = new Md5());
}
public get_md5(str: string): string {
return this.md5(str);
}
split(target: string | any[], step: number, markString: boolean = typeof target === "string") {
if (typeof target === "string") {
target = target.split("");
}
let result: any[] = target.map(
(_, index: number) =>
index % step === 0
? Array.from(Array(step).keys()).map((x: number) => target[index + x])
: []
)
.filter((x: any[]) => x.length > 0);
if (markString) {
result = result.map((x: any[]) => x.join(""))
}
return result;
}
padding(str: string | any[], length: number, char: string, tail: boolean = true,
isArray: boolean = Array.isArray(str)) {
let arr;
if (Array.isArray(str)) {
arr = str;
} else {
arr = str.split("");
}
const paddingStr: any[] = this.range(length - str.length).map(() => char);
const result = tail ? arr.concat(paddingStr) : paddingStr.concat(arr);
return isArray ? result : result.join("");
}
little_endian(charCode: number) {
return this.split(this.padding(charCode.toString(16), 8, "0", false), 2).reverse().join("");
}
range(...args: number[]) {
const start: number = args.length === 1 ? 0 : args[0];
const end: number = args.length === 2 ? args[1] : args[0] - 1;
return Array.from(Array(end - start + 1).keys()).map((x: number) => x + start);
}
to_binary(code: number, bit: number = 8, max: number = Math.pow(2, bit) - 1) {
if (code < 0) {
throw new Error("code should be greater than: 0");
}
if (code > max) {
throw new Error("code should be less than: " + max);
}
return this.padding(code.toString(2), bit, "0", false);
}
to_hex(code: number, bit: number = 8, max: number = Math.pow(16, bit) - 1) {
if (code < 0) {
throw new Error("code should be greater than: 0");
}
if (code > max) {
throw new Error("code should be less than: " + max);
}
return this.padding(code.toString(16), bit, "0", false);
}
to_code(str: string) {
if (str.substr(0, 2).toLowerCase() === "0b") {
return parseInt(str.substr(2, 8), 2);
}
if (str.substr(0, 2).toLowerCase() === "0x") {
return parseInt(str.substr(2, 8), 16);
}
}
utf16_to_utf8(str: string) {
return str.split("").map((char: string) => this.utf8_encode(char)).join("");
}
utf8_encode(char: string) {
let utftext = "";
const c = char.charCodeAt(0);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 0b11000000);
utftext += String.fromCharCode((c & 0b00111111) | 0b10000000);
} else {
utftext += String.fromCharCode((c >> 12) | 0b11100000);
utftext += String.fromCharCode(((c >> 6) & 0b00111111) | 0b10000000);
utftext += String.fromCharCode((c & 0b00111111) | 0b10000000);
}
return utftext;
}
uint_add(...args: number[]) {
const t = Uint32Array.from([0]);
const x = Uint32Array.from(args);
x.forEach(n => t[0] = t[0] + n);
return t[0];
}
loop_shift_left(n: number, bits: number) {
return (n << bits) | (n >>> (32 - bits));
}
F(b: number, c: number, d: number) {
return (b & c) | (~b & d);
}
G(b: number, c: number, d: number) {
return (b & d) | (c & ~d);
}
H(b: number, c: number, d: number) {
return b ^ c ^ d;
}
I(b: number, c: number, d: number) {
return c ^ (b | ~d)
}
T(i: number) {
return Math.floor(Math.pow(2, 32) * Math.abs(Math.sin(i + 1)));
}
x_index(i: number) {
if (i >= 0 && i <= 15) {
return i;
}
if (i >= 16 && i <= 31) {
return (5 * i + 1) % 16;
}
if (i >= 32 && i <= 47) {
return (3 * i + 5) % 16;
}
if (i >= 48 && i <= 63) {
return (7 * i) % 16;
}
return 0;
}
wrap(m: any) {
return (a: number, b: number, c: number, d: number, x: number, s: number, t: number) => {
// 循环左移
return this.uint_add(this.loop_shift_left(this.uint_add(a, m(b, c, d), x, t), s), b);
};
}
porcess_message(str: string) {
const length = str.length;
const length_of_zero = Math.ceil(length / 64) * 64 - length - 8 - 1;
str += String.fromCharCode(0b10000000);
const strArray = this.padding(str.split(""), length + 1 + length_of_zero, String.fromCharCode(0));
const tail =
this.split(this.padding(this.to_binary(length * 8 % Math.pow(2, 64)), 64, "0"), 8).map(x => parseInt(x, 2));
const head = (strArray as any[]).map(x => x.charCodeAt(0));
return Uint32Array.from(
this.split(head.concat(tail), 4)
.map(x =>
x.map((t: number) => this.padding(t.toString(16), 2, "0", false)).join("")
)
.map(x => parseInt(x, 16))
.map(x => parseInt(this.little_endian(x), 16))
)
}
fghi(i: number) {
if (i >= 0 && i <= 15) {
return this.F;
}
if (i >= 16 && i <= 31) {
return this.G;
}
if (i >= 32 && i <= 47) {
return this.H;
}
if (i >= 48 && i <= 63) {
return this.I;
}
}
fghi_wrapped(i: number) {
return this.wrap(this.fghi(i));
}
//------------------------------------------------
md5(str: string) {
str = this.utf16_to_utf8(str);
const uint32_array = this.porcess_message(str);
const result = Uint32Array.from([this.A, this.B, this.C, this.D]);
const chunks = this.split(Array.from(uint32_array), 16);
for (const chunk of chunks) {
const a = result[0];
const b = result[1];
const c = result[2];
const d = result[3];
for (let i = 0; i < 64; i++) {
result[(4 - i % 4) % 4] =
this.fghi_wrapped(i)(result[(4 - i % 4) % 4], result[((4 - i % 4) + 1) % 4], result[((4 - i % 4) + 2) % 4],
result[((4 - i % 4) + 3) % 4], chunk[this.x_index(i)], this.S[i], this.T(i))
}
result[0] = a + result[0];
result[1] = b + result[1];
result[2] = c + result[2];
result[3] = d + result[3];
}
return Array.from(result).map(x => this.little_endian(x)).join("").toLowerCase();
}
}
export default Md5

View File

@ -13,7 +13,7 @@ interface IPConfig {
udpOppositeIpPort: string udpOppositeIpPort: string
} }
class UdpClient { export default class UdpClient {
private localIp: string = '' private localIp: string = ''
private localIpPort: string = '' private localIpPort: string = ''
private oppositeIp: string = '' private oppositeIp: string = ''
@ -24,7 +24,9 @@ class UdpClient {
private dealMethod: DealMethod private dealMethod: DealMethod
bindUdp(): Promise<void> { bindUdp(): Promise<void> {
return this.udp.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 }) return this.udp.bind({
address: this.localIp, port: parseInt(this.localIpPort), family: 1
})
} }
async reBind() { async reBind() {
@ -56,12 +58,14 @@ class UdpClient {
return this.udp?.getState().then(() => { return this.udp?.getState().then(() => {
return this.udp.send({ return this.udp.send({
data, data,
address: { address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1 } address: {
address: this.oppositeIp, port: parseInt(this.oppositeIpPort), family: 1
}
}) })
}) })
} }
protected create(udpLocalIp: string, udpLocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { 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
@ -86,6 +90,7 @@ class UdpClient {
} }
} }
// 获取后置机信号
class ObjUdpClient extends UdpClient { class ObjUdpClient extends UdpClient {
async init(context: common.UIAbilityContext) { async init(context: common.UIAbilityContext) {
try { try {
@ -103,6 +108,7 @@ class ObjUdpClient extends UdpClient {
} }
} }
// 给中心发送消息
class CenterUDPClient extends UdpClient { class CenterUDPClient extends UdpClient {
async init(context: common.UIAbilityContext) { async init(context: common.UIAbilityContext) {
try { try {
@ -121,6 +127,7 @@ class CenterUDPClient extends UdpClient {
} }
} }
// 顶灯
class LightUDPClient extends UdpClient { class LightUDPClient extends UdpClient {
async init(context: common.UIAbilityContext) { async init(context: common.UIAbilityContext) {
try { try {

View File

@ -1,8 +1,7 @@
import FileUtil from './File'
import { uploadHarmonyLiCheng } from '../../api/judge'
import { GetCurrentTime } from '../Common' import { GetCurrentTime } from '../Common'
import FileUtils from '../FileUtils'
import common from '@ohos.app.ability.common'
const LOGTAG = 'GetDistance'
export default class GetDistance { export default class GetDistance {
public folderPath: string public folderPath: string
@ -11,11 +10,12 @@ export default class GetDistance {
public totalTime: number public totalTime: number
public date: string public date: string
public fd: number public fd: number
//后续文件路径待替换
private fileUtil: FileUtils
// 设置文件夹 // 设置文件夹
public initFolder = async () => { public initFolder = async () => {
const { fileUtil } = this
const time = await GetCurrentTime() const time = await GetCurrentTime()
const folderPath = await fileUtil.initFolder(`/车辆行驶距离统计`); const folderPath = await this.fileUtil.initFolder(`/车辆行驶距离统计`);
console.info('surenjun folderPath=>', folderPath); console.info('surenjun folderPath=>', folderPath);
const date = time.split(' ')[0].split('-').join('_') const date = time.split(' ')[0].split('-').join('_')
const timeStr = time.split(' ')[1] const timeStr = time.split(' ')[1]
@ -24,34 +24,32 @@ export default class GetDistance {
this.totalDistance = 0; this.totalDistance = 0;
this.totalTime = 0; this.totalTime = 0;
this.date = date; this.date = date;
this.fd = await fileUtil.editFile( this.fd = await this.fileUtil.editFile(
`${folderPath}/${date}.txt`, `${folderPath}/${date}.txt`,
`程序启动时间:${timeStr} 累计行驶距离:${this.totalDistance}m 累计运行时常:${this.totalTime}min`, this.fd `程序启动时间:${timeStr} 累计行驶距离:${this.totalDistance}m 累计运行时常:${this.totalTime}min`, this.fd
); );
return folderPath return folderPath
} }
//后续文件路径待替换
private fileUtil: FileUtil
constructor(context) { constructor(context: common.UIAbilityContext) {
const fileUtil = new FileUtil(context) const fileUtil = new FileUtils(context)
this.fileUtil = fileUtil; this.fileUtil = fileUtil;
} }
// 过程文件数据 // 过程文件数据
public setTimeData = async (str: number) => { public setTimeData = async (str: number) => {
const { fileUtil, folderPath, timeStr, date, totalDistance } = this; // const { fileUtil, folderPath, timeStr, date, totalDistance } = this;
console.log('folderPath', folderPath) console.log('folderPath', this.folderPath)
const content = await fileUtil.readFile(`${folderPath}/${date}.txt`) || ''; const content = await this.fileUtil.readFile(`${this.folderPath}/${this.date}.txt`) || '';
const contentArr = content.split('\n').filter(item => item) const contentArr = content.split('\n').filter(item => item)
console.info('surenjun contentArr', JSON.stringify(contentArr)) console.info('surenjun contentArr', JSON.stringify(contentArr))
this.totalDistance += (str * 1 > 200 ? 200 : str * 1) this.totalDistance += (str * 1 > 200 ? 200 : str * 1)
this.totalTime += 1; this.totalTime += 1;
contentArr[contentArr.length - 1] = contentArr[contentArr.length - 1] =
`程序启动时间:${timeStr} 累计行驶距离:${(this.totalDistance).toFixed(2)}m 累计运行时常:${Math.ceil(this.totalTime / `程序启动时间:${this.timeStr} 累计行驶距离:${(this.totalDistance).toFixed(2)}m 累计运行时常:${Math.ceil(this.totalTime /
60)}min` + '\n' 60)}min` + '\n'
console.info('surenjun', contentArr.join('\n')) console.info('surenjun', contentArr.join('\n'))
console.log('folderPath', folderPath, date) console.log('folderPath', this.folderPath, this.date)
this.uploadData() this.uploadData()
// await fileUtil.addFile( // await fileUtil.addFile(
@ -61,16 +59,11 @@ export default class GetDistance {
//上传行驶里程数据 //上传行驶里程数据
uploadData = async () => { uploadData = async () => {
setInterval(() => { setInterval(() => {
const { carId } = AppStorage.get<CarInfoType>('carInfo'); // const { carId } = AppStorage.get<CarInfoType>('carInfo');
const { date, timeStr, totalDistance } = this; // const { date, timeStr, totalDistance } = this;
return return
//"carid":"1001","startTime":"2024-08-24 08:09:01","time":"111233", "mileage":"1222" //"carid":"1001","startTime":"2024-08-24 08:09:01","time":"111233", "mileage":"1222"
uploadHarmonyLiCheng({
carid: carId,
startTime: `${date.split('_').join('-')} ${timeStr}`,
time: timeStr,
mileage: totalDistance
})
}, 5000) }, 5000)
} }
} }

View File

@ -0,0 +1,57 @@
import { GlobalConfig } from '../../config'
import { ObtainSignalDataConfigType } from '../../model'
import UdpClient from '../UdpUtils'
class obtainSignalData {
// 三代机UDP
private thirdGenerationMachineUdp: UdpClient
// 三代机UDP配置
private thirdGenerationMachineUdpConfig: ObtainSignalDataConfigType
// 几代机
private modelNo: string = "3"
constructor() {
this.modelNo = GlobalConfig.modelNo
}
// 一些初始化
init(config: ObtainSignalDataConfigType) {
this.thirdGenerationMachineUdpConfig = config
if (this.modelNo === "0") {
} else if (this.modelNo === "1") {
} else if (this.modelNo === "2") {
} else if (this.modelNo === "3") {
// 初始化UDP
this.thirdGenerationMachineUdp = new UdpClient()
this.thirdGenerationMachineUdp.create(config.udpLocalIp, config.udpLocalIpPort, config.udpOppositeIp,
config.udpOppositeIpPort)
}
}
// 获取信号
getData(callback: (data: string) => void) {
// 一代机
// 二代机
// 三代机 通过UDP onMessage获取信号
if (this.modelNo === "3") {
this.thirdGenerationMachineUdp.onMessage((data: ArrayBuffer) => {
const dataView = new DataView(data);
let str = ""
for (let i = 0; i < dataView?.byteLength; ++i) {
let c = String.fromCharCode(dataView?.getUint8(i))
if (c !== "\n") {
str += c
}
}
callback(str)
})
}
// 一体机
}
}
export const ObtainSignalData = new obtainSignalData()