node-red-contrib-modbus-modpackqt 3.3.7 → 3.3.9
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 +21 -0
- package/nodes/lib/probe-runtime.js +1 -1
- package/nodes/modpackqt-config.html +8 -5
- package/nodes/modpackqt-master-probe.html +2 -2
- package/nodes/modpackqt-master-read.html +2 -2
- package/nodes/modpackqt-master-write.html +13 -3
- package/nodes/modpackqt-master-write.js +11 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ 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.9] — 2026-05-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Master Write** now has a **Quantity** field — fixes how many registers
|
|
12
|
+
the write covers. Payload arrays longer than this are truncated; shorter
|
|
13
|
+
ones are padded with the last value (or 0 if empty). For FC5 / FC6
|
|
14
|
+
(single-register writes) Quantity is forced to 1.
|
|
15
|
+
|
|
16
|
+
## [3.3.8] — 2026-05-10
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **Plain-language labels in master nodes.** The dropdown that selects a
|
|
21
|
+
config is now labelled **Target Device** (was "Runtime") in master-read,
|
|
22
|
+
master-write, and master-probe, with clearer helper text.
|
|
23
|
+
- **Config dialog: "Device" section renamed to "Target Device".**
|
|
24
|
+
- **Config dialog: Host field renamed to "IP Address"** with an example
|
|
25
|
+
placeholder (`e.g. 192.168.1.10`) and an inline hint explaining what to
|
|
26
|
+
enter. Port and Unit ID placeholders also clarified.
|
|
27
|
+
|
|
7
28
|
## [3.3.7] — 2026-05-10
|
|
8
29
|
|
|
9
30
|
### Added
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const http = require('http');
|
|
19
19
|
const { URL } = require('url');
|
|
20
20
|
|
|
21
|
-
const PALETTE_VERSION = '3.3.
|
|
21
|
+
const PALETTE_VERSION = '3.3.9';
|
|
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;
|
|
@@ -127,18 +127,21 @@
|
|
|
127
127
|
Picks a saved connection from modpackqt.com — auto-fills Host, Port, and Unit ID below.
|
|
128
128
|
</div>
|
|
129
129
|
|
|
130
|
-
<h4 style="margin-top:18px">Device</h4>
|
|
130
|
+
<h4 style="margin-top:18px">Target Device</h4>
|
|
131
131
|
<div class="form-row modpackqt-tcp-only">
|
|
132
|
-
<label for="node-config-input-targetHost"><i class="fa fa-plug"></i>
|
|
133
|
-
<input type="text" id="node-config-input-targetHost" placeholder="
|
|
132
|
+
<label for="node-config-input-targetHost"><i class="fa fa-plug"></i> IP Address</label>
|
|
133
|
+
<input type="text" id="node-config-input-targetHost" placeholder="e.g. 192.168.1.10 — IP/hostname of the Modbus device">
|
|
134
|
+
</div>
|
|
135
|
+
<div class="form-tips modpackqt-tcp-only" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
136
|
+
The IP address (or hostname) of the target Modbus device on your network.
|
|
134
137
|
</div>
|
|
135
138
|
<div class="form-row modpackqt-tcp-only">
|
|
136
139
|
<label for="node-config-input-targetPort"><i class="fa fa-hashtag"></i> Port</label>
|
|
137
|
-
<input type="number" id="node-config-input-targetPort" min="1" max="65535" placeholder="502">
|
|
140
|
+
<input type="number" id="node-config-input-targetPort" min="1" max="65535" placeholder="502 (Modbus TCP default)">
|
|
138
141
|
</div>
|
|
139
142
|
<div class="form-row">
|
|
140
143
|
<label for="node-config-input-unitId"><i class="fa fa-id-card"></i> Unit ID</label>
|
|
141
|
-
<input type="number" id="node-config-input-unitId" min="1" max="247" placeholder="1">
|
|
144
|
+
<input type="number" id="node-config-input-unitId" min="1" max="247" placeholder="1 (slave address on the bus)">
|
|
142
145
|
</div>
|
|
143
146
|
|
|
144
147
|
<h4 style="margin-top:18px">Transport</h4>
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
<input type="text" id="node-input-name" placeholder="(optional, e.g. Inverter A)">
|
|
57
57
|
</div>
|
|
58
58
|
<div class="form-row">
|
|
59
|
-
<label for="node-input-server"><i class="fa fa-
|
|
59
|
+
<label for="node-input-server"><i class="fa fa-plug"></i> Target Device</label>
|
|
60
60
|
<input type="text" id="node-input-server">
|
|
61
61
|
</div>
|
|
62
62
|
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
63
|
-
|
|
63
|
+
Pick the Modbus device this probe should attach to — the web tester deep-links to it.
|
|
64
64
|
</div>
|
|
65
65
|
|
|
66
66
|
<div class="form-row">
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
32
32
|
</div>
|
|
33
33
|
<div class="form-row">
|
|
34
|
-
<label for="node-input-server"><i class="fa fa-
|
|
34
|
+
<label for="node-input-server"><i class="fa fa-plug"></i> Target Device</label>
|
|
35
35
|
<input type="text" id="node-input-server">
|
|
36
36
|
</div>
|
|
37
37
|
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
38
|
-
|
|
38
|
+
Pick the Modbus device this node should read from. Each target device carries its own Host / Port / Unit ID — to talk to a different device, click the pencil → + to add one.
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
41
|
<div class="form-row">
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
targetPort: { value: 0, validate: function (v) { return v === '' || v === 0 || RED.validators.number()(v); } },
|
|
10
10
|
unitId: { value: 0, validate: function (v) { return v === '' || v === 0 || RED.validators.number()(v); } },
|
|
11
11
|
functionCode: { value: '6', required: true },
|
|
12
|
-
address: { value: 0, required: true, validate: RED.validators.number() }
|
|
12
|
+
address: { value: 0, required: true, validate: RED.validators.number() },
|
|
13
|
+
quantity: { value: 1, required: true, validate: RED.validators.number() }
|
|
13
14
|
},
|
|
14
15
|
inputs: 1,
|
|
15
16
|
outputs: 1,
|
|
@@ -27,11 +28,11 @@
|
|
|
27
28
|
<input type="text" id="node-input-name" placeholder="Name">
|
|
28
29
|
</div>
|
|
29
30
|
<div class="form-row">
|
|
30
|
-
<label for="node-input-server"><i class="fa fa-
|
|
31
|
+
<label for="node-input-server"><i class="fa fa-plug"></i> Target Device</label>
|
|
31
32
|
<input type="text" id="node-input-server">
|
|
32
33
|
</div>
|
|
33
34
|
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
34
|
-
|
|
35
|
+
Pick the Modbus device this node should write to. Each target device carries its own Host / Port / Unit ID — to talk to a different device, click the pencil → + to add one.
|
|
35
36
|
</div>
|
|
36
37
|
|
|
37
38
|
<div class="form-row">
|
|
@@ -47,6 +48,15 @@
|
|
|
47
48
|
<label for="node-input-address"><i class="fa fa-map-marker"></i> Start Address</label>
|
|
48
49
|
<input type="number" id="node-input-address" min="0" max="65535" placeholder="0">
|
|
49
50
|
</div>
|
|
51
|
+
<div class="form-row">
|
|
52
|
+
<label for="node-input-quantity"><i class="fa fa-sort-numeric-asc"></i> Quantity</label>
|
|
53
|
+
<input type="number" id="node-input-quantity" min="1" max="125" placeholder="1">
|
|
54
|
+
</div>
|
|
55
|
+
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
56
|
+
Number of registers to write. Payload arrays longer than this are truncated;
|
|
57
|
+
shorter ones are padded with the last value (or 0 if empty). For FC5 / FC6
|
|
58
|
+
(single-register writes) Quantity is forced to 1.
|
|
59
|
+
</div>
|
|
50
60
|
|
|
51
61
|
<input type="hidden" id="node-input-targetHost">
|
|
52
62
|
<input type="hidden" id="node-input-targetPort">
|
|
@@ -14,6 +14,7 @@ module.exports = function (RED) {
|
|
|
14
14
|
node.unitId = parseInt(config.unitId, 10) || 0;
|
|
15
15
|
node.functionCode = parseInt(config.functionCode, 10) || 6;
|
|
16
16
|
node.address = parseInt(config.address, 10) || 0;
|
|
17
|
+
node.quantity = parseInt(config.quantity, 10) || 1;
|
|
17
18
|
|
|
18
19
|
node.on('input', async function (msg) {
|
|
19
20
|
if (!server) {
|
|
@@ -26,7 +27,16 @@ module.exports = function (RED) {
|
|
|
26
27
|
try { raw = JSON.parse(raw); } catch (_) { raw = Number(raw); }
|
|
27
28
|
}
|
|
28
29
|
const isCoilWrite = (node.functionCode === 5 || node.functionCode === 15);
|
|
29
|
-
const
|
|
30
|
+
const isSingle = (node.functionCode === 5 || node.functionCode === 6);
|
|
31
|
+
const targetQty = isSingle ? 1 : Math.max(1, node.quantity);
|
|
32
|
+
let arr = Array.isArray(raw) ? raw.slice() : [raw];
|
|
33
|
+
// Pad / truncate to targetQty
|
|
34
|
+
if (arr.length > targetQty) {
|
|
35
|
+
arr = arr.slice(0, targetQty);
|
|
36
|
+
} else if (arr.length < targetQty) {
|
|
37
|
+
const filler = arr.length ? arr[arr.length - 1] : (isCoilWrite ? 0 : 0);
|
|
38
|
+
while (arr.length < targetQty) arr.push(filler);
|
|
39
|
+
}
|
|
30
40
|
const values = arr.map((v) => {
|
|
31
41
|
if (isCoilWrite) return v ? 1 : 0;
|
|
32
42
|
const n = Number(v);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-modbus-modpackqt",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.9",
|
|
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",
|