node-zserial 1.0.23 → 1.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/zserial.js +119 -44
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-zserial",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Node-RED nodes to talk to serial ports",
5
5
  "dependencies": {
6
6
  "serialport": "^12.0.0"
package/zserial.js CHANGED
@@ -24,7 +24,7 @@ module.exports = function (RED) {
24
24
  node.send(msg);
25
25
  done();
26
26
  }, node);
27
- }
27
+ }
28
28
  else if (msg.serialConfigs) {
29
29
  let allLen = msg.serialConfigs.length;
30
30
  let total = msg.serialConfigs.length;
@@ -329,7 +329,7 @@ module.exports = function (RED) {
329
329
  node.successMsg = {};
330
330
  node.errorMsg = {};
331
331
  node._msg = null
332
-
332
+
333
333
  function initMsg(msg) {
334
334
  node._msg = msg;
335
335
  node.totallenth = msg.serialConfigs.length;
@@ -338,7 +338,7 @@ module.exports = function (RED) {
338
338
  node.errorMsg = {};
339
339
  }
340
340
  function zsend(msg, err, alldone, port, done) {
341
-
341
+
342
342
  let payload = msg || err;
343
343
  node._msg.payload = payload;
344
344
  node.totalMsg[port] = payload
@@ -358,7 +358,6 @@ module.exports = function (RED) {
358
358
  sendAll(done);
359
359
  }
360
360
  function onMsg(msg, send, done) {
361
-
362
361
  initMsg(msg);
363
362
  if (!msg.serialConfigs) {
364
363
  node.error("需要配置批量配置:msg.serialConfigs");
@@ -370,14 +369,14 @@ module.exports = function (RED) {
370
369
  for (var i = 0; i < msg.serialConfigs.length; i++) {
371
370
  var serialConfig = msg.serialConfigs[i];
372
371
  serialConfig._msgid = msg._msgid + "_" + i;
373
- getSerialServer(msg, serialConfig, done);
372
+ getSerialServer( msg, serialConfig, done);
374
373
  }
375
374
  }
376
375
 
377
376
  function sendAll(done) {
377
+
378
378
  try {
379
379
  let len = Object.keys(node.totalMsg).length;
380
-
381
380
  if (len == node.totallenth) {
382
381
  let payload = {
383
382
  totalMsg: node.totalMsg,
@@ -501,53 +500,82 @@ module.exports = function (RED) {
501
500
 
502
501
  }
503
502
 
503
+ function isCurNode(msgout, curMsg, _ndoe, sender) {
504
+ // if (sender == node) { return true; }
505
+ if (msgout.request_msgid && msgout.request_msgid.startsWith(curMsg._msgid)) {
506
+ return true
507
+ }
508
+ return false
509
+ }
510
+
504
511
  function setCallback(msg, serialConfig, done) {
505
512
  let curPort = serialPool.get(serialConfig);
506
- // 确保只绑定一次事件
507
- if (curPort._isBindEventInit) {
508
- return;
509
- }
513
+ // 确保当前节点只绑定一次事件
514
+ // if (curPort._isBindEventInit) {
515
+ // return;
516
+ // }
510
517
  // node.warn("setCallback called for " + curPort.serial.path);
511
- curPort._isBindEventInit = true;
518
+ // curPort._isBindEventInit = true;
512
519
 
513
- curPort.on('data', function (msgout, sender) {
520
+ if (node[`_dataHandler_${curPort.serial.path}`]) {
521
+ return;
522
+ }
523
+ const dataHandler = function (msgout, sender) {
514
524
  if (sender !== node) { return; }
515
- msgout.status = "OK";
516
- zsend(msgout, null, null, curPort.serial.path, done);
517
- });
518
- curPort.on('timeout', function (msgout, sender) {
525
+ try {
526
+ msgout.status = "OK";
527
+ zsend(msgout, null, null, curPort.serial.path, done);
528
+ } catch (error) {
529
+ node.error(error)
530
+ }
531
+
532
+ }
533
+
534
+ const timeoutHandler = function (msgout, sender) {
519
535
  if (sender !== node) { return; }
520
536
  msgout.status = "ERR_TIMEOUT";
521
537
  msgout.port = curPort.serial.path;
522
538
  node.status({ fill: "red", shape: "ring", text: "timeout:::" + curPort.serial.path });
523
539
  zsend(null, msgout, null, curPort.serial.path, done);
524
- });
525
-
526
- curPort.on('initerror', function (port, retryNum, olderr) {
527
- // zsend(null, {
528
- // status: "ERR_INIT",
529
- // text: `请检查端口是否打开,重试次数${retryNum}`,
530
- // error: olderr,
531
- // port: port
532
- // }, null, curPort.serial.path, done);
533
- });
534
-
535
-
536
- curPort.on('retryerror', function (port, retryNum) {
537
- // curPort._retryNum = 0;
538
- // zsend(null, {
539
- // status: "ERR_retry",
540
- // text: `重试${retryNum}失败`,
541
- // port: port
542
- // }, null, curPort.serial.path, done);
543
- });
540
+ }
544
541
 
545
- curPort.on('closed', function (port) {
546
- // node.warn(`串口已关闭:${port}`);
547
- });
548
- curPort.on('ready', function (port) {
549
- // node.warn(`串口已准备好:${port}`);
550
- });
542
+ node[`_dataHandler_${curPort.serial.path}`] = dataHandler
543
+ node[`_timeoutHandler_${curPort.serial.path}`] = timeoutHandler
544
+ curPort.on('data', dataHandler);
545
+ curPort.on('timeout', timeoutHandler);
546
+
547
+ node.on('close', function () {
548
+ node[`_dataHandler_${curPort.serial.path}`] = null
549
+ node[`_timeoutHandler_${curPort.serial.path}`] = null
550
+ curPort.off('data', dataHandler);
551
+ curPort.off('timeout', timeoutHandler);
552
+ })
553
+
554
+ // curPort.on('initerror', function (port, retryNum, olderr) {
555
+ // // zsend(null, {
556
+ // // status: "ERR_INIT",
557
+ // // text: `请检查端口是否打开,重试次数${retryNum}`,
558
+ // // error: olderr,
559
+ // // port: port
560
+ // // }, null, curPort.serial.path, done);
561
+ // });
562
+
563
+
564
+ // curPort.on('retryerror', function (port, retryNum) {
565
+ // // curPort._retryNum = 0;
566
+ // // zsend(null, {
567
+ // // status: "ERR_retry",
568
+ // // text: `重试${retryNum}失败`,
569
+ // // port: port
570
+ // // }, null, curPort.serial.path, done);
571
+ // });
572
+
573
+ // curPort.on('closed', function (port) {
574
+ // // node.warn(`串口已关闭:${port}`);
575
+ // });
576
+ // curPort.on('ready', function (port) {
577
+ // // node.warn(`串口已准备好:${port}`);
578
+ // });
551
579
  }
552
580
 
553
581
  this.on("input", function (msg, send, done) {
@@ -876,6 +904,47 @@ module.exports = function (RED) {
876
904
  return Buffer.from(out);
877
905
  }
878
906
 
907
+
908
+ // GNW 蓝牙帧:7E 7E 7E 5A ... CS 7E A5
909
+ function tryParseBleGNW(input) {
910
+ const b = input;
911
+ if (b.length < 9) return { ok: false }; // 最短:4起始 + 1LEN + 1CMD + 0DATA + 1CS + 2结束
912
+ // 形态判定:必须以 7E 7E 7E 5A 开头
913
+ if (!(b[0] === 0x7E && b[1] === 0x7E && b[2] === 0x7E && b[3] === 0x5A)) {
914
+ // 若不是,看看后面是否有候选起点(容错脏字节)
915
+ const n = b.indexOf(0x7E);
916
+ if (n > 0) return { ok: false, used: n, frame: b.slice(0, n), err: "BLE_NO_7E7E7E5A_AT_START" };
917
+ return { ok: false };
918
+ }
919
+
920
+ // 向后找结束 A5,要求倒数第二个字节是 0x7E(结束符 7E A5)
921
+ let endPos = -1;
922
+ for (let i = 5; i < b.length; i++) {
923
+ if (b[i] === 0xA5 && b[i - 1] === 0x7E) { endPos = i; break; }
924
+ }
925
+ if (endPos === -1) return { ok: false }; // 半包,继续累计
926
+
927
+ const frame = b.slice(0, endPos + 1); // [0 .. A5]
928
+ // 基本字段位置:len 在 [4],cmd 在 [5],CS 在倒数第3个字节
929
+ const L = frame[4] >>> 0;
930
+ const cs = frame[frame.length - 3] >>> 0;
931
+
932
+ // (宽松)长度一致性:实测总长 T 与 L 的关系为 T = L + 3
933
+ const T = frame.length;
934
+ if ((T - 3) !== L) {
935
+ // 不强制失败,给出“长度不一致”的错误帧提示并丢掉该段,避免卡死
936
+ return { ok: false, used: frame.length, frame, err: "BLE_LEN_MISMATCH" };
937
+ }
938
+
939
+ // 和校验:从起始 0x7E 到 CS 之前所有字节累加低8位
940
+ let sum = 0;
941
+ for (let i = 0; i < frame.length - 3; i++) sum = (sum + (frame[i] >>> 0)) & 0xFF;
942
+ if (sum !== cs) {
943
+ return { ok: false, used: frame.length, frame, err: "BLE_CS_FAIL" };
944
+ }
945
+
946
+ return { ok: true, used: frame.length, frame };
947
+ }
879
948
  // 645:FE* 68 + 6 addr + 68 + ctrl + len + data + cs + 16
880
949
  function tryParse645(input) {
881
950
  // 统计 FE 前导(仅用于 used,不参与 CS 计算)
@@ -1026,8 +1095,14 @@ module.exports = function (RED) {
1026
1095
 
1027
1096
  // 抽帧
1028
1097
  while (assembleBuf.length >= 5) {
1029
- // 优先 HDLC,再 645,再 698-Len(避免误判)
1030
- let r = tryParse698HDLC(assembleBuf);
1098
+ // // 优先 HDLC,再 645,再 698-Len(避免误判)
1099
+ // let r = tryParse698HDLC(assembleBuf);
1100
+ // if (!r.ok) r = tryParse645(assembleBuf);
1101
+ // if (!r.ok) r = tryParse698Len(assembleBuf);
1102
+
1103
+ // --fix-20251108-先 BLE(7E7E7E5A…7EA5),再 698-HDLC,再 645,再 698-LEN
1104
+ let r = tryParseBleGNW(assembleBuf);
1105
+ if (!r.ok) r = tryParse698HDLC(assembleBuf);
1031
1106
  if (!r.ok) r = tryParse645(assembleBuf);
1032
1107
  if (!r.ok) r = tryParse698Len(assembleBuf);
1033
1108