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.
- package/.prettierignore +10 -0
- package/.prettierrc +14 -0
- package/AGENTS.md +96 -0
- package/CHANGELOG.md +66 -0
- package/README.md +17 -21
- package/ROADMAP.md +402 -0
- package/eslint.config.js +45 -0
- package/examples/rpc-events.json +65 -0
- package/examples/switch-datapoint.json +86 -0
- package/examples/system-variable.json +60 -0
- package/nodes/ccu-alexa.html +12 -7
- package/nodes/ccu-alexa.js +33 -14
- package/nodes/ccu-connection.html +9 -1
- package/nodes/ccu-connection.js +588 -335
- package/nodes/ccu-display.html +11 -4
- package/nodes/ccu-display.js +26 -9
- package/nodes/ccu-get-value.html +13 -4
- package/nodes/ccu-get-value.js +2 -2
- package/nodes/ccu-mqtt.html +9 -10
- package/nodes/ccu-mqtt.js +55 -29
- package/nodes/ccu-program.html +1 -1
- package/nodes/ccu-program.js +9 -7
- package/nodes/ccu-rpc-event.html +12 -7
- package/nodes/ccu-rpc-event.js +4 -5
- package/nodes/ccu-rpc.html +12 -5
- package/nodes/ccu-rpc.js +8 -6
- package/nodes/ccu-script.html +1 -1
- package/nodes/ccu-script.js +4 -3
- package/nodes/ccu-set-value.html +11 -7
- package/nodes/ccu-set-value.js +40 -16
- package/nodes/ccu-signal.html +11 -5
- package/nodes/ccu-signal.js +34 -23
- package/nodes/ccu-switch.html +13 -5
- package/nodes/ccu-sysvar.html +1 -1
- package/nodes/ccu-sysvar.js +11 -7
- package/nodes/ccu-value.html +12 -7
- package/nodes/ccu-value.js +36 -13
- package/nodes/lib/base62.js +22 -0
- package/nodes/lib/discover.js +127 -0
- package/nodes/lib/nextport.js +30 -0
- package/nodes/lib/similarity.js +51 -0
- package/nodes/lib/status.js +1 -1
- package/package.json +105 -155
- package/roadmap-archive/README.md +20 -0
- package/roadmap-archive/phase-1.md +48 -0
- package/roadmap-archive/todo-history.md +39 -0
- package/TODO.md +0 -41
- package/ccu_rega_localhost.json +0 -1
- 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
|
+
]
|
package/nodes/ccu-alexa.html
CHANGED
|
@@ -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-
|
|
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>
|
package/nodes/ccu-alexa.js
CHANGED
|
@@ -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({
|
|
154
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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>
|