node-red-contrib-modbus-modpackqt 1.1.84 → 2.0.0

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/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # node-red-contrib-modbus-modpackqt
2
2
 
3
- **Node-RED Modbus nodes powered by [ModPackQT](https://modpackqt.com)** — drag-and-drop nodes to read and write Modbus TCP registers (master & slave) from your Node-RED flows. No hand-written HTTP calls. No protocol handling. Just connect and go.
3
+ **Embedded Modbus TCP / RTU master + slave server for Node-RED no extra apps required.**
4
+ By [ModPackQT](https://modpackqt.com).
4
5
 
5
6
  [![npm version](https://img.shields.io/npm/v/node-red-contrib-modbus-modpackqt.svg)](https://www.npmjs.com/package/node-red-contrib-modbus-modpackqt)
6
7
  [![Node-RED](https://img.shields.io/badge/Node--RED-%E2%89%A52.0.0-red)](https://nodered.org)
@@ -8,224 +9,195 @@
8
9
 
9
10
  ---
10
11
 
11
- ## What is ModPackQT?
12
+ ## What you get
12
13
 
13
- [ModPackQT](https://modpackqt.com) is an industrial Modbus Master/Slave platform for engineers and technicians. It provides:
14
+ - **Modbus master** read (FC1–FC4) and write (FC5/FC6/FC15/FC16) over **TCP** or **RTU (serial)**
15
+ - **Embedded Modbus TCP slave server** — push values from any flow, let PLCs / SCADA / HMIs read them
16
+ - **Free passive traffic monitor** — see every Modbus op (timing, values, errors) in real time
17
+ - **Outputs raw register values** — pair with [`node-red-contrib-bytes-modpackqt`](https://www.npmjs.com/package/node-red-contrib-bytes-modpackqt) to decode int / float / string / bitmask
18
+ - **Zero external dependencies** — Modbus runs inside the Node-RED process
14
19
 
15
- - **Modbus TCP and RTU** communication via a local gateway app
16
- - **Built-in slave simulator** — simulate a PLC register map without hardware
17
- - **Real-time data visualization**, profile management, and AI-assisted setup
18
- - A **REST API** that this Node-RED palette talks to
19
-
20
- 👉 [Download ModPackQT](https://modpackqt.com/download) · [Modbus Tutorial](https://modpackqt.com/resources/tutorial) · [Resources Hub](https://modpackqt.com/resources)
20
+ ---
21
21
 
22
- > **Requires the ModPackQT Gateway app to be running locally.**
23
- > The gateway is what the nodes talk to — not the cloud server directly.
22
+ > ## ⚠️ Read before deploying in production
23
+ >
24
+ > This software writes to industrial control equipment. A wrong write can damage
25
+ > equipment, ruin a batch, or cause a safety incident.
26
+ >
27
+ > - **Test against the embedded slave server first** — never wire a new write
28
+ > directly to a real device.
29
+ > - **Not for safety-instrumented systems** (SIS / SIL-rated loops). This is
30
+ > for monitoring and supervisory control, not safety interlocks.
31
+ > - **You are responsible** for what your flows do. See
32
+ > [`DISCLAIMER.md`](./DISCLAIMER.md) for the full safe-use checklist and
33
+ > [`LICENSE`](./LICENSE) for the legal terms.
24
34
 
25
35
  ---
26
36
 
27
- ## Installation
37
+ ## Install
28
38
 
29
- ### Option 1Node-RED Palette Manager (recommended)
39
+ **Recommended (one shot):** install both palettes Modbus + decoders — together.
30
40
 
31
- 1. Open Node-RED **Menu (☰) → Manage palette → Install**
32
- 2. Search for **`modbus-modpackqt`**
33
- 3. Click **Install**
34
- 4. Restart Node-RED — the **ModPackQT** palette group appears in the sidebar
35
-
36
- ### Option 2 — npm CLI
41
+ Palette manager → Manage palette → Install:
42
+ - `node-red-contrib-modbus-modpackqt`
43
+ - `node-red-contrib-bytes-modpackqt`
37
44
 
45
+ **npm:**
38
46
  ```bash
39
47
  cd ~/.node-red
40
- npm install node-red-contrib-modbus-modpackqt
41
- # Restart Node-RED after installation
48
+ npm install node-red-contrib-modbus-modpackqt node-red-contrib-bytes-modpackqt
49
+ # then restart Node-RED
42
50
  ```
43
51
 
44
52
  ---
45
53
 
46
- ## Prerequisites
47
-
48
- 1. **Sign up at [modpackqt.com](https://modpackqt.com)**
49
- A free account works for all master nodes. Slave nodes require a **paid plan**.
50
-
51
- 2. **Download and start the ModPackQT Gateway app**
52
- Download it from [modpackqt.com/download](https://modpackqt.com/download) and run it.
53
- By default it listens on **port 8502** (`localhost:8502`).
54
+ ## 5-minute walkthrough
54
55
 
55
- 3. **Create an API key**
56
- In the ModPackQT web app go to **Settings → API Keys → New Key**. Paste it into the `modpackqt-config` node.
56
+ ### 1. Read a temperature float from a PLC
57
57
 
58
- 4. **For slave nodes** — create and start at least one slave in the ModPackQT app first (Slave Simulator → New Slave). Note the **Slave ID** shown — you'll need it in Node-RED.
59
-
60
- > **Plan limits**
61
- >
62
- > | Feature | Free | Paid |
63
- > |---|---|---|
64
- > | Master Read (`modpackqt-master-read`) | ✓ | ✓ |
65
- > | Master Write (`modpackqt-master-write`) | ✓ | ✓ |
66
- > | Slave Write (`modpackqt-slave-write`) | ✗ | ✓ |
67
- > | Slave Read (`modpackqt-slave-read`) | ✗ | ✓ |
68
- >
69
- > [View plans & upgrade →](https://modpackqt.com/#pricing)
70
-
71
- ---
58
+ ```
59
+ [inject every 5s] → [modbus master read FC3 addr=100 qty=2] → [decode-float32 BE] → [debug]
60
+ ```
72
61
 
73
- ## Available Nodes
62
+ | Step | Setting |
63
+ |---|---|
64
+ | Add a runtime config | TCP, timeout 3000 ms |
65
+ | Master read | Host `192.168.1.10`, port `502`, unit `1`, FC `3`, address `100`, qty `2` |
66
+ | `decode-float32` | Endian `BE` (try `LE_SWAP` if value looks wrong — Siemens often uses CDAB) |
74
67
 
75
- | Node | Category | Purpose |
76
- |---|---|---|
77
- | `modpackqt-config` | Config | Shared gateway connection (host, port, API key) |
78
- | `modpackqt-master-read` | Modbus Master | Read Modbus TCP registers — FC1/FC2/FC3/FC4 |
79
- | `modpackqt-master-write` | Modbus Master | Write Modbus TCP registers — FC5/FC6/FC15/FC16 |
80
- | `modpackqt-slave-read` | Modbus Slave *(paid)* | Read registers from a ModPackQT slave |
81
- | `modpackqt-slave-write` | Modbus Slave *(paid)* | Push values into a ModPackQT slave (build a live Modbus device from Node-RED) |
68
+ **`msg.payload` along the wire:**
69
+ - After Modbus read: `[16828, 0]` (raw registers)
70
+ - After decode-float32: `23.5` (clean float done)
82
71
 
83
- ---
72
+ ### 2. Send a setpoint back
84
73
 
85
- ## Node-RED Modbus Master — Read Registers (FC1/FC2/FC3/FC4)
74
+ ```
75
+ [inject 23.5] → [encode-float32 BE] → [modbus master write FC16 addr=200]
76
+ ```
86
77
 
87
- The `modpackqt-master-read` node reads registers from **any Modbus TCP slave device** by routing the request through the ModPackQT Gateway app.
78
+ The encoder converts `23.5` `[16828, 0]`, the write node sends it to the PLC.
88
79
 
89
- **Supported function codes:**
90
- - **FC1** — Read Coils
91
- - **FC2** — Read Discrete Inputs
92
- - **FC3** — Read Holding Registers
93
- - **FC4** — Read Input Registers
80
+ ### 3. Watch what's happening (debug visibility)
94
81
 
95
- **Config options:**
82
+ Drop a **modbus traffic** node anywhere on the canvas, point it at the same runtime config, wire to a Debug node. You'll see one message per Modbus op:
96
83
 
97
- | Property | Description |
98
- |---|---|
99
- | Gateway | Config node pointing at your running ModPackQT Gateway app |
100
- | Target Host | IP/hostname of the Modbus TCP slave to read from |
101
- | Target Port | Port of the Modbus TCP slave (default: 502) |
102
- | Unit ID | Modbus unit ID of the slave (1–247) |
103
- | Function Code | FC1 / FC2 / FC3 / FC4 |
104
- | Start Address | First register address (0-based) |
105
- | Quantity | Number of registers/coils to read (1–125) |
106
- | Poll Interval | Auto-poll every N ms (0 = trigger on input msg only) |
107
-
108
- **Output:**
109
84
  ```json
110
85
  {
111
- "payload": { "success": true, "values": [100, 200, 300] },
112
- "topic": "modbus/read/192.168.1.10:502"
86
+ "ts": "2026-05-09T14:23:01.234Z",
87
+ "direction": "read",
88
+ "kind": "master",
89
+ "target": "192.168.1.10:502",
90
+ "unitId": 1,
91
+ "fc": 3,
92
+ "address": 100,
93
+ "quantity": 2,
94
+ "values": [16828, 0],
95
+ "durationMs": 12,
96
+ "ok": true
113
97
  }
114
98
  ```
115
99
 
116
- ---
100
+ Filter by direction, function code, or target if you only want a slice. **Free, doesn't count toward your daily op cap.**
117
101
 
118
- ## Node-RED Modbus Master Write Registers (FC5/FC6/FC15/FC16)
102
+ ### 4. Be a Modbus slave (let SCADA read your values)
119
103
 
120
- The `modpackqt-master-write` node writes registers to **any Modbus TCP slave device**.
104
+ In the runtime config check **Enable embedded Modbus TCP slave server**, set port `1502`. Then:
121
105
 
122
- **Supported function codes:**
123
- - **FC5** Write Single Coil
124
- - **FC6** — Write Single Holding Register
125
- - **FC15** — Write Multiple Coils
126
- - **FC16** — Write Multiple Holding Registers
127
-
128
- **Input:** `msg.payload` — a number (FC5/FC6) or array of numbers (FC15/FC16)
106
+ ```
107
+ [any source] → [encode-int32 BE] [modbus slave write holding addr=0]
108
+ ```
129
109
 
130
- **Output:** Original `msg` with `msg.success = true`
110
+ External masters connecting to `your-host:1502`, unit `1`, FC `3`, address `0`, qty `2` will read the latest value back.
131
111
 
132
112
  ---
133
113
 
134
- ## Building a Modbus Slave from Node-RED *(Paid plan)*
114
+ ## Cookbook (combined with the bytes palette)
135
115
 
136
- Use `modpackqt-slave-write` to make Node-RED the **data source** for a live Modbus slave device. Any external Modbus master (PLC, SCADA, HMI) that connects to the ModPackQT slave port will read whatever values you last pushed from Node-RED.
137
-
138
- **Typical flow:**
116
+ ### Decode a status bitmask
139
117
  ```
140
- [MQTT / Sensor / Timer] → [Function: scale to integer] → [modpackqt-slave-write addr=0] → [External Modbus master reads]
118
+ [master read FC3 addr=50 qty=1] → [decode-bitmask bits=8] → [debug]
119
+ // payload = [true, true, false, true, false, false, false, false]
141
120
  ```
142
121
 
143
- **Use cases:**
144
- - Publish MQTT sensor data as Modbus TCP registers
145
- - Simulate a PLC register map for HMI/SCADA testing
146
- - Bridge OPC-UA, REST, or database data to Modbus
147
-
148
- **Slave write input — all of these work:**
149
- ```js
150
- msg.payload = 234; // single integer
151
- msg.payload = [234, 1013, 65]; // array — writes 3 registers starting at address 0
152
- msg.payload = "[234, 1013, 65]"; // JSON string also works (inject string type)
122
+ ### Read a device serial number string
153
123
  ```
154
-
155
- **Override at runtime:**
156
- ```js
157
- msg.slaveId = "42"; // select a different slave per message
158
- msg.address = 10; // start at register 10 instead of the configured address
159
- msg.registerType = "coil"; // override register type
124
+ [master read FC3 addr=10 qty=8] → [decode-string BE encoding=utf8 trim=true] → [debug]
125
+ // payload = "SN-2025-A0042"
160
126
  ```
161
127
 
162
- **Slave read output:**
163
- ```json
164
- {
165
- "payload": {
166
- "values": [234, 1013, 65],
167
- "registerType": "holding",
168
- "address": 0,
169
- "quantity": 3,
170
- "slaveId": "42"
171
- },
172
- "topic": "slave/42/holding/0"
173
- }
128
+ ### Bridge MQTT → Modbus
129
+ ```
130
+ [mqtt in topic=setpoint] → [encode-float32 BE] → [master write FC16 addr=200]
174
131
  ```
175
132
 
176
- ---
177
-
178
- ## Example Flows
179
-
180
- ### Poll Holding Registers Every 5 Seconds (Modbus Master)
181
-
133
+ ### Bridge Modbus → MQTT
182
134
  ```
183
- [Inject (repeat 5s)] → [modpackqt-master-read FC3 target=192.168.1.10:502 unitId=1 addr=0 qty=10] → [Debug]
135
+ [poll every 5s] → [master read FC3 addr=100 qty=2] → [decode-float32 BE] → [mqtt out topic=temp]
184
136
  ```
185
137
 
186
- ### Write a Setpoint Register from a Button
187
-
138
+ ### Mirror a remote PLC into local slave server
188
139
  ```
189
- [Inject (payload=1234)] → [modpackqt-master-write FC6 target=192.168.1.10:502 unitId=1 addr=100] → [Debug]
140
+ [poll 1s] → [master read FC3 addr=0 qty=10] → [slave write holding addr=0]
141
+ // any local SCADA can now read from your Node-RED slave instead of hammering the PLC
190
142
  ```
191
143
 
192
- ### Build a Slave — Publish Sensor Data as Modbus (Paid plan)
193
-
144
+ ### Alert on Modbus errors
194
145
  ```
195
- [MQTT in] → [Function: msg.payload = parseInt(msg.payload * 10)] → [modpackqt-slave-write Holding addr=0] → [Debug]
146
+ [modbus traffic filter=any] → [switch ok==false] → [email out]
196
147
  ```
197
148
 
198
- Any Modbus master on the network now reads live sensor values from the slave.
149
+ ---
199
150
 
200
- ### Import the Demo Flow
151
+ ## Available nodes
201
152
 
202
- 1. Open Node-RED **Menu → Import**
203
- 2. Choose `examples/basic-flow.json` from the package directory
204
- 3. Update the config node with your gateway host/port
205
- 4. Click **Deploy**
153
+ | Node | Purpose |
154
+ |---|---|
155
+ | `modpackqt-config` | Shared runtime master mode (TCP/RTU), serial settings, optional slave server, API key |
156
+ | `modpackqt-master-read` | Read FC1/FC2/FC3/FC4 from a remote Modbus device |
157
+ | `modpackqt-master-write` | Write FC5/FC6/FC15/FC16 to a remote Modbus device |
158
+ | `modpackqt-slave-read` | Read from the embedded slave's register store (verify what masters see) |
159
+ | `modpackqt-slave-write` | Push values into the embedded slave's register store |
160
+ | `modpackqt-traffic` | **Passive monitor** — emits one message per Modbus op. Free, with filters, full visibility into what's happening on the wire. |
206
161
 
207
162
  ---
208
163
 
209
- ## Configuration Node
164
+ ## Why Modbus + bytes are split into two palettes
165
+
166
+ Most Modbus packages bake type decoding into the read node — one giant dropdown for int16 / int32 / float32 / Siemens-CDAB / etc. That made sense in 2010 but it's a mess: every protocol re-implements the same decoders, and you can't reuse them for MQTT / TCP / BLE / file payloads.
210
167
 
211
- Add one `modpackqt-config` node per gateway instance. All other nodes reference it.
168
+ We split them on purpose:
169
+ - **Modbus nodes** speak Modbus and output raw registers — nothing else.
170
+ - **Bytes nodes** decode any binary payload into typed values.
212
171
 
213
- | Property | Default | Description |
172
+ You write less code, your flows stay readable, and the same decoder works whether the data came from a PLC, an MQTT broker, or a UDP socket.
173
+
174
+ ---
175
+
176
+ ## Pricing
177
+
178
+ | | Free | Paid |
214
179
  |---|---|---|
215
- | Host | `localhost` | Hostname or IP of the machine running the ModPackQT Gateway app |
216
- | Port | `8502` | Port that the ModPackQT Gateway app listens on |
217
- | API Key | _(empty)_ | Optional — sent as `x-api-key` header if set |
180
+ | Master read / write | | |
181
+ | Embedded slave server | | |
182
+ | **Traffic monitor** | | |
183
+ | Daily ops cap | **1,000 / day** per Node-RED instance | **Unlimited** |
184
+ | Branding in node status | Visible | Hidden |
185
+ | API key required | No | Yes |
186
+ | Trial | — | **30 days free, no credit card** |
187
+
188
+ [Get a free trial key →](https://modpackqt.com/nodered)
189
+
190
+ When the daily cap is hit, master read/write nodes return a clear error pointing at the upgrade link. **Traffic events, slave register reads/writes, and decode/encode operations don't count.**
218
191
 
219
192
  ---
220
193
 
221
- ## API Endpoints Used
194
+ ## Importing the example flow
222
195
 
223
- | Node | Gateway Endpoint |
224
- |---|---|
225
- | `modpackqt-master-read` | `POST /api/modbus/tcp/read` |
226
- | `modpackqt-master-write` | `POST /api/modbus/tcp/write` |
227
- | `modpackqt-slave-read` | `GET /api/slaves/:id/registers` |
228
- | `modpackqt-slave-write` | `PATCH /api/slaves/:id/registers` |
196
+ This package ships with a complete demo flow under `examples/basic-flow.json` showing every node combined with the bytes palette (master read → decode-float32, encode-float32 → master write, status bitmask, traffic monitor, slave loop).
197
+
198
+ Node-RED Menu → Import → Examples → **node-red-contrib-modbus-modpackqt** → basic-flow.
199
+
200
+ Make sure `node-red-contrib-bytes-modpackqt` is also installed before importing — the example uses both.
229
201
 
230
202
  ---
231
203
 
@@ -233,25 +205,42 @@ Add one `modpackqt-config` node per gateway instance. All other nodes reference
233
205
 
234
206
  | Issue | Solution |
235
207
  |---|---|
236
- | `connect ECONNREFUSED localhost:8502` | The ModPackQT Gateway app is not running. Start it first. |
237
- | `401 Unauthorized` | Missing or invalid API key check `modpackqt-config`. |
238
- | `403 Forbidden` on slave nodes | Your plan does not include the Slave Simulator. [Upgrade your plan →](https://modpackqt.com/#pricing) |
239
- | `slave not found check Slave ID` | The Slave ID is wrong or that slave was deleted. Check in ModPackQT Slave Simulator. |
240
- | `gateway not running` on slave nodes | The Gateway app is stopped. Open ModPackQT and click Start Gateway. |
241
- | `Cannot find module 'axios'` | Run `npm install` in `~/.node-red`. |
242
- | Nodes not appearing after install | Restart Node-RED completely after `npm install`. |
243
- | Node-RED version error | Requires Node-RED ≥ 2.0.0 and Node.js ≥ 14. |
208
+ | `ModPackQT free tier limit reached` | Either wait until midnight or [get a free trial key](https://modpackqt.com/nodered) |
209
+ | Decoded float looks like garbage | Try a different word order (`BE` `LE_SWAP`) — Schneider uses ABCD, Siemens often uses CDAB |
210
+ | `Serial port not configured for RTU mode` | Open runtime config set Serial Port (e.g. `/dev/ttyUSB0` or `COM3`) |
211
+ | `EADDRINUSE` on slave port | Another process already uses that port. Pick a different one (e.g. `1502`). |
212
+ | `connect ECONNREFUSED` | Target Modbus device is unreachable. Check IP / port / firewall. |
213
+ | `Embedded slave is disabled` | Open runtime config check **Enable embedded slave server** |
214
+ | Nodes don't appear after install | Fully restart Node-RED. |
215
+
216
+ ---
217
+
218
+ ## Reporting bugs & getting updates
219
+
220
+ - **Bugs / feature requests:** open a GitHub issue at the repository linked in
221
+ `package.json`, or email **support@modpackqt.com**.
222
+ - **Security issues:** see [`SECURITY.md`](./SECURITY.md) — please report
223
+ privately to **support@modpackqt.com**.
224
+ - **Updates are never automatic.** Node-RED's palette manager will show
225
+ "update available" when we publish a new version — you choose when to
226
+ upgrade. Pin a major version (`^2.0.0`) in production.
227
+ - **Changelog:** see [`CHANGELOG.md`](./CHANGELOG.md). We follow
228
+ [semver](https://semver.org/) — patch releases for bug fixes only.
229
+ - **Paid customers** get email notice for security and breaking-change
230
+ releases.
244
231
 
245
232
  ---
246
233
 
247
234
  ## Links
248
235
 
249
- - [ModPackQT Homepage](https://modpackqt.com)
250
- - [Download ModPackQT Gateway](https://modpackqt.com/download)
251
- - [Free Modbus Tutorial](https://modpackqt.com/resources/tutorial)
252
- - [Modbus Resources Hub](https://modpackqt.com/resources)
253
- - [Node-RED Docs](https://nodered.org/docs/)
254
- - [Contact / Report an Issue](https://modpackqt.com/contact)
236
+ - [ModPackQT homepage](https://modpackqt.com)
237
+ - [Node-RED + ModPackQT docs](https://modpackqt.com/nodered)
238
+ - [Bytes palette (decoders/encoders)](https://www.npmjs.com/package/node-red-contrib-bytes-modpackqt)
239
+ - [Modbus tutorials](https://modpackqt.com/resources/tutorial)
240
+ - [Disclaimer & safe-use checklist](./DISCLAIMER.md)
241
+ - [Changelog](./CHANGELOG.md)
242
+ - [Security policy](./SECURITY.md)
243
+ - [Contributing guide](./CONTRIBUTING.md)
255
244
 
256
245
  ---
257
246
 
package/SECURITY.md ADDED
@@ -0,0 +1,50 @@
1
+ # Security policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ If you discover a security issue in this package, **please report it
6
+ privately** so we can fix it before it's exploited.
7
+
8
+ - **Email:** support@modpackqt.com
9
+ - **Response time:** we aim to acknowledge within **2 business days** and
10
+ publish a fix or mitigation within **90 days** of the report.
11
+
12
+ Please include:
13
+
14
+ - Affected version(s)
15
+ - A short description of the impact
16
+ - Steps or a proof-of-concept to reproduce
17
+ - Your preferred name for credit (or anonymous)
18
+
19
+ We follow [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure):
20
+ we will not publish the issue until you've had a chance to verify the fix or
21
+ the 90-day window has elapsed.
22
+
23
+ ## Supported versions
24
+
25
+ | Version | Status |
26
+ |---|---|
27
+ | `2.x` | ✅ Active — security fixes within 90 days |
28
+ | `1.x` | ❌ End of life — please migrate to 2.x |
29
+
30
+ ## What is in scope
31
+
32
+ - The Node-RED nodes shipped in this package
33
+ - The embedded Modbus TCP slave server
34
+ - The traffic event bus
35
+ - Authentication and rate-limiting code paths
36
+
37
+ ## What is out of scope
38
+
39
+ - Vulnerabilities in our dependencies (please report those upstream — for
40
+ example to [`modbus-serial`](https://github.com/yaacov/node-modbus-serial))
41
+ — but tell us too so we can pin a safe version
42
+ - Issues that require an attacker to already have control of the Node-RED
43
+ runtime (Node-RED is not a sandbox)
44
+ - Denial-of-service caused by the free-tier rate limit (this is by design)
45
+
46
+ ## Hall of fame
47
+
48
+ We credit security reporters in this section unless they request anonymity.
49
+
50
+ _(none yet)_