|
|
@@ -0,0 +1,277 @@
|
|
|
+// 使用ws模块
|
|
|
+const { monitorEventLoopDelay } = require('perf_hooks');
|
|
|
+const WebSocket = require('ws');
|
|
|
+
|
|
|
+// npm i stickpackage
|
|
|
+// npm i ws
|
|
|
+
|
|
|
+var ws = new WebSocket("ws://jiangyi.site:11111/");
|
|
|
+
|
|
|
+let stringsArray = [
|
|
|
+ "get:version=?",
|
|
|
+ "get:heart_beat=?",
|
|
|
+ "get:time=?",
|
|
|
+
|
|
|
+ "get:work_status=?",
|
|
|
+ "get:fire_status=?",
|
|
|
+ "get:fault_status=?",
|
|
|
+
|
|
|
+ "get:humidity=?",
|
|
|
+ "get:temperature=?",
|
|
|
+ "get:cur_photosen0=?",
|
|
|
+ "get:photosen0=?",
|
|
|
+ "get:net=?",
|
|
|
+ "get:event_num=?",
|
|
|
+ "get:warning_num=?",
|
|
|
+
|
|
|
+ // "set:extra_time=180",
|
|
|
+ // "set:standing_time=10",
|
|
|
+ // "set:interval_time=600",
|
|
|
+
|
|
|
+ // "set:photosen0=6000,6000,6000,6000",
|
|
|
+ // "set:time=24,9,15,21,53,0",
|
|
|
+ // "set:reset=1",
|
|
|
+ // "set:net=WIFI24,12345678,qq.com,1883,user,123456",
|
|
|
+ // "set:event_num=1000",
|
|
|
+ // "set:warning_num=1000",
|
|
|
+ // "set:erase_bit=7",
|
|
|
+];
|
|
|
+let strings_i = 0;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+function bin2String(array) {
|
|
|
+ return String.fromCharCode.apply(String, array);
|
|
|
+}
|
|
|
+
|
|
|
+function calculateChecksum16bit(code) {
|
|
|
+ let sum = 0;
|
|
|
+ for (let i = 0; i < code.length; i++) {
|
|
|
+ sum += code[i]&0xff;
|
|
|
+ // console.log("sum:"+ sum +",i:"+ code[i] );
|
|
|
+ }
|
|
|
+ // 将结果转换为16位二进制字符串
|
|
|
+ return sum&0xffff;
|
|
|
+}
|
|
|
+
|
|
|
+function stringToByteArray(str) {
|
|
|
+ const encoder = new TextEncoder(); // 创建TextEncoder实例
|
|
|
+ const bytes = encoder.encode(str); // 将字符串转换为字节序列
|
|
|
+ return bytes; // 返回字节数组
|
|
|
+}
|
|
|
+
|
|
|
+//小端模式
|
|
|
+function BytesToIntLittleEndian(bytes){
|
|
|
+ var val = 0;
|
|
|
+ for (var i = bytes.length - 1; i >= 0; i--) {
|
|
|
+ val += bytes[i];
|
|
|
+ if (i != 0) {
|
|
|
+ val = val << 8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
+//小端模式
|
|
|
+//number 要转换的整形数值
|
|
|
+//length 要转成什么byte数组,规定数组的长度
|
|
|
+//如uint16,则lenght=2表示两个字节,转成的byte数组长度是length=2
|
|
|
+//如uint32,则lenght=2表示两个字节,转成的byte数组长度是length=4
|
|
|
+function IntToBytesLittleEndian(number, length){
|
|
|
+ var bytes = [];
|
|
|
+ var i = 0;
|
|
|
+ do {
|
|
|
+ bytes[i++] = number & (255);
|
|
|
+ number = number>>8;
|
|
|
+ } while ( i < length )
|
|
|
+ return bytes;
|
|
|
+}
|
|
|
+
|
|
|
+//大端模式
|
|
|
+function BytesToIntBigEndian(bytes){
|
|
|
+ var val = 0;
|
|
|
+ for (var i = 0; i < bytes.length; ++i) {
|
|
|
+ val += bytes[i];
|
|
|
+ if (i < bytes.length-1) {
|
|
|
+ val = val << 8;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return val;
|
|
|
+}
|
|
|
+
|
|
|
+//大端模式
|
|
|
+//number 要转换的整形数值
|
|
|
+//length 要转成什么byte数组,规定数组的长度
|
|
|
+//如uint16,则lenght=2表示两个字节,转成的byte数组长度是length=2
|
|
|
+//如uint32,则lenght=2表示两个字节,转成的byte数组长度是length=4
|
|
|
+function IntToBytesBigEndian(number, length){
|
|
|
+ var bytes = [];
|
|
|
+ var i = length;
|
|
|
+ do {
|
|
|
+ bytes[--i] = number & (255);
|
|
|
+ number = number>>8;
|
|
|
+ } while (i)
|
|
|
+ return bytes;
|
|
|
+}
|
|
|
+
|
|
|
+function Uint8ArrayToString(fileData){
|
|
|
+ var dataString = "";
|
|
|
+ for (var i = 0; i < fileData.length; i++) {
|
|
|
+ dataString += String.fromCharCode(fileData[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return dataString
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+function stringToUint8Array(str){
|
|
|
+ var arr = [];
|
|
|
+ for (var i = 0, j = str.length; i < j; ++i) {
|
|
|
+ arr.push(str.charCodeAt(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ var tmpUint8Array = new Uint8Array(arr);
|
|
|
+ return tmpUint8Array
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+// 封包
|
|
|
+function pack_send(str) {
|
|
|
+ console.log("封包前:"+str);
|
|
|
+
|
|
|
+ body = str;
|
|
|
+ body = stringToByteArray(str);
|
|
|
+ data_len = body.length;
|
|
|
+ data_check = calculateChecksum16bit(body);
|
|
|
+ let headBuf = Buffer.from([0x59, 0x4C, '<', (data_len>>8)&0xff, (data_len>>0)&0xff, (data_check>>8)&0xff, (data_check>>0)&0xff]);
|
|
|
+ let pack_date = headBuf+body
|
|
|
+ ws.send(pack_date);
|
|
|
+ console.log("封包后:"+pack_date);
|
|
|
+}
|
|
|
+
|
|
|
+function handler_recv(out){
|
|
|
+ console.log("解析:" + out);
|
|
|
+ str = String(out);
|
|
|
+ let arr = str.split("=");
|
|
|
+ if(arr.length == 2){
|
|
|
+ let key = arr[0]
|
|
|
+ let val = arr[1]
|
|
|
+ if(key == "heart_beat"){
|
|
|
+ let arr2 = val.split(",");
|
|
|
+ if(arr2.length == 6){
|
|
|
+ year = arr2[0];
|
|
|
+ mon = arr2[1];
|
|
|
+ day = arr2[2];
|
|
|
+ hour = arr2[3];
|
|
|
+ min = arr2[4];
|
|
|
+ sec = arr2[5];
|
|
|
+ console.log("heart_beat:20"+year+"-"+mon+"-"+day+" "+hour+":"+min+":"+sec);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 解包
|
|
|
+let RecvBuf = "";
|
|
|
+function unpack_recv(data) {
|
|
|
+ console.log("recv " + data.length +":"+ data);
|
|
|
+ // data添加到全局RecvBuf
|
|
|
+ if(RecvBuf == ""){
|
|
|
+ RecvBuf = data;
|
|
|
+ }else{
|
|
|
+ RecvBuf += data;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(RecvBuf.length < 7){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log(Buffer.from(RecvBuf.slice(0, 7)).toString('hex'));
|
|
|
+
|
|
|
+ //找包头
|
|
|
+ let index = -1;
|
|
|
+ for (i = 0; i < RecvBuf.length-3; i++) {
|
|
|
+ if(RecvBuf.slice(i, i+3) == "YL>"){
|
|
|
+ index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(index == -1){
|
|
|
+ console.log("未找到到包头");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log("已查到包头, index:"+ index );
|
|
|
+
|
|
|
+ // 如果不满足,断包了
|
|
|
+ if(index+7 > RecvBuf.length){
|
|
|
+ console.log("检查长度1失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log("检查长度1正常" );
|
|
|
+
|
|
|
+ // console.log(RecvBuf.slice(index+3, index+5));
|
|
|
+ let data_len = BytesToIntBigEndian(RecvBuf.slice(index+3, index+5));
|
|
|
+ // console.log("data_len:"+ data_len );
|
|
|
+ // 检查实际长度
|
|
|
+ if(index+7+data_len > RecvBuf.length || data_len == 0){
|
|
|
+ console.log("检查长度2失败, data_len:" + data_len + "recv_len:" + RecvBuf.length );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log("检查长度2正常" );
|
|
|
+
|
|
|
+ // 检查校验码
|
|
|
+ // console.log("5:" + RecvBuf[index+5] +", 6:"+ RecvBuf[index+6] );
|
|
|
+ let recv_check = BytesToIntBigEndian(RecvBuf.slice(index+5, index+7));
|
|
|
+ let cal_check = calculateChecksum16bit(RecvBuf.slice(index+7,index+7+data_len));
|
|
|
+ if(recv_check != cal_check){
|
|
|
+ console.log("校验码失败, recv_check:" + recv_check +", cal_check:"+ cal_check );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log("校验码成功" );
|
|
|
+
|
|
|
+ //解析数据
|
|
|
+ let start = index+7;
|
|
|
+ let stop = index+7+data_len;
|
|
|
+ console.log("start:" + start +", stop:"+ stop );
|
|
|
+ let out = RecvBuf.slice(index+7,index+7+data_len);
|
|
|
+
|
|
|
+ // 处理out数据
|
|
|
+ handler_recv(out);
|
|
|
+
|
|
|
+ // 留下剩余数据:正常情况下长度=0:无剩余数据
|
|
|
+ let old_len = data.length;
|
|
|
+ RecvBuf = RecvBuf.slice(index+7+data_len);
|
|
|
+ console.log("剩余数据:" + RecvBuf);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// 设置一个每5000毫秒执行一次的定时器
|
|
|
+setInterval(function() {
|
|
|
+ array = stringsArray[strings_i];
|
|
|
+ pack_send(array);
|
|
|
+
|
|
|
+
|
|
|
+ strings_i++;
|
|
|
+ if(strings_i >= stringsArray.length){
|
|
|
+ strings_i = 0;
|
|
|
+ }
|
|
|
+}, 5000);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ws.onopen = function(evt) {
|
|
|
+ console.log("Connection open ...");
|
|
|
+};
|
|
|
+
|
|
|
+ws.onmessage = function(evt) {
|
|
|
+ unpack_recv(evt.data); //string
|
|
|
+};
|
|
|
+
|
|
|
+ws.onclose = function(evt) {
|
|
|
+ console.log("Connection closed.");
|
|
|
+};
|
|
|
+
|
|
|
+
|