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

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,18 @@ 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.17] — 2026-05-10
8
+
9
+ ### Changed
10
+
11
+ - **Master-probe dialog: one Account Key, not two.** The duplicate
12
+ Account Key field on master-probe is gone — the key now lives only
13
+ on the Target Device (probe-config) where it always belonged.
14
+ - **My Connections picker is now front-and-center on master-probe.**
15
+ Pick a saved connection right from the master-probe dialog —
16
+ no more drilling into the Target Device config to choose host /
17
+ port / unit ID. The picker reuses the Target Device's Account Key.
18
+
7
19
  ## [3.3.16] — 2026-05-10
8
20
 
9
21
  ### 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.16';
21
+ const PALETTE_VERSION = '3.3.17';
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;
@@ -11,9 +11,6 @@
11
11
  unitId: { value: 0, validate: function (v) { return v === '' || v === 0 || RED.validators.number()(v); } },
12
12
  timeoutMs: { value: 0, validate: function (v) { return v === '' || v === 0 || RED.validators.number()(v); } }
13
13
  },
14
- credentials: {
15
- apiKey: { type: 'password' }
16
- },
17
14
  inputs: 0,
18
15
  outputs: 0,
19
16
  icon: 'font-awesome/fa-rocket',
@@ -23,29 +20,88 @@
23
20
  paletteLabel: 'modbus master probe',
24
21
  oneditprepare: function () {
25
22
  const node = this;
26
- const buildLink = (info) => {
27
- const probeHost = (info && info.host) || '127.0.0.1';
28
- const probePort = (info && info.port) || 8502;
23
+ let runtimeInfo = {};
24
+
25
+ const getCfgTarget = () => {
29
26
  const cfgId = $('#node-input-server').val();
30
27
  const cfg = cfgId ? RED.nodes.node(cfgId) : null;
31
- const targetHost = node.targetHost || (cfg && cfg.targetHost) || '';
32
- const targetPort = node.targetPort || (cfg && cfg.targetPort) || 502;
33
- const unitId = node.unitId || (cfg && cfg.unitId) || 1;
34
- const name = $('#node-input-name').val() || node.name || '';
28
+ return {
29
+ host: (cfg && cfg.targetHost) || '',
30
+ port: (cfg && cfg.targetPort) || 502,
31
+ unitId: (cfg && cfg.unitId) || 1
32
+ };
33
+ };
34
+
35
+ const buildLink = () => {
36
+ const probeHost = runtimeInfo.host || '127.0.0.1';
37
+ const probePort = runtimeInfo.port || 8502;
38
+ const tHost = $('#node-input-targetHost').val() || node.targetHost || getCfgTarget().host;
39
+ const tPort = $('#node-input-targetPort').val() || node.targetPort || getCfgTarget().port;
40
+ const tUnit = $('#node-input-unitId').val() || node.unitId || getCfgTarget().unitId;
41
+ const name = $('#node-input-name').val() || node.name || '';
35
42
  const url = 'https://modpackqt.com/master'
36
43
  + '?probe=' + encodeURIComponent(node.id)
37
44
  + '&probeHost=' + encodeURIComponent(probeHost)
38
45
  + '&probePort=' + probePort
39
- + '&host=' + encodeURIComponent(targetHost)
40
- + '&port=' + targetPort
41
- + '&unitId=' + unitId
46
+ + '&host=' + encodeURIComponent(tHost)
47
+ + '&port=' + tPort
48
+ + '&unitId=' + tUnit
42
49
  + (name ? '&name=' + encodeURIComponent(name) : '');
43
50
  $('#modpackqt-probe-link').attr('href', url);
44
51
  $('#modpackqt-probe-runtime').text(probeHost + ':' + probePort);
45
- $('#modpackqt-probe-target').text(targetHost + ':' + targetPort + ' · unit ' + unitId);
52
+ $('#modpackqt-probe-target').text((tHost || '—') + ':' + tPort + ' · unit ' + tUnit);
53
+ };
54
+ $.getJSON('modpackqt-probe/info')
55
+ .done((info) => { runtimeInfo = info || {}; buildLink(); })
56
+ .fail(() => buildLink());
57
+
58
+ // ── My Connections picker — uses the selected Target Device's Account Key
59
+ const $sel = $('#node-input-modpackqt-conn-picker');
60
+ const $hint = $('#modpackqt-conn-picker-hint');
61
+ const reload = () => {
62
+ $sel.empty().append('<option value="">— Loading… —</option>');
63
+ const cfgId = $('#node-input-server').val();
64
+ if (!cfgId) {
65
+ $sel.empty().append('<option value="">— Pick a Target Device below first —</option>');
66
+ $hint.text('Pick a Target Device first — its Account Key is used to load your saved connections.');
67
+ return;
68
+ }
69
+ $.getJSON('modpackqt/connections?probe=' + encodeURIComponent(cfgId))
70
+ .done((rows) => {
71
+ $sel.empty().append('<option value="">— Manual entry —</option>');
72
+ (rows || []).forEach((c) => {
73
+ const label = (c.name || '(unnamed)') + (c.connectionType === 'rtu'
74
+ ? ' — RTU'
75
+ : ' — ' + (c.host || '?') + ':' + (c.port || 502) + ' #' + (c.unitId || 1));
76
+ $('<option>').val(c.id).text(label).data('conn', c).appendTo($sel);
77
+ });
78
+ $hint.text('Picks one of your saved connections from modpackqt.com — auto-fills host, port, and unit ID.');
79
+ // Reflect current node target as selected if it matches
80
+ (rows || []).some((c) => {
81
+ if (c.host === (node.targetHost || '') && Number(c.port) === Number(node.targetPort || 0)) {
82
+ $sel.val(c.id); return true;
83
+ }
84
+ return false;
85
+ });
86
+ })
87
+ .fail((xhr) => {
88
+ const msg = (xhr.responseJSON && xhr.responseJSON.error) || ('HTTP ' + xhr.status);
89
+ $sel.empty().append($('<option>').val('').text('— ' + msg + ' —'));
90
+ $hint.text('Could not load connections — check the Account Key on the Target Device.');
91
+ });
46
92
  };
47
- $.getJSON('modpackqt-probe/info').done(buildLink).fail(() => buildLink({}));
48
- $('#node-input-server').on('change', () => buildLink({}));
93
+ $('#modpackqt-conn-picker-refresh').on('click', (e) => { e.preventDefault(); reload(); });
94
+ $sel.on('change', function () {
95
+ const c = $(this).find('option:selected').data('conn');
96
+ if (!c) return;
97
+ if (c.host) $('#node-input-targetHost').val(c.host);
98
+ if (c.port) $('#node-input-targetPort').val(c.port);
99
+ if (c.unitId) $('#node-input-unitId').val(c.unitId);
100
+ if (!$('#node-input-name').val() && c.name) $('#node-input-name').val(c.name);
101
+ buildLink();
102
+ });
103
+ $('#node-input-server').on('change', () => { reload(); buildLink(); });
104
+ reload();
49
105
  }
50
106
  });
51
107
  </script>
@@ -56,20 +112,20 @@
56
112
  <input type="text" id="node-input-name" placeholder="(optional, e.g. Inverter A)">
57
113
  </div>
58
114
  <div class="form-row">
59
- <label for="node-input-server"><i class="fa fa-plug"></i> Target Device</label>
60
- <input type="text" id="node-input-server">
115
+ <label for="node-input-modpackqt-conn-picker"><i class="fa fa-cloud-download"></i> My Connections</label>
116
+ <select id="node-input-modpackqt-conn-picker" style="width:65%"></select>
117
+ <button type="button" id="modpackqt-conn-picker-refresh" class="red-ui-button" title="Reload" style="margin-left:4px"><i class="fa fa-refresh"></i></button>
61
118
  </div>
62
- <div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
63
- Pick the Modbus device this probe should attach to the web tester deep-links to it.
119
+ <div id="modpackqt-conn-picker-hint" class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
120
+ Picks one of your saved connections from modpackqt.comauto-fills host, port, and unit ID.
64
121
  </div>
65
122
 
66
123
  <div class="form-row">
67
- <label for="node-input-apiKey"><i class="fa fa-key"></i> Account Key</label>
68
- <input type="password" id="node-input-apiKey" placeholder="Paste your ModPackQT tunnel key">
124
+ <label for="node-input-server"><i class="fa fa-plug"></i> Target Device</label>
125
+ <input type="text" id="node-input-server">
69
126
  </div>
70
127
  <div class="form-tips" style="font-size:11px;color:#6b7280;margin:-8px 0 12px 105px">
71
- Generate at <a href="https://modpackqt.com/settings" target="_blank" rel="noopener">modpackqt.com Settings Cloud Gateways</a>.
72
- Used only by the modpackqt.com web console to sync with this probe.
128
+ Runtime config that holds your <b>Account Key</b>. The key powers the picker above and lets the web console attach to this probe.
73
129
  </div>
74
130
 
75
131
  <input type="hidden" id="node-input-targetHost">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-modbus-modpackqt",
3
- "version": "3.3.16",
3
+ "version": "3.3.17",
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",