smithtek-mako-rf 3.0.1 → 3.0.3

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/smithtek-mako-rf.js +27 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smithtek-mako-rf",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Smithtek dedicated node for communicating with the Mako PLC over RS485 or RF",
5
5
  "keywords": [
6
6
  "node-red",
@@ -411,25 +411,37 @@ state._rssiCleanup = cleanup;
411
411
  return [5, 6, 15, 16].includes(fc) ? fc : 5;
412
412
  }
413
413
 
414
+ async function closeClientSafe(state) {
415
+ // Best-effort: close and wait a moment for the fd to actually drop
416
+ try {
417
+ await new Promise((resolve) => {
418
+ try {
419
+ state.client.close(() => resolve());
420
+ } catch (_e) {
421
+ resolve();
422
+ }
423
+ });
424
+ } catch (_e) {}
425
+
426
+ // tiny settle time helps on Pi serial
427
+ await sleep(50);
428
+ }
429
+
414
430
  async function connectIfNeeded(cfg, state) {
415
431
  if (!cfg) throw new Error("Bus config missing");
416
432
 
417
- // NOTE: we will hard-lock /dev/ttyAMA2 later (PassPort mode)
418
- // if (process.env.SMITHTEK_PASSPORT === "1") cfg.serialPort = "/dev/ttyAMA2";
419
-
420
433
  const portKey = makePortKey(cfg);
421
434
 
422
- // If port settings changed, force reconnect
435
+ // If settings changed, force reconnect
423
436
  if (state.connected && state.lastPortKey !== portKey) {
424
437
  state.connected = false;
425
- try {
426
- state.client.close(() => {});
427
- } catch (_e) {}
438
+ await closeClientSafe(state);
428
439
  }
429
440
 
441
+ // Already connected
430
442
  if (state.connected) return;
431
443
 
432
- // If another request is already connecting, wait for it
444
+ // If already connecting, wait for that attempt to finish
433
445
  if (state.connecting) {
434
446
  for (let i = 0; i < 200; i++) {
435
447
  if (state.connected) return;
@@ -451,10 +463,10 @@ state._rssiCleanup = cleanup;
451
463
  parity: cfg.parity || "none",
452
464
  };
453
465
 
454
- try {
455
- state.client.close(() => {});
456
- } catch (_e) {}
466
+ // Always close cleanly before opening (and WAIT for it)
467
+ await closeClientSafe(state);
457
468
 
469
+ // Open
458
470
  await state.client.connectRTUBuffered(port, options);
459
471
 
460
472
  // UI uses seconds; library uses ms
@@ -564,12 +576,7 @@ state._rssiCleanup = cleanup;
564
576
  } catch (err) {
565
577
  lastErr = err;
566
578
 
567
- // Force reconnect next attempt
568
- state.connected = false;
569
- try {
570
- await new Promise((resolve) => state.client.close(() => resolve()));
571
- } catch (_e) {}
572
-
579
+ node.warn(`${busName}: RF error fc${req.fc} uid${req.unitid} try ${attempt}/${totalTries}: ${err.message || err}`);
573
580
 
574
581
  if (attempt < totalTries && gap_s > 0) {
575
582
  await sleep(Math.floor(gap_s * 1000));
@@ -799,18 +806,15 @@ try {
799
806
  if (busCfg) {
800
807
  const s = BUS.get(busCfg.id);
801
808
  if (s) {
802
- // NEW: stop any in-flight queue processor from the old deploy
803
809
  s.queue = [];
804
810
  s.busy = false;
805
811
 
806
812
  if (typeof s._rssiCleanup === "function") {
807
813
  try { s._rssiCleanup(); } catch (_e) {}
808
814
  }
809
- if (s.client) {
810
- try { s.client.close(() => {}); } catch (_e) {}
811
- s.connected = false;
812
- s.client = new (require("modbus-serial"))();
813
- }
815
+
816
+ s.connected = false;
817
+ try { s.client.close(() => {}); } catch (_e) {}
814
818
  }
815
819
  }
816
820
  } catch (_e) {}