node-red-contrib-ccu 3.4.2 → 4.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.
Files changed (49) hide show
  1. package/.prettierignore +10 -0
  2. package/.prettierrc +14 -0
  3. package/AGENTS.md +96 -0
  4. package/CHANGELOG.md +66 -0
  5. package/README.md +17 -21
  6. package/ROADMAP.md +402 -0
  7. package/eslint.config.js +45 -0
  8. package/examples/rpc-events.json +65 -0
  9. package/examples/switch-datapoint.json +86 -0
  10. package/examples/system-variable.json +60 -0
  11. package/nodes/ccu-alexa.html +12 -7
  12. package/nodes/ccu-alexa.js +33 -14
  13. package/nodes/ccu-connection.html +9 -1
  14. package/nodes/ccu-connection.js +588 -335
  15. package/nodes/ccu-display.html +11 -4
  16. package/nodes/ccu-display.js +26 -9
  17. package/nodes/ccu-get-value.html +13 -4
  18. package/nodes/ccu-get-value.js +2 -2
  19. package/nodes/ccu-mqtt.html +9 -10
  20. package/nodes/ccu-mqtt.js +55 -29
  21. package/nodes/ccu-program.html +1 -1
  22. package/nodes/ccu-program.js +9 -7
  23. package/nodes/ccu-rpc-event.html +12 -7
  24. package/nodes/ccu-rpc-event.js +4 -5
  25. package/nodes/ccu-rpc.html +12 -5
  26. package/nodes/ccu-rpc.js +8 -6
  27. package/nodes/ccu-script.html +1 -1
  28. package/nodes/ccu-script.js +4 -3
  29. package/nodes/ccu-set-value.html +11 -7
  30. package/nodes/ccu-set-value.js +40 -16
  31. package/nodes/ccu-signal.html +11 -5
  32. package/nodes/ccu-signal.js +34 -23
  33. package/nodes/ccu-switch.html +13 -5
  34. package/nodes/ccu-sysvar.html +1 -1
  35. package/nodes/ccu-sysvar.js +11 -7
  36. package/nodes/ccu-value.html +12 -7
  37. package/nodes/ccu-value.js +36 -13
  38. package/nodes/lib/base62.js +22 -0
  39. package/nodes/lib/discover.js +127 -0
  40. package/nodes/lib/nextport.js +30 -0
  41. package/nodes/lib/similarity.js +51 -0
  42. package/nodes/lib/status.js +1 -1
  43. package/package.json +105 -155
  44. package/roadmap-archive/README.md +20 -0
  45. package/roadmap-archive/phase-1.md +48 -0
  46. package/roadmap-archive/todo-history.md +39 -0
  47. package/TODO.md +0 -41
  48. package/ccu_rega_localhost.json +0 -1
  49. package/ccu_values_localhost.json +0 -1
@@ -0,0 +1,60 @@
1
+ [
2
+ {
3
+ "id": "sysvar-watch",
4
+ "type": "ccu-sysvar",
5
+ "name": "Presence",
6
+ "ccuConfig": "ccu-conn-example",
7
+ "topic": "${CCU}/SysVar/${Name}",
8
+ "change": true,
9
+ "cache": true,
10
+ "x": 340,
11
+ "y": 100,
12
+ "wires": [["debug-sysvar"]]
13
+ },
14
+ {
15
+ "id": "debug-sysvar",
16
+ "type": "debug",
17
+ "name": "sysvar",
18
+ "active": true,
19
+ "tosidebar": true,
20
+ "complete": "payload",
21
+ "x": 550,
22
+ "y": 100,
23
+ "wires": []
24
+ },
25
+ {
26
+ "id": "inject-set",
27
+ "type": "inject",
28
+ "name": "set true",
29
+ "props": [
30
+ {
31
+ "p": "payload"
32
+ }
33
+ ],
34
+ "payload": "true",
35
+ "payloadType": "bool",
36
+ "x": 140,
37
+ "y": 100,
38
+ "wires": [["sysvar-watch"]]
39
+ },
40
+ {
41
+ "id": "ccu-conn-example",
42
+ "type": "ccu-connection",
43
+ "name": "CCU",
44
+ "host": "ccu3-hostname-or-ip",
45
+ "regaEnabled": true,
46
+ "bcrfEnabled": true,
47
+ "iprfEnabled": true,
48
+ "virtEnabled": false,
49
+ "bcwiEnabled": false,
50
+ "cuxdEnabled": false,
51
+ "jackEnabled": false,
52
+ "regaPoll": true,
53
+ "regaInterval": "30",
54
+ "rpcPingTimeout": "60",
55
+ "rpcInitAddress": "",
56
+ "rpcServerHost": "",
57
+ "rpcBinPort": "2047",
58
+ "rpcXmlPort": "2048"
59
+ }
60
+ ]
@@ -21,7 +21,6 @@
21
21
  return this.name ? 'node_label_italic' : '';
22
22
  },
23
23
  oneditprepare() {
24
- console.log(this);
25
24
 
26
25
  const $nodeInputIface = $('#node-input-iface');
27
26
  const $nodeInputCcuConfig = $('#node-input-ccuConfig');
@@ -30,6 +29,7 @@
30
29
  let data;
31
30
  let ifacesLoaded = false;
32
31
  let ifacesPending = false;
32
+ let ifaceLoadRetries = 5;
33
33
 
34
34
  function loadIfaces(iface, cb) {
35
35
  if (ifacesPending) {
@@ -37,7 +37,6 @@
37
37
  }
38
38
 
39
39
  ifacesPending = true;
40
- console.log('loadIfaces()');
41
40
  $nodeInputIface.html('<option value=""></option>');
42
41
  const nodeId = $nodeInputCcuConfig.val();
43
42
  if (nodeId === '_ADD_') {
@@ -57,6 +56,12 @@
57
56
  cb();
58
57
  ifacesPending = false;
59
58
  }
59
+ }).fail(() => {
60
+ // config node not (yet) available in the runtime - allow retrying
61
+ ifacesPending = false;
62
+ if (ifaceLoadRetries-- > 0) {
63
+ setTimeout(() => loadIfaces(iface, cb), 1000);
64
+ }
60
65
  });
61
66
  }
62
67
  }
@@ -66,18 +71,15 @@
66
71
  return;
67
72
  }
68
73
 
69
- console.log('loadConfig()');
70
74
  const nodeId = $nodeInputCcuConfig.val();
71
75
  const url = 'ccu?config=' + nodeId + '&type=channels&iface=' + $nodeInputIface.val();
72
76
  $.getJSON(url, d => {
73
77
  data = d;
74
- console.log(d);
75
78
  autocompleteChannel();
76
79
  });
77
80
  }
78
81
 
79
82
  $nodeInputCcuConfig.change(() => {
80
- console.log('$nodeInputCcuConfig change');
81
83
  loadIfaces(this.iface, () => {
82
84
  ifacesLoaded = true;
83
85
  $nodeInputIface.removeAttr('disabled');
@@ -85,6 +87,10 @@
85
87
  });
86
88
  });
87
89
 
90
+ // Node-RED 4.x does not reliably fire the change event on dialog
91
+ // open - trigger the initial load explicitly (see ROADMAP.md 8.1)
92
+ $nodeInputCcuConfig.trigger('change');
93
+
88
94
  $nodeInputChannel.autocomplete({
89
95
  source: [],
90
96
  close: () => {
@@ -122,7 +128,6 @@
122
128
  }
123
129
 
124
130
  $nodeInputIface.change(() => {
125
- console.log('$nodeInputIface change');
126
131
  loadConfig();
127
132
  });
128
133
  },
@@ -172,7 +177,7 @@
172
177
 
173
178
  </script>
174
179
 
175
- <script type="text/x-red" data-template-name="ccu-alexa">
180
+ <script type="text/x-red" data-help-name="ccu-alexa" lang="de">
176
181
  <p>Homematic Geräte mit node-red-contrib-alexa-smart-home verbinden. Am Eingang den Node "alexa smart home v3"
177
182
  anschließen, am Ausgang "alexa smart home v3 state".</p>
178
183
  </script>
@@ -36,15 +36,15 @@ module.exports = function (RED) {
36
36
  change: true,
37
37
  stable: true,
38
38
  iface: config.iface,
39
- channel: String(config.channel).split(' ')[0]
39
+ channel: String(config.channel).split(' ')[0],
40
40
  };
41
41
 
42
42
  const payload = {
43
43
  acknowledge: true,
44
- state: {}
44
+ state: {},
45
45
  };
46
46
 
47
- this.idSubscription = this.ccu.subscribe(filter, message => {
47
+ this.idSubscription = this.ccu.subscribe(filter, (message) => {
48
48
  let change = false;
49
49
  switch (channelType) {
50
50
  case 'SHUTTER_CONTACT':
@@ -150,11 +150,15 @@ module.exports = function (RED) {
150
150
  if (keys.length > 0) {
151
151
  if (change) {
152
152
  this.debug(JSON.stringify(payload));
153
- this.status({fill: 'green', shape: 'ring', text: JSON.stringify(payload.state).replace(/^{/, '').replace(/}$/, '')});
154
- keys.forEach(key => {
153
+ this.status({
154
+ fill: 'green',
155
+ shape: 'ring',
156
+ text: JSON.stringify(payload.state).replace(/^{/, '').replace(/}$/, ''),
157
+ });
158
+ keys.forEach((key) => {
155
159
  const distinctPayload = {
156
160
  acknowledge: true,
157
- state: {}
161
+ state: {},
158
162
  };
159
163
  distinctPayload.state[key] = payload.state[key];
160
164
  this.send({payload: distinctPayload});
@@ -165,7 +169,7 @@ module.exports = function (RED) {
165
169
  }
166
170
  });
167
171
 
168
- this.on('input', message => {
172
+ this.on('input', (message) => {
169
173
  this.debug('alexa > ' + JSON.stringify(message));
170
174
 
171
175
  if (!this.iface) {
@@ -182,7 +186,12 @@ module.exports = function (RED) {
182
186
  case 'TurnOn':
183
187
  case 'TurnOff':
184
188
  if (channelType.startsWith('DIMMER')) {
185
- this.ccu.setValueQueued(this.iface, this.channel, 'LEVEL', message.payload === 'ON' ? 1 : 0);
189
+ this.ccu.setValueQueued(
190
+ this.iface,
191
+ this.channel,
192
+ 'LEVEL',
193
+ message.payload === 'ON' ? 1 : 0,
194
+ );
186
195
  } else {
187
196
  this.ccu.setValueQueued(this.iface, this.channel, 'STATE', message.payload === 'ON');
188
197
  }
@@ -200,7 +209,12 @@ module.exports = function (RED) {
200
209
 
201
210
  case 'AdjustBrightness':
202
211
  if (channelType.startsWith('DIMMER')) {
203
- this.ccu.setValueQueued(this.iface, this.channel, 'LEVEL', (this.values.brightness + message.payload) / 100);
212
+ this.ccu.setValueQueued(
213
+ this.iface,
214
+ this.channel,
215
+ 'LEVEL',
216
+ (this.values.brightness + message.payload) / 100,
217
+ );
204
218
  } else {
205
219
  this.ccu.setValueQueued(this.iface, this.channel, 'STATE', message.payload > 0);
206
220
  }
@@ -215,7 +229,12 @@ module.exports = function (RED) {
215
229
  break;
216
230
 
217
231
  case 'HEATING_CLIMATECONTROL_TRANSCEIVER':
218
- this.ccu.setValueQueued(this.iface, this.channel, 'SET_POINT_TEMPERATURE', message.payload);
232
+ this.ccu.setValueQueued(
233
+ this.iface,
234
+ this.channel,
235
+ 'SET_POINT_TEMPERATURE',
236
+ message.payload,
237
+ );
219
238
  break;
220
239
 
221
240
  default:
@@ -235,10 +254,10 @@ module.exports = function (RED) {
235
254
 
236
255
  break;
237
256
 
238
- // Todo case 'SetColor':
239
- // Todo case 'SetColorTemperature':
240
- // Todo case 'AdjustTargetTemperature':
241
- // todo case 'SetThermostatMode':
257
+ // Todo case 'SetColor':
258
+ // Todo case 'SetColorTemperature':
259
+ // Todo case 'AdjustTargetTemperature':
260
+ // todo case 'SetThermostatMode':
242
261
 
243
262
  default:
244
263
  this.warn('unknown command ' + message.command);
@@ -11,6 +11,8 @@
11
11
  virtEnabled: {value: true},
12
12
  bcwiEnabled: {value: false},
13
13
  cuxdEnabled: {value: false},
14
+ jackEnabled: {value: false},
15
+ jackPort: {value: 2121},
14
16
 
15
17
  regaPoll: {value: true},
16
18
  regaInterval: {value: 30},
@@ -80,6 +82,7 @@
80
82
  $('#node-config-input-virtEnabled').prop('checked', ccu.interfaces.VirtualDevices);
81
83
  $('#node-config-input-bcwiEnabled').prop('checked', ccu.interfaces['BidCos-Wired']);
82
84
  $('#node-config-input-cuxdEnabled').prop('checked', ccu.interfaces.CuXD);
85
+ $('#node-config-input-jackEnabled').prop('checked', ccu.interfaces['CCU-Jack']);
83
86
  }
84
87
  });
85
88
  },
@@ -116,6 +119,8 @@
116
119
  }
117
120
  });
118
121
 
122
+ // called from the inline onclick attribute of the authentication checkbox
123
+ // eslint-disable-next-line no-unused-vars
119
124
  function TLSSSL(){
120
125
  if (document.getElementById('node-config-input-authentication').checked && !document.getElementById('node-config-input-tls').checked){
121
126
  document.getElementById('node-config-input-tls').checked = true
@@ -168,7 +173,9 @@
168
173
  <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-bcwiEnabled"> BidCos-Wired</label><br>
169
174
  <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-iprfEnabled"> HmIP-RF</label><br>
170
175
  <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-virtEnabled"> VirtualDevices</label><br>
171
- <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-cuxdEnabled"> CUxD</label>
176
+ <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-cuxdEnabled"> CUxD</label><br>
177
+ <label class="ccu-checkbox"><input type="checkbox" id="node-config-input-jackEnabled"> CCU-Jack</label>
178
+ <input type="text" id="node-config-input-jackPort" style="width: 70px;" placeholder="2121">
172
179
  </div>
173
180
  </div>
174
181
  <div class="form-row">
@@ -254,6 +261,7 @@
254
261
  <li>HmIP-RF: Homematic-IP Funk</li>
255
262
  <li>VirtualDevices: Heizungsgruppen, in CCU eingebundene Systeme wie Osram Lightify</li>
256
263
  <li>CUxD</li>
264
+ <li>CCU-Jack: XMLRPC-Schnittstelle des <a href="https://github.com/mdzio/ccu-jack" target="_blank">CCU-Jack</a> Addons (Port konfigurierbar, Standard 2121 bzw. 2122 mit TLS)</li>
257
265
  </ul>
258
266
 
259
267
  </li>