| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- // 使用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:heart_beat=?;time=?;version=?;work_status=?;fire_status=?;fault_status=?",
- "get:humidity=?;temperature=?;cur_photosen0=?;photosen0=?",
- "get:net=?;event_num=?;warning_num=?",
- // 设置(可批量)
- // "set:extra_time=180;standing_time=10;interval_time=600",
- // "set:photosen0=6000,6000,6000,6000",
- // "set:net=WIFI24,12345678,qq.com,1883,user,123456;event_num=1000;warning_num=1000",
- // 操作(单独)
- // "set:time=1727107200",
- // "set:reset=1",
- // "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 bufferToHex (buffer) {
- return [...new Uint8Array (buffer)]
- .map (b => b.toString (16).padStart (2, "0"))
- .join (" ");
- }
- 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 intToHex(number, minLength) {
- return number.toString(16).padStart(minLength, '0');
- }
- function hexToString(hex) {
- var string = '';
- for (var i = 0; i < hex.length; i += 2) {
- string += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
- }
- return string;
- }
- // 封包
- function pack_send(str) {
- console.log("封包前:"+str);
-
- body = str;
- let data_len = body.length & 0xffff;
- let data_check = calculateChecksum16bit(stringToByteArray(body)) & 0xffff;
- // console.log("len:"+intToHex(data_len,4));
- // console.log("check:"+intToHex(data_check,4));
- const headBuf = Buffer.from([0x59, 0x4c, 0x3c, (data_len>>8)&0xff, (data_len)&0xff, (data_check>>8)&0xff, (data_check)&0xff]);
- const bodyBuf = Buffer.from(body);
- let pack_date = Buffer.concat([headBuf, bodyBuf]);
- ws.send(pack_date);
- // console.log("headBuf:"+bufferToHex(headBuf));
- // console.log("bodyBuf:"+bufferToHex(bodyBuf));
- console.log("封包后:"+bufferToHex(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) {
- datArray = stringToByteArray(data);
- console.log("接收 " + data.length +": "+ bufferToHex(datArray));
- // 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];
- if(array.length >= 500){
- console.log("长度太大,请减少数据长度");
- return;
- }
- 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.");
- };
|