node-red-contrib-modbus-modpackqt 3.2.2 → 3.2.4
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 +25 -0
- package/nodes/lib/probe-runtime.js +1 -1
- package/nodes/modpackqt-config.html +33 -13
- package/nodes/modpackqt-master-probe.html +20 -33
- package/nodes/modpackqt-slave-probe.html +19 -31
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,31 @@ 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.2.4] — 2026-05-10
|
|
8
|
+
|
|
9
|
+
### Changed — Probe nodes are now picker-only
|
|
10
|
+
|
|
11
|
+
- **`modpackqt-master-probe` and `modpackqt-slave-probe` no longer expose
|
|
12
|
+
Target Host / Target Port / Unit ID / Timeout / Bind Host / Listen Port
|
|
13
|
+
fields in the editor.** All of that information comes from the picked
|
|
14
|
+
profile (or saved slave). The probe simply deep-links the web tester
|
|
15
|
+
to that device.
|
|
16
|
+
- The fields are still stored on the node (so existing flows keep
|
|
17
|
+
working) — they're just hidden form state filled by the picker.
|
|
18
|
+
- Probe edit dialog is now: **Name + Runtime + My Profiles/Slaves**.
|
|
19
|
+
Plus a one-line summary above the "Open in ModPackQT Console" button
|
|
20
|
+
showing the resolved target.
|
|
21
|
+
|
|
22
|
+
## [3.2.3] — 2026-05-10
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **Embedded slave server section is now hidden by default** in the
|
|
27
|
+
runtime config dialog. Only relevant to users of the
|
|
28
|
+
`modpackqt-slave-read` / `-write` nodes — master-only users no longer
|
|
29
|
+
see the "Enable embedded Modbus TCP slave server" checkbox at all.
|
|
30
|
+
Auto-expanded if the slave server is already enabled on the config.
|
|
31
|
+
|
|
7
32
|
## [3.2.2] — 2026-05-10
|
|
8
33
|
|
|
9
34
|
### Changed
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const http = require('http');
|
|
19
19
|
const { URL } = require('url');
|
|
20
20
|
|
|
21
|
-
const PALETTE_VERSION = '3.2.
|
|
21
|
+
const PALETTE_VERSION = '3.2.4';
|
|
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;
|
|
@@ -35,6 +35,22 @@
|
|
|
35
35
|
$('#node-config-input-slaveEnabled').on('change', toggleSlave);
|
|
36
36
|
toggleRtu();
|
|
37
37
|
toggleSlave();
|
|
38
|
+
// Embedded slave server section is hidden by default — only relevant
|
|
39
|
+
// for users of the modpackqt-slave-read / -write nodes. Auto-expand
|
|
40
|
+
// if the slave server is already enabled on this config.
|
|
41
|
+
const $slaveSection = $('.modpackqt-slave-section');
|
|
42
|
+
const $slaveToggle = $('.modpackqt-slave-section-toggle');
|
|
43
|
+
const setSlaveOpen = (open) => {
|
|
44
|
+
$slaveSection.toggle(open);
|
|
45
|
+
$slaveToggle.html(open
|
|
46
|
+
? '▾ Hide embedded slave server'
|
|
47
|
+
: '▸ Embedded slave server (only for modpackqt-slave-read / -write nodes)');
|
|
48
|
+
};
|
|
49
|
+
setSlaveOpen(this.slaveEnabled === true || this.slaveEnabled === 'true');
|
|
50
|
+
$slaveToggle.off('click.modpackqt').on('click.modpackqt', (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
setSlaveOpen($slaveSection.is(':hidden'));
|
|
53
|
+
});
|
|
38
54
|
}
|
|
39
55
|
});
|
|
40
56
|
</script>
|
|
@@ -86,20 +102,24 @@
|
|
|
86
102
|
<input type="number" id="node-config-input-timeoutMs" placeholder="3000">
|
|
87
103
|
</div>
|
|
88
104
|
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
<label for="node-config-input-slaveEnabled" style="width:auto">
|
|
92
|
-
<input type="checkbox" id="node-config-input-slaveEnabled" style="width:auto;vertical-align:middle">
|
|
93
|
-
Enable embedded Modbus TCP slave server
|
|
94
|
-
</label>
|
|
95
|
-
</div>
|
|
96
|
-
<div class="form-row modpackqt-slave-only">
|
|
97
|
-
<label for="node-config-input-slaveHost"><i class="fa fa-globe"></i> Bind Host</label>
|
|
98
|
-
<input type="text" id="node-config-input-slaveHost" placeholder="0.0.0.0 (all interfaces)">
|
|
105
|
+
<div class="form-row" style="margin:14px 0 4px 0;border-top:1px solid #e5e7eb;padding-top:10px">
|
|
106
|
+
<a href="#" class="modpackqt-slave-section-toggle" style="font-size:12px;color:#6b7280;text-decoration:none;cursor:pointer">▸ Embedded slave server (only for modpackqt-slave-read / -write nodes)</a>
|
|
99
107
|
</div>
|
|
100
|
-
<div class="
|
|
101
|
-
<
|
|
102
|
-
|
|
108
|
+
<div class="modpackqt-slave-section" style="display:none">
|
|
109
|
+
<div class="form-row">
|
|
110
|
+
<label for="node-config-input-slaveEnabled" style="width:auto">
|
|
111
|
+
<input type="checkbox" id="node-config-input-slaveEnabled" style="width:auto;vertical-align:middle">
|
|
112
|
+
Enable embedded Modbus TCP slave server
|
|
113
|
+
</label>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="form-row modpackqt-slave-only">
|
|
116
|
+
<label for="node-config-input-slaveHost"><i class="fa fa-globe"></i> Bind Host</label>
|
|
117
|
+
<input type="text" id="node-config-input-slaveHost" placeholder="0.0.0.0 (all interfaces)">
|
|
118
|
+
</div>
|
|
119
|
+
<div class="form-row modpackqt-slave-only">
|
|
120
|
+
<label for="node-config-input-slavePort"><i class="fa fa-hashtag"></i> Slave Port</label>
|
|
121
|
+
<input type="number" id="node-config-input-slavePort" placeholder="1502">
|
|
122
|
+
</div>
|
|
103
123
|
</div>
|
|
104
124
|
|
|
105
125
|
<h4 style="margin-top:18px">ModPackQT Account Key (optional — for cloud profile sync)</h4>
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: '' },
|
|
7
7
|
server: { value: '', type: 'modpackqt-config' },
|
|
8
|
-
targetHost: { value: '192.168.1.10'
|
|
9
|
-
targetPort: { value: 502,
|
|
10
|
-
unitId: { value: 1,
|
|
8
|
+
targetHost: { value: '192.168.1.10' },
|
|
9
|
+
targetPort: { value: 502, validate: RED.validators.number() },
|
|
10
|
+
unitId: { value: 1, validate: RED.validators.number() },
|
|
11
11
|
timeoutMs: { value: 3000, validate: RED.validators.number() }
|
|
12
12
|
},
|
|
13
13
|
inputs: 0,
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
oneditprepare: function () {
|
|
21
21
|
const node = this;
|
|
22
22
|
if (window.ModPackQTMasterPicker) ModPackQTMasterPicker.attach(this);
|
|
23
|
-
if (window.ModPackQTAdvancedToggle) ModPackQTAdvancedToggle.attach('modpackqt-master-probe');
|
|
24
23
|
const buildLink = (info) => {
|
|
25
24
|
const probeHost = (info && info.host) || '127.0.0.1';
|
|
26
25
|
const probePort = (info && info.port) || 8502;
|
|
@@ -38,8 +37,11 @@
|
|
|
38
37
|
+ (name ? '&name=' + encodeURIComponent(name) : '');
|
|
39
38
|
$('#modpackqt-probe-link').attr('href', url);
|
|
40
39
|
$('#modpackqt-probe-runtime').text(probeHost + ':' + probePort);
|
|
40
|
+
$('#modpackqt-probe-target').text(targetHost + ':' + targetPort + ' · unit ' + unitId);
|
|
41
41
|
};
|
|
42
42
|
$.getJSON('modpackqt-probe/info').done(buildLink).fail(() => buildLink({}));
|
|
43
|
+
// Refresh the link summary whenever the picker fills the hidden fields
|
|
44
|
+
$('#node-input-modpackqt-picker').on('change', () => setTimeout(() => buildLink({}), 0));
|
|
43
45
|
}
|
|
44
46
|
});
|
|
45
47
|
</script>
|
|
@@ -49,40 +51,24 @@
|
|
|
49
51
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
50
52
|
<input type="text" id="node-input-name" placeholder="(optional, e.g. Inverter A)">
|
|
51
53
|
</div>
|
|
54
|
+
<div class="form-row">
|
|
55
|
+
<label for="node-input-server"><i class="fa fa-cog"></i> Runtime</label>
|
|
56
|
+
<input type="text" id="node-input-server">
|
|
57
|
+
</div>
|
|
52
58
|
<div class="form-row">
|
|
53
59
|
<label for="node-input-modpackqt-picker"><i class="fa fa-cloud-download"></i> My Profiles</label>
|
|
54
60
|
<select id="node-input-modpackqt-picker" style="width:65%"></select>
|
|
55
61
|
<button type="button" id="modpackqt-picker-refresh" class="red-ui-button" title="Reload from modpackqt.com" style="margin-left:4px"><i class="fa fa-refresh"></i></button>
|
|
56
62
|
</div>
|
|
57
63
|
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
58
|
-
Pick a saved Modbus profile from your modpackqt.com account —
|
|
64
|
+
Pick a saved Modbus profile from your modpackqt.com account — the probe deep-links the web tester to that device. Set up your Account Key on the runtime config (pencil icon).
|
|
59
65
|
</div>
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
<label for="node-input-server"><i class="fa fa-cog"></i> Runtime</label>
|
|
67
|
-
<input type="text" id="node-input-server">
|
|
68
|
-
</div>
|
|
69
|
-
<div class="form-row">
|
|
70
|
-
<label for="node-input-targetHost"><i class="fa fa-plug"></i> Target Host</label>
|
|
71
|
-
<input type="text" id="node-input-targetHost" placeholder="192.168.1.10">
|
|
72
|
-
</div>
|
|
73
|
-
<div class="form-row">
|
|
74
|
-
<label for="node-input-targetPort"><i class="fa fa-hashtag"></i> Target Port</label>
|
|
75
|
-
<input type="number" id="node-input-targetPort" min="1" max="65535" placeholder="502">
|
|
76
|
-
</div>
|
|
77
|
-
<div class="form-row">
|
|
78
|
-
<label for="node-input-unitId"><i class="fa fa-id-card"></i> Unit ID</label>
|
|
79
|
-
<input type="number" id="node-input-unitId" min="1" max="247" placeholder="1">
|
|
80
|
-
</div>
|
|
81
|
-
<div class="form-row">
|
|
82
|
-
<label for="node-input-timeoutMs"><i class="fa fa-clock-o"></i> Timeout (ms)</label>
|
|
83
|
-
<input type="number" id="node-input-timeoutMs" placeholder="3000">
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
67
|
+
<!-- Hidden state — populated by the picker, used to build the probe URL. -->
|
|
68
|
+
<input type="hidden" id="node-input-targetHost">
|
|
69
|
+
<input type="hidden" id="node-input-targetPort">
|
|
70
|
+
<input type="hidden" id="node-input-unitId">
|
|
71
|
+
<input type="hidden" id="node-input-timeoutMs">
|
|
86
72
|
|
|
87
73
|
<div class="form-tips" style="margin-top:14px">
|
|
88
74
|
<b>One probe = one device.</b> Drop additional master-probe nodes for additional devices —
|
|
@@ -96,15 +82,16 @@
|
|
|
96
82
|
Open in ModPackQT Console <i class="fa fa-external-link" style="margin-left:6px;"></i>
|
|
97
83
|
</a>
|
|
98
84
|
<div style="margin-top:6px;font-size:11px;color:#6b7280;">
|
|
99
|
-
|
|
85
|
+
Target: <span id="modpackqt-probe-target">—</span> · runtime <span id="modpackqt-probe-runtime">starting…</span>
|
|
100
86
|
</div>
|
|
101
87
|
</div>
|
|
102
88
|
</script>
|
|
103
89
|
|
|
104
90
|
<script type="text/html" data-help-name="modpackqt-master-probe">
|
|
105
91
|
<p>Live tester / commissioning probe for a single Modbus TCP device.
|
|
106
|
-
|
|
107
|
-
to launch the web tester live-attached
|
|
92
|
+
Pick a saved profile from your modpackqt.com account, then click
|
|
93
|
+
<b>Open in ModPackQT Console</b> to launch the web tester live-attached
|
|
94
|
+
to that device.</p>
|
|
108
95
|
|
|
109
96
|
<h3>How it works</h3>
|
|
110
97
|
<p>The first probe deployed in this Node-RED instance starts a small local
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
name: { value: '' },
|
|
7
7
|
server: { value: '', type: 'modpackqt-config' },
|
|
8
8
|
bindHost: { value: '0.0.0.0' },
|
|
9
|
-
bindPort: { value: 1502,
|
|
10
|
-
unitId: { value: 1,
|
|
9
|
+
bindPort: { value: 1502, validate: RED.validators.number() },
|
|
10
|
+
unitId: { value: 1, validate: RED.validators.number() }
|
|
11
11
|
},
|
|
12
12
|
inputs: 0,
|
|
13
13
|
outputs: 0,
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
oneditprepare: function () {
|
|
20
20
|
const node = this;
|
|
21
21
|
if (window.ModPackQTSlavePicker) ModPackQTSlavePicker.attach(this);
|
|
22
|
-
if (window.ModPackQTAdvancedToggle) ModPackQTAdvancedToggle.attach('modpackqt-slave-probe');
|
|
23
22
|
const buildLink = (info) => {
|
|
24
23
|
const probeHost = (info && info.host) || '127.0.0.1';
|
|
25
24
|
const probePort = (info && info.port) || 8502;
|
|
@@ -35,8 +34,10 @@
|
|
|
35
34
|
+ (name ? '&name=' + encodeURIComponent(name) : '');
|
|
36
35
|
$('#modpackqt-slave-probe-link').attr('href', url);
|
|
37
36
|
$('#modpackqt-slave-probe-runtime').text(probeHost + ':' + probePort);
|
|
37
|
+
$('#modpackqt-slave-probe-target').text(':' + bindPort + ' · unit ' + unitId);
|
|
38
38
|
};
|
|
39
39
|
$.getJSON('modpackqt-probe/info').done(buildLink).fail(() => buildLink({}));
|
|
40
|
+
$('#node-input-modpackqt-slave-picker').on('change', () => setTimeout(() => buildLink({}), 0));
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
43
|
</script>
|
|
@@ -52,12 +53,12 @@
|
|
|
52
53
|
const cfgId = $('#node-input-server').val();
|
|
53
54
|
$sel.empty().append('<option value="">— Loading… —</option>');
|
|
54
55
|
if (!cfgId || cfgId === '_ADD_') {
|
|
55
|
-
$sel.empty().append('<option value="">— Set up runtime & Account Key
|
|
56
|
+
$sel.empty().append('<option value="">— Set up runtime & Account Key first —</option>');
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
$.getJSON('modpackqt/slaves?config=' + encodeURIComponent(cfgId))
|
|
59
60
|
.done(function (rows) {
|
|
60
|
-
$sel.empty().append('<option value="">—
|
|
61
|
+
$sel.empty().append('<option value="">— None —</option>');
|
|
61
62
|
(rows || [])
|
|
62
63
|
.filter(function (s) { return s && (s.protocol === 'tcp' || !s.protocol); })
|
|
63
64
|
.forEach(function (s) {
|
|
@@ -89,36 +90,23 @@
|
|
|
89
90
|
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
90
91
|
<input type="text" id="node-input-name" placeholder="(optional, e.g. Fake Inverter)">
|
|
91
92
|
</div>
|
|
93
|
+
<div class="form-row">
|
|
94
|
+
<label for="node-input-server"><i class="fa fa-cog"></i> Runtime</label>
|
|
95
|
+
<input type="text" id="node-input-server">
|
|
96
|
+
</div>
|
|
92
97
|
<div class="form-row">
|
|
93
98
|
<label for="node-input-modpackqt-slave-picker"><i class="fa fa-cloud-download"></i> My Slaves</label>
|
|
94
99
|
<select id="node-input-modpackqt-slave-picker" style="width:65%"></select>
|
|
95
100
|
<button type="button" id="modpackqt-slave-picker-refresh" class="red-ui-button" title="Reload from modpackqt.com" style="margin-left:4px"><i class="fa fa-refresh"></i></button>
|
|
96
101
|
</div>
|
|
97
102
|
<div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
|
|
98
|
-
Pick a saved slave config from your modpackqt.com account —
|
|
103
|
+
Pick a saved slave config from your modpackqt.com account — the probe deep-links the web register editor to that slave. Set up your Account Key on the runtime config (pencil icon).
|
|
99
104
|
</div>
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
<div class="form-row">
|
|
106
|
-
<label for="node-input-server"><i class="fa fa-cog"></i> Runtime</label>
|
|
107
|
-
<input type="text" id="node-input-server">
|
|
108
|
-
</div>
|
|
109
|
-
<div class="form-row">
|
|
110
|
-
<label for="node-input-bindHost"><i class="fa fa-globe"></i> Bind Host</label>
|
|
111
|
-
<input type="text" id="node-input-bindHost" placeholder="0.0.0.0 (all interfaces)">
|
|
112
|
-
</div>
|
|
113
|
-
<div class="form-row">
|
|
114
|
-
<label for="node-input-bindPort"><i class="fa fa-hashtag"></i> Listen Port</label>
|
|
115
|
-
<input type="number" id="node-input-bindPort" min="1" max="65535" placeholder="1502">
|
|
116
|
-
</div>
|
|
117
|
-
<div class="form-row">
|
|
118
|
-
<label for="node-input-unitId"><i class="fa fa-id-card"></i> Unit ID</label>
|
|
119
|
-
<input type="number" id="node-input-unitId" min="1" max="247" placeholder="1">
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
106
|
+
<!-- Hidden state — populated by the picker, used to build the probe URL. -->
|
|
107
|
+
<input type="hidden" id="node-input-bindHost">
|
|
108
|
+
<input type="hidden" id="node-input-bindPort">
|
|
109
|
+
<input type="hidden" id="node-input-unitId">
|
|
122
110
|
|
|
123
111
|
<div class="form-tips" style="margin-top:14px">
|
|
124
112
|
<b>One probe = one fake slave.</b> For multiple slaves, drop one node per
|
|
@@ -133,15 +121,15 @@
|
|
|
133
121
|
Open in ModPackQT Console <i class="fa fa-external-link" style="margin-left:6px;"></i>
|
|
134
122
|
</a>
|
|
135
123
|
<div style="margin-top:6px;font-size:11px;color:#6b7280;">
|
|
136
|
-
|
|
124
|
+
Target: <span id="modpackqt-slave-probe-target">—</span> · runtime <span id="modpackqt-slave-probe-runtime">starting…</span>
|
|
137
125
|
</div>
|
|
138
126
|
</div>
|
|
139
127
|
</script>
|
|
140
128
|
|
|
141
129
|
<script type="text/html" data-help-name="modpackqt-slave-probe">
|
|
142
|
-
<p>Live simulator probe for a single Modbus TCP slave.
|
|
143
|
-
|
|
144
|
-
|
|
130
|
+
<p>Live simulator probe for a single Modbus TCP slave. Pick a saved slave
|
|
131
|
+
config from your modpackqt.com account, then click <b>Open in ModPackQT
|
|
132
|
+
Console</b> to launch the web register editor.</p>
|
|
145
133
|
|
|
146
134
|
<h3>How it works</h3>
|
|
147
135
|
<p>Each slave-probe owns a 65 536-register store per type (coils, discrete,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-modbus-modpackqt",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
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",
|