/* * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // @ts-ignore import socket, { UDPSocket } from '@ohos.net.socket'; import { Array2Byte } from '../utils/tools' import FileUtil from '../../common/utils/File' import { fillZero, string2Bytes } from '../utils/tools' const TAG = '[UdpDemo.UdpClient]' import hilog from '@ohos.hilog'; import prompt from '@ohos.prompt' import promptAction from '@ohos.promptAction'; import { getUDP } from './GlobalUdp'; import { dateFormat } from '../utils/tools' import { getSyncData } from '../service/initable'; export default class UdpClientByCenter { private localIp: string = '' private localIpPort: string = '' private oppositeIp: string = '' private oppositeIpPort: string = '' private udpMsg: any = '' private chafenFlag: number = 0 private num: number = 0 private fileUtil: FileUtil private udp: UDPSocket = null private sendId: any = 0 private lsh: string = null private context private folderPath private stashFn: StashFunction private errorStep: number=0 private interval private headLenth: number = 9 //消息头长度 private isWorking: Boolean = false private plcUdpError = false; private initParam private onMessage_1Callback:Function = ()=>{} public currentValue:string = '' constructor(udplocalIp: string, udplocalIpPort: string, udpOppositeIp: string, udpOppositeIpPort: string) { this.localIp = udplocalIp this.oppositeIp = udpOppositeIp this.localIpPort = udplocalIpPort this.oppositeIpPort = udpOppositeIpPort this.stashFn = () => { } this.udp = socket.constructUDPSocketInstance(); this.initPath() } getStatus() { return this.isWorking } rebindUdp(localIp: string, localIpPort: string, oppositeIp: string, oppositeIpPort: string) { console.log(`${TAG}getUDPudpCLient rebindUdp enter localIp:${localIp},localIpPort:${localIpPort},oppositeIp:${oppositeIp},oppositeIpPort:${oppositeIpPort}`); this.localIp = localIp this.oppositeIp = oppositeIp this.localIpPort = localIpPort this.oppositeIpPort = oppositeIpPort let promise = this.udp.bind({ // address: '192.168.7.170', port: 20122, family: 1 address: this.localIp, port: parseInt(this.localIpPort), family: 1 }); promise.then(() => { // globalThis.closeHeartSocket=false this.isWorking = true console.log(`${TAG} getUDPudp rebind success`); // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG} getUDPudp rebind success`, // }) }).catch(err => { //globalThis.closeHeartSocket=true this.isWorking = false // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`, // }) console.log(`${TAG} getUDPudp rebind failed:${JSON.stringify(err)}`); }); } bindUdp() { let promise = this.udp.bind({ address: this.localIp, port: parseInt(this.localIpPort), family: 1 }); promise.then(() => { this.isWorking = true // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG} getUDPudp bind success`, // }) }).catch(err => { this.isWorking = false // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG} getUDPudp bind error${JSON.stringify(err)},localIp:${this.localIpPort},port:${this.localIpPort}`, // }) }); } //异或运算 setMessageExclusive(tmpList) { let result = tmpList[0]; for (let i = 1; i < tmpList.length; i++) { result = result ^ tmpList[i] } return [result]; } Array2Byte(array) { var buf = new ArrayBuffer(array.length); var view = new Uint8Array(buf); for (var i = 0; i != array.length; ++i) { view[i] = array[i] & 0xFF; } return view; } //length消息体bufferlength id消息类型id bodyStr消息体string // setMsyBody(id,bodyByte){ // {id: 31,list:[0,1,'0000000000000'],carNo:489,placeId:62} setWholeMsg(params) { let head = this.setMsgHead(params); let headJudge = this.setMessageExclusive(head); let body = this.setMsgBody(params); let bodyJudge = this.setMessageExclusive(body); let end = [13, 10]; const arr = [...head, ...headJudge, ...body, ...bodyJudge, ...end] console.log('BitArray', arr) return this.Array2Byte(arr).buffer } setMsgHead({id, list, placeId=62, carNo=489}) { console.log('globalThis.lshNo', globalThis.lshNo) let a = string2Bytes(`${id}${fillZero(placeId, 3)}`, 2 * 8); console.log('aaa', a) let b = string2Bytes(`${fillZero(carNo, 4)}${globalThis.lshNo}`, 4 * 8); console.log('bbb', b) let c = string2Bytes(list.length, 2 * 8); return [...a, ...b, ...c]; } setMsgBody({id,list}) { let tmpList = [] tmpList = list return tmpList; } sendHeadMsg(msgData) { console.log('getUDPsendHeadMsg enter') this.sendMsg(msgData, null) console.log('getUDPsendHeadMsg exit') } sendMsg(msg, sendCallback?) { if (!this.isWorking ) { console.log(`${TAG}getUDPudpCLient sendMsg is closed return `); // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG}getUDPudpCLient sendMsg is closed return oppositeIp:${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort:${this.localIpPort}`, // }) if(sendCallback) { sendCallback() } return; } let promise = this.udp.send({ data: msg, address: { address: this.oppositeIp, port: parseInt(this.oppositeIpPort), } }); promise.then(() => { if (sendCallback) { sendCallback() } // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG}getUDPudpCLient udp send success: oppositeIp:${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort:${this.localIpPort}`, // }) }).catch(err => { // this.writeLog({ // time:dateFormat(new Date()), // PLC:`${TAG}getUDPudpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}${JSON.stringify(err)}`, // }) promptAction.showToast({ message:`${TAG}getUDPudpCLient udp send fail:oppositeIp${this.oppositeIp},oppositeIpPort:${this.oppositeIpPort},localIp:${this.localIp},localIpPort,${this.localIpPort}`, duration:4000 }) }); } sendMsgExt(param, context?) { console.log('sendMsgExt enterbitbit',JSON.stringify(param)); if (context) { this.context = context } this.sendId = param.id const msgData = this.setWholeMsg(param) this.sendMsg(msgData, param.sendCallback) } onError_Callback(callback?) { this.udp.on('error', async err => { this.isWorking = false; // this.writeLog({ // time:dateFormat(new Date()), // PLC:'getUDPUdpClientByCenter onError err:' + JSON.stringify(err)+this.oppositeIpPort, // }) callback && callback() }); } onError_resend(callback?) { this.udp.on('error', async err => { this.isWorking = false; callback && callback() }); } setMsgCallBack(callback) { this.stashFn = callback ? callback : () => { } } //中心udp回执 onMessage_2(callback, type?) { this.udp.on('message', (value, remoteInfo) => { console.log('UdpClientByCenter onMessage msg:' + JSON.stringify(value)); let arr = [] let dataView = new DataView(value.message) for (let i = 0; i < dataView?.byteLength; ++i) { arr[i] = dataView?.getUint8(i) } let idNum = '0x' + fillZero(arr[1].toString(16), 2) + fillZero(arr[0].toString(16), 2); let id = Math.floor(+idNum / 1000) let lengthNum = '0x' + fillZero(arr[7].toString(16), 2) + fillZero(arr[6].toString(16), 2); let length = +lengthNum; let list = [] for (let i = this.headLenth; i <= this.headLenth + length - 1; i++) { list.push(arr[i]) } this.stashFn({ id, length, body: list, sendId: this.sendId }) callback({ id, length, body: list, sendId: this.sendId }) hilog.info(0x0000, 'bitbitarrrbitbitarrr', JSON.stringify({ id, length, body: list, sendId: this.sendId })); // this.interval=setInterval(()=>{ // // },3000) }); } closeUdp(callback?) { console.log('getUDPUdpClientByCenter enter closeUdp ip:' + this.localIp + ' port:' + this.localIpPort); this.udp.close(err => { if (err) { // this.writeLog({ // time:dateFormat(new Date()), // PLC:'getUDPUdpClientByCenter closeUdp err:' + JSON.stringify(err)+this.oppositeIpPort, // }) } else { this.isWorking = false if (callback != null) { callback() } // this.writeLog({ // time:dateFormat(new Date()), // PLC:'getUDPUdpClientByCenter closeUdp succeed:' + JSON.stringify(err)+this.oppositeIpPort, // }) } }) } //plc onMessage_1(callback?) { this.onMessage_1Callback = callback; this.udp&&this.udp.on('message', this.message_1Fn); } closeMessage_1(){ console.info('surenjun', 'getUDP关闭udp message监听事件') this.udp.off('message',this.message_1Fn); console.info('surenjun', 'getUDP关闭udp message监听事件 成功') } message_1Fn = (value)=>{ console.log(TAG, 'udponmessage') let callback = this.onMessage_1Callback // 收到的是ArrayBuffer 需要进行转换解析 this.plcUdpError = false if (value) { let dataView = new DataView(value.message) let str = "" for (let i = 0; i < dataView?.byteLength; ++i) { let c = String.fromCharCode(dataView?.getUint8(i)) if (c !== "\n") { str += c } } console.log(`${TAG} udp on message array buffer:${str}`); let strachArr = str.split(',') if (strachArr[0] != '#DN_GD') { return } strachArr[28] = globalThis.chuankoMsg || strachArr[28] console.log(`${TAG} udp222 on message array buffer:${str}`); // this.stashFn(str) const newArr = JSON.parse(JSON.stringify(strachArr)) // this.writeLog({ // time:dateFormat(new Date()), // PLC: JSON.stringify(newArr.toString()), // }) if(strachArr[83]!='4'){ console.log('差分状态异常',strachArr[83],strachArr[92]) this.writeLog({ time:dateFormat(new Date()), PLC: `${TAG}差分状态异常,${strachArr[83]},${strachArr[92]}`, }) }else{ globalThis.dialogOpen=false this.chafenFlag=0 } callback && callback(newArr.toString()) this.currentValue = newArr.toString(); } else { callback && callback('') } console.log('messageTimeEnd') this.testIfUdpConnetced(callback) } async writeLog(param){ // const fileUtil = new FileUtil(globalThis.context) // fileUtil.editFile(`${this.folderPath}/plcLog.txt`, JSON.stringify(param)+`\n`) } async initPath(){ // const fileUtil = new FileUtil(globalThis.context) // const date=dateFormat(new Date).split(' ')[0] // this.folderPath = await fileUtil.initFolder(`/PLC/${date}`); } //获取当前UDP信号 getCurrentMessage = () => { return this.currentValue } testIfUdpConnetced(callback) { const arrRed = [0x55, 0xaa, 0x01, 0x01, 0x02, 0x00, 0x03, 0x00]; const arrBlue = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00]; const arrGreen = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x00, 0x03, 0x01]; const arrBlueBuffer = Array2Byte(arrBlue).buffer const arrRedBuffer = Array2Byte(arrRed).buffer const arrGreenBugger = Array2Byte(arrGreen).buffer let num = 0 globalThis.dialogOpen=false //监听udp是否断开 clearInterval(globalThis.messageTimer) globalThis.messageTimer = setInterval(() => { const lightLineUdp = globalThis.lightLineUdp const isJudge = globalThis.isJudge setTimeout(async () => { //程序断开 lightLineUdp?.send(this.plcUdpError ? arrRedBuffer : (isJudge ? arrGreenBugger : arrBlueBuffer)); if (this.plcUdpError) { num++ this.writeLog({ time:dateFormat(new Date()), PLC: 'plc udp信号丢失', }) console.log(TAG, 'plc udp信号丢失') if (num == 3) { getUDP(globalThis.context,true) globalThis.title='plc udp信号丢失' globalThis.type='3' if(!globalThis.dialogOpen){ // AppStorage.SetOrCreate('errorCode', 1); // if(this.errorStep!=1){ // console.log('sys.v_valuesys.v_valuesys.v_value11221') // // this.errorStep=1 // this.avPlayer.playAudio(['voice/差分状态异常.wav']) // getSyncData('MA_SYSSET').then(syssetParams => { // console.log('sys.v_valuesys.v_valuesys.v_value11221',JSON.stringify(syssetParams)) // // @ts-ignore // syssetParams.forEach(sys => { // // 差分长时间是SINGLE状态报考车故障,停止考试(0-否 1-是) // if (sys.v_no === '424'&&sys.v_value==1){ // //plc差分丢失 // AppStorage.SetOrCreate('errorCode', 0); // AppStorage.SetOrCreate('errorCodeFlage', true); // // } // }) // // const errorParam = syssetParams.filter(sys => sys.v_no === '424') // // // that.studentRefreshStatue = studentRefreshParam?.[0]?.v_value || '0' // // // }); // } } num = 0 } prompt.showToast({ message: 'plc udp信号丢失', duration: 2000 }); } this.plcUdpError = true; }, 2000) }, 2000) } // initHeartSendMsg(param,context){ // console.log('1111param',JSON.stringify(param)) // this.initParam=param // this.context=context // } } interface StashFunction { (params: { id: number; length: number; body: any[]; sendId: string }): void; }