node-red-contrib-modbus-modpackqt 3.3.15 → 3.3.16

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to **node-red-contrib-modbus-modpackqt** are documented
4
4
  here. This project follows [Semantic Versioning](https://semver.org/) — pin a
5
5
  major version (`^2.0.0`) in production.
6
6
 
7
+ ## [3.3.16] — 2026-05-10
8
+
9
+ ### Added
10
+
11
+ - **Slave server now has a single output port** that emits one message
12
+ per external Modbus client read/write — `{ direction, type, address,
13
+ values, port, unitId, ts }`. Wire to a Debug node to watch live
14
+ traffic from PLCs / SCADA / HMIs hitting the slave. The output port
15
+ also makes the node render visibly chunkier on the canvas (matching
16
+ the size of other contrib server nodes).
17
+ - **"Edit on modpackqt.com" CTAs** in both master-probe and
18
+ slave-server dialogs — quick link to the saved-profile editor on
19
+ the web for changing IP / port / unit ID / register layout without
20
+ leaving Node-RED.
21
+
7
22
  ## [3.3.15] — 2026-05-10
8
23
 
9
24
  ### Changed
@@ -18,7 +18,7 @@
18
18
  const http = require('http');
19
19
  const { URL } = require('url');
20
20
 
21
- const PALETTE_VERSION = '3.3.15';
21
+ const PALETTE_VERSION = '3.3.16';
22
22
  const DEFAULT_PORT = parseInt(process.env.MODPACKQT_PROBE_PORT, 10) || 8502;
23
23
  const BIND_HOST = process.env.MODPACKQT_PROBE_HOST || '127.0.0.1';
24
24
  const PORT_RETRY = 5;
@@ -91,6 +91,12 @@
91
91
  <div style="margin-top:6px;font-size:11px;color:#6b7280;">
92
92
  Target: <span id="modpackqt-probe-target">—</span> · runtime <span id="modpackqt-probe-runtime">starting…</span>
93
93
  </div>
94
+ <div style="margin-top:10px;font-size:12px;">
95
+ <a href="https://modpackqt.com/settings#connections" target="_blank" rel="noopener noreferrer"
96
+ style="color:#7c3aed;text-decoration:none;font-weight:500;">
97
+ <i class="fa fa-pencil" style="margin-right:4px;"></i>Edit IP / port / unit ID on modpackqt.com →
98
+ </a>
99
+ </div>
94
100
  </div>
95
101
  </script>
96
102
 
@@ -12,7 +12,8 @@
12
12
  apiKey: { type: 'password' }
13
13
  },
14
14
  inputs: 0,
15
- outputs: 0,
15
+ outputs: 1,
16
+ outputLabels: ['external client read/write events'],
16
17
  align: 'right',
17
18
  icon: 'font-awesome/fa-server',
18
19
  label: function () {
@@ -126,6 +127,12 @@
126
127
  <div style="margin-top:6px;font-size:11px;color:#6b7280;">
127
128
  Target: <span id="modpackqt-slave-server-target">—</span> · runtime <span id="modpackqt-slave-server-runtime">starting…</span>
128
129
  </div>
130
+ <div style="margin-top:10px;font-size:12px;">
131
+ <a href="https://modpackqt.com/settings#slaves" target="_blank" rel="noopener noreferrer"
132
+ style="color:#7c3aed;text-decoration:none;font-weight:500;">
133
+ <i class="fa fa-pencil" style="margin-right:4px;"></i>Edit port / unit ID / register layout on modpackqt.com →
134
+ </a>
135
+ </div>
129
136
  </div>
130
137
  </script>
131
138
 
@@ -53,13 +53,25 @@ module.exports = function (RED) {
53
53
  // ── Modbus TCP server
54
54
  let server = null;
55
55
  try {
56
+ const emit = (direction, type, address, values) => {
57
+ try {
58
+ node.send({
59
+ payload: {
60
+ ts: new Date().toISOString(),
61
+ direction, type, address,
62
+ values: Array.isArray(values) ? values : [values],
63
+ port: node.bindPort, unitId: node.unitId
64
+ }
65
+ });
66
+ } catch (_) { /* never let listener errors break the slave */ }
67
+ };
56
68
  const vector = {
57
- getCoil: (addr, _u, cb) => cb(null, store.coils[addr]),
58
- getDiscreteInput: (addr, _u, cb) => cb(null, store.discrete[addr]),
59
- getHoldingRegister: (addr, _u, cb) => cb(null, store.holding[addr]),
60
- getInputRegister: (addr, _u, cb) => cb(null, store.input[addr]),
61
- setCoil: (addr, val, _u, cb) => { store.coils[addr] = !!val; cb(null); },
62
- setRegister: (addr, val, _u, cb) => { store.holding[addr] = val & 0xFFFF; cb(null); }
69
+ getCoil: (addr, _u, cb) => { const v = store.coils[addr]; emit('read', 'coils', addr, v); cb(null, v); },
70
+ getDiscreteInput: (addr, _u, cb) => { const v = store.discrete[addr]; emit('read', 'discrete', addr, v); cb(null, v); },
71
+ getHoldingRegister: (addr, _u, cb) => { const v = store.holding[addr]; emit('read', 'holding', addr, v); cb(null, v); },
72
+ getInputRegister: (addr, _u, cb) => { const v = store.input[addr]; emit('read', 'input', addr, v); cb(null, v); },
73
+ setCoil: (addr, val, _u, cb) => { store.coils[addr] = !!val; emit('write', 'coils', addr, !!val); cb(null); },
74
+ setRegister: (addr, val, _u, cb) => { const v = val & 0xFFFF; store.holding[addr] = v; emit('write', 'holding', addr, v); cb(null); }
63
75
  };
64
76
  server = new ModbusRTU.ServerTCP(vector, {
65
77
  host: node.bindHost,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-modbus-modpackqt",
3
- "version": "3.3.15",
3
+ "version": "3.3.16",
4
4
  "description": "Modbus commissioning, testing & analysis tools for Node-RED. Embedded Modbus TCP/RTU master + slave server, FC1/FC2/FC3/FC4 reads, FC5/FC6/FC15/FC16 writes, built-in slave register store, and a passive traffic monitor for debugging. 100% free, MIT, no usage limits. By ModPackQT — open the matching web console at modpackqt.com for register decoding, simulation and AI assistance.",
5
5
  "keywords": [
6
6
  "node-red",