node-red-contrib-knx-ultimate 2.4.8 → 2.4.10
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 +7 -1
- package/KNXEngine/src/dptlib/dpt238.js +13 -3
- package/README.md +2 -0
- package/nodes/hue-config.html +1 -1
- package/nodes/icons/node-ha-icon.svg +5 -0
- package/nodes/knxUltimate-config.html +1 -1
- package/nodes/knxUltimate-config.js +1 -1
- package/nodes/knxUltimate.html +60 -33
- package/nodes/knxUltimate.js +3 -3
- package/nodes/knxUltimateGarageDoorBarrierOpener.html +1 -1
- package/nodes/knxUltimateGlobalContext.js +2 -2
- package/nodes/knxUltimateHATranslator.html +74 -0
- package/nodes/knxUltimateHATranslator.js +83 -0
- package/nodes/knxUltimateHueBattery.html +1 -1
- package/nodes/knxUltimateHueBattery.js +2 -2
- package/nodes/knxUltimateHueButton.html +1 -1
- package/nodes/knxUltimateHueButton.js +2 -2
- package/nodes/knxUltimateHueLight.html +1 -1
- package/nodes/knxUltimateHueLight.js +22 -12
- package/nodes/knxUltimateHueLightSensor.html +1 -1
- package/nodes/knxUltimateHueLightSensor.js +2 -2
- package/nodes/knxUltimateHueMotion.html +1 -1
- package/nodes/knxUltimateHueMotion.js +2 -2
- package/nodes/knxUltimateHueScene.html +1 -1
- package/nodes/knxUltimateHueScene.js +2 -2
- package/nodes/knxUltimateHueTapDial.html +1 -1
- package/nodes/knxUltimateHueTapDial.js +2 -2
- package/nodes/knxUltimateHueTemperatureSensor.html +1 -1
- package/nodes/knxUltimateHueTemperatureSensor.js +2 -2
- package/nodes/knxUltimateHueZigbeeConnectivity.html +1 -1
- package/nodes/knxUltimateHueZigbeeConnectivity.js +2 -2
- package/nodes/knxUltimateLoadControl.html +1 -1
- package/nodes/knxUltimateLogger.js +5 -5
- package/nodes/knxUltimateViewer.html +1 -1
- package/nodes/knxUltimateViewer.js +2 -2
- package/nodes/knxUltimateWatchDog.js +4 -4
- package/nodes/utils/utils.js +57 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
-
**Version 2.4.
|
|
9
|
+
**Version 2.4.10** - March 2024<br/>
|
|
10
|
+
- Warning: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
|
|
11
|
+
- NEW: Home Assistant translator node: translates the HA input msg, to a KNX value. Comes with a built.in translation table, that's user editable.<br/>
|
|
12
|
+
- Updated KNX-Ultimate device node help.<br/>
|
|
13
|
+
- Minor KNX-Ultimate device node UI changes.<br/>
|
|
14
|
+
|
|
15
|
+
**Version 2.4.9** - March 2024<br/>
|
|
10
16
|
- WARNING: this version uses the Node-Red plugin system; the Node-Red version must be **equals or major than 3.1.1**<br/>
|
|
11
17
|
- Fixed [this](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/338).<br/>
|
|
12
18
|
|
|
@@ -29,12 +29,22 @@ exports.basetype = {
|
|
|
29
29
|
bitlength: 8,
|
|
30
30
|
range: [,],
|
|
31
31
|
valuetype: 'basic',
|
|
32
|
-
desc: '1-byte'
|
|
32
|
+
desc: '1-byte',
|
|
33
|
+
help:
|
|
34
|
+
`// Datapoint for 1 byte.
|
|
35
|
+
// For example, for DPT 238.102, HVAC Mode, the values are as following:
|
|
36
|
+
// 0-Auto
|
|
37
|
+
// 1-Heat
|
|
38
|
+
// 3-Cool
|
|
39
|
+
// 9-Fan
|
|
40
|
+
// 14-Dry
|
|
41
|
+
msg.payload = 0; // Auto
|
|
42
|
+
return msg;`
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
exports.subtypes = {
|
|
36
|
-
//
|
|
37
|
-
102: {
|
|
46
|
+
// .102 HVAC mode
|
|
47
|
+
'102': {
|
|
38
48
|
name: 'HVAC_Mode',
|
|
39
49
|
desc: '',
|
|
40
50
|
unit: '',
|
package/README.md
CHANGED
|
@@ -38,6 +38,8 @@ msg.payload = {red:255, green:200, blue:30} // Put some colors in our life
|
|
|
38
38
|
* **LOAD CONTROL node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/LoadControl-Configuration). Control your loads (Oven, Washing machine, etc..) and avoit shutting down the main voltage due to too high power consumption.
|
|
39
39
|
* **VIEWER node** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/knxUltimateViewer). View all Group Addresses and values of your KNX BUS, in the Node-Red Dashboard.
|
|
40
40
|
* **PHILIPS HUE nodeset** [here](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/en-hue-configuration). Link HUE devices to KNX in a simple way.
|
|
41
|
+
* **Homeassistant translator node** translates the HA input msg, to a KNX value. Comes with a built.in translation table, that's user editable.
|
|
42
|
+
|
|
41
43
|
|
|
42
44
|
<br>
|
|
43
45
|
<br>
|
package/nodes/hue-config.html
CHANGED
|
@@ -150,6 +150,6 @@
|
|
|
150
150
|
|
|
151
151
|
</script>
|
|
152
152
|
<script type="text/markdown" data-help-name="hue-config" This node registers to the Hue Bridge. Just set the Bridge's IP
|
|
153
|
-
and click **CONNECT** button. [
|
|
153
|
+
and click **CONNECT** button. [DONATE HERE, THANK YOU!](https://www.paypal.me/techtoday) <br />
|
|
154
154
|
|
|
155
155
|
</script>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- Generated by Pixelmator Pro 3.5.7 -->
|
|
3
|
+
<svg width="40" height="40" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
4
|
+
<image id="Livello-immagine" x="8" y="8" width="24" height="24" xlink:href="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAGKADAAQAAAABAAAAGAAAAADiNXWtAAACn0lEQVRIDZ2Uy2sTURSHMzHioygWrRWitAXbpoiKIIKu6saVWVhs3EYXXZkKrgrd5J9wEXDlCwpSEF1YfEQtQSi4KIoiqAsXQtMWH9UhadXx+w33hsm0mcQc+HLOPfc85p65k1isRfE8rx+mDP0tprUU5lB0CIrw1/AMPUS201KFqCAKpeAB/AErsuVLReU23aOAxvIEgsVZ+iLfU2hvXJVK5SDJc6CxNBLtzSm26dMGAjTzAXgEweKrrMsG2VYUo9gBajR/J+bJp0n4bSugK3DTdddOosUt40P5onFNNz0JQb3wEILFWXrv4ZQ9pWzjQ9VEOcrttXHScbt4++lLD/ZtOAObrN/oVXQ14JMtX1CUo9w7plZtTzPvg/BVxFWTKlY+m81uFbIh+B5qgRgal2r10cGJlcs/97HQFxoeC646WVhy3aTAu1C3s36hWlOqnejq6rhEpxEIj6V2RGPEuSL2ltRGGw4ya9Uaofa8AscgYTbaUe9IOmeQbUU1x/Sjl9uueCRecBzntQowlo+oebAn7Wl2VOVFyTeKv7EBmUzmA/aaXft6/fvxfuG7Z5BtZXHZdfcLHIuwAhMU8Z+2UChsZn0Z6kTHCkuOq7hLsDEe2Aw2+Ix/srv7SIdpeIP1LHwPxPtmuEFVT2KPmM/nE0TpG5D4DWZKpb3YE3sGB3dQ/AD2K202knAD3d/DtgE6zvqlSfYbyJdOp7fjOwYls9dQhRso8DlchNO5XG4L+ji8ANtAX/5ReAx6oEjZqIH+fn/AElwxpziBPaN5J5Op3dgtFSfO26iB/FbUbFz/PyvV6qHR0dFtgVtkYyK1GujKRYmu41XGtVPv5j8blDVP/Q+dh04VaCDL+K/zUc3eLxY7zw4PX2PtN2wQL/dXuPsP3FmfJDlKUiMAAAAASUVORK5CYII="/>
|
|
5
|
+
</svg>
|
|
@@ -1379,7 +1379,7 @@ module.exports = (RED) => {
|
|
|
1379
1379
|
|
|
1380
1380
|
// 14/08/2019 If the node has payload same as the received telegram, return false
|
|
1381
1381
|
function checkRBEInputFromKNXBusAllowSend(_node, _KNXTelegramPayload) {
|
|
1382
|
-
if (_node.inputRBE !== true) return true;
|
|
1382
|
+
if (_node.inputRBE !== "true") return true;
|
|
1383
1383
|
|
|
1384
1384
|
return !_.isEqual(_node.currentPayload, _KNXTelegramPayload);
|
|
1385
1385
|
}
|
package/nodes/knxUltimate.html
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
<!-- <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/jquery.searchableSelect.js"></script> -->
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
<script type="text/javascript">
|
|
2
5
|
RED.nodes.registerType('knxUltimate', {
|
|
3
6
|
category: "KNX Ultimate",
|
|
@@ -17,8 +20,8 @@
|
|
|
17
20
|
listenallga: { value: false },
|
|
18
21
|
name: { value: "" },
|
|
19
22
|
outputtype: { value: "write" },
|
|
20
|
-
outputRBE: { value: true },
|
|
21
|
-
inputRBE: { value: false },
|
|
23
|
+
outputRBE: { value: "true" },
|
|
24
|
+
inputRBE: { value: "false" },
|
|
22
25
|
formatmultiplyvalue: { value: 1 },
|
|
23
26
|
formatnegativevalue: { value: "leave" },
|
|
24
27
|
formatdecimalsvalue: { value: 999 },
|
|
@@ -28,7 +31,7 @@
|
|
|
28
31
|
outputs: 1,
|
|
29
32
|
icon: "node-knx-icon.svg",
|
|
30
33
|
label: function () {
|
|
31
|
-
return (this.outputRBE
|
|
34
|
+
return (this.outputRBE === "true" ? "|rbe| " : "") + (this.name || this.topic || "KNX Device") + (this.inputRBE === "true" ? " |rbe|" : "")
|
|
32
35
|
},
|
|
33
36
|
paletteLabel: "KNX DEVICE",
|
|
34
37
|
// button: {
|
|
@@ -49,7 +52,6 @@
|
|
|
49
52
|
var node = this;
|
|
50
53
|
var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node
|
|
51
54
|
$("#tabs").tabs();
|
|
52
|
-
|
|
53
55
|
// 31/03/2020 Search Helper
|
|
54
56
|
function fullSearch(sourceText, searchString) {
|
|
55
57
|
// This searches for all words in a string
|
|
@@ -161,9 +163,9 @@
|
|
|
161
163
|
if ($("#node-input-listenallga").is(":checked")) {
|
|
162
164
|
$("#GAandDPT").hide()
|
|
163
165
|
$("#divOutputRBE").hide()
|
|
164
|
-
$("#node-input-outputRBE").
|
|
166
|
+
$("#node-input-outputRBE").val("false")
|
|
165
167
|
$("#divInputRBE").hide()
|
|
166
|
-
$("#node-input-inputRBE").
|
|
168
|
+
$("#node-input-inputRBE").val("false")
|
|
167
169
|
$("#divnotifyreadrequestautoreact").hide();
|
|
168
170
|
$("#helpallga").show();
|
|
169
171
|
$("#divTopic").hide()
|
|
@@ -386,6 +388,17 @@
|
|
|
386
388
|
</label>
|
|
387
389
|
<input type="text" id="node-input-outputtopic" data-i18n="[placeholder]knxUltimate.placeholder.leaveempty" />
|
|
388
390
|
</div>
|
|
391
|
+
<div class="form-row">
|
|
392
|
+
<label for="node-input-passthrough">
|
|
393
|
+
<i class="fa fa-long-arrow-right"></i> Passthrough
|
|
394
|
+
</label>
|
|
395
|
+
<select id="node-input-passthrough">
|
|
396
|
+
<option value="no">No</option>
|
|
397
|
+
<option value="yes">Yes, pass the input msg to the output msg</option>
|
|
398
|
+
<option value="yesownprop">Yes, but put the input msg into msg.inputmessage property of the output msg
|
|
399
|
+
</option>
|
|
400
|
+
</select>
|
|
401
|
+
</div>
|
|
389
402
|
<div class="form-row">
|
|
390
403
|
<input type="checkbox" id="node-input-listenallga"
|
|
391
404
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
@@ -406,16 +419,6 @@
|
|
|
406
419
|
</ul>
|
|
407
420
|
<div id="tabs-1">
|
|
408
421
|
<div class="form-row" style="padding:10px">
|
|
409
|
-
<div class="form-row">
|
|
410
|
-
<label style="width:180px" for="node-input-passthrough">
|
|
411
|
-
<i class="fa fa-long-arrow-right"></i> Msg passthrough
|
|
412
|
-
</label>
|
|
413
|
-
<select id="node-input-passthrough">
|
|
414
|
-
<option value="no" data-i18n="knxUltimate.selectlists.passthrough_No"></option>
|
|
415
|
-
<option value="yes" data-i18n="knxUltimate.selectlists.passthrough_Leave"></option>
|
|
416
|
-
<option value="yesownprop" data-i18n="knxUltimate.selectlists.passthrough_OwnProp"></option>
|
|
417
|
-
</select>
|
|
418
|
-
</div>
|
|
419
422
|
<div class="form-row">
|
|
420
423
|
<dt>
|
|
421
424
|
<i class="fa fa-arrow-right"></i> CONTROL (payload to KNX bus)
|
|
@@ -433,11 +436,13 @@
|
|
|
433
436
|
</select>
|
|
434
437
|
</div>
|
|
435
438
|
<div class="form-row" id="divOutputRBE">
|
|
436
|
-
<
|
|
437
|
-
|
|
438
|
-
<label style="width:85%" for="node-input-outputRBE">
|
|
439
|
-
<i class="fa fa-filter"></i> Send payload to KNX only if changed (RBE filter)
|
|
439
|
+
<label style="width:180px" for="node-input-outputRBE">
|
|
440
|
+
<i class="fa fa-filter"></i> RBE filter
|
|
440
441
|
</label>
|
|
442
|
+
<select id="node-input-outputRBE">
|
|
443
|
+
<option value="true">Enable (send the payload to KNX only if changed)</option>
|
|
444
|
+
<option value="false">Disable</option>
|
|
445
|
+
</select>
|
|
441
446
|
</div>
|
|
442
447
|
<br />
|
|
443
448
|
<div class="form-row">
|
|
@@ -458,11 +463,13 @@
|
|
|
458
463
|
|
|
459
464
|
</div>
|
|
460
465
|
<div class="form-row" id="divInputRBE">
|
|
461
|
-
<
|
|
462
|
-
|
|
463
|
-
<label style="width:85%" for="node-input-inputRBE">
|
|
464
|
-
<i class="fa fa-filter"></i> React only by changed payload (RBE filter)
|
|
466
|
+
<label style="width:180px" for="node-input-inputRBE">
|
|
467
|
+
<i class="fa fa-filter"></i> RBE filter
|
|
465
468
|
</label>
|
|
469
|
+
<select id="node-input-inputRBE">
|
|
470
|
+
<option value="true">Enable (react only if payload changes)</option>
|
|
471
|
+
<option value="false">Disable</option>
|
|
472
|
+
</select>
|
|
466
473
|
</div>
|
|
467
474
|
<div class="form-row">
|
|
468
475
|
<input type="checkbox" id="node-input-notifywrite"
|
|
@@ -581,9 +588,11 @@
|
|
|
581
588
|
<br /><br />
|
|
582
589
|
</script>
|
|
583
590
|
<script type="text/markdown" data-help-name="knxUltimate">
|
|
584
|
-
<p>This node lets you control a KNX Group Address, this is the most used node.
|
|
591
|
+
<p>This node lets you control a KNX Group Address, this is the most used node.
|
|
592
|
+
|
|
593
|
+
[<i class="fa fa-code"></i> Here you'll find some samples](https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-SamplesHome)
|
|
585
594
|
|
|
586
|
-
**
|
|
595
|
+
**Configuration**
|
|
587
596
|
|Property|Description|
|
|
588
597
|
|--|--|
|
|
589
598
|
| Gateway | Select the KNX gateway to be used |
|
|
@@ -591,17 +600,35 @@
|
|
|
591
600
|
| Datapoint | The datapoint belonging to your node.|
|
|
592
601
|
| Node name | Self explaining. |
|
|
593
602
|
| Topic | The msg output topic. Leave it blank to have it set to your Group Address. |
|
|
603
|
+
| Passthrough | If set, you can pass the input mgs to the output msg. |
|
|
594
604
|
| Universal mode (listen to all Group Addresses) | By setting this, the node will read and control ALL group addresses. |
|
|
595
|
-
|
|
596
|
-
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
**Advanced options**
|
|
608
|
+
|Property|Description|
|
|
609
|
+
|--|--|
|
|
610
|
+
||**CONTROL (payload to KNX bus)**|
|
|
597
611
|
| Telegram type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
|
|
598
|
-
|
|
|
612
|
+
| RBE filter (in the CONTROL section) | *Report by change* filter. If set, only the msg input (from the Flow) having different values each time, will be sent to the KNX bus. If you intend to send everytime the same value, turn it off. |
|
|
613
|
+
||**STATUS (payload from KNX BUS)**|
|
|
599
614
|
| Read status on start | Read group address status, every time Node-Red starts and at every reconnection to the KNX Gateway. The node stores all group address values to a file, so you can choose wether to read from file or from the KNX bus. |
|
|
600
|
-
|
|
|
615
|
+
| RBE filter (in the STATUS section)| *Report by change* filter. If set, only the msg output (to KNX bus) having different values each time, will be sent to the msg output's flow. If you intend to send everytime the same value, leave it off. |
|
|
601
616
|
| React to write telegrams | The node will react (will send a msg to the flow) each time it receives a *write* telegram from the KNX bus. Usually, you want that. |
|
|
602
617
|
| React to response telegrams | The node will react (will send a msg to the flow) each time it receives a *response* telegram from the KNX bus. Usually, you want that for particular scenarios. |
|
|
603
618
|
| React to read telegrams | The node will react (will send a msg to the flow) each time it receives a *read* telegram from the KNX bus. Usually, you want that if you're want to send a custom value to the KNX BUS. |
|
|
604
|
-
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
**Format input**
|
|
622
|
+
|Property|Description|
|
|
623
|
+
|--|--|
|
|
624
|
+
| Multiply | Multiplies or divides the payload value |
|
|
625
|
+
| Decimals | Round or handle decimals in any way |
|
|
626
|
+
| Negatives | Handles the negative values |
|
|
627
|
+
|
|
628
|
+
**Payload sample**
|
|
629
|
+
|Property|Description|
|
|
630
|
+
|--|--|
|
|
631
|
+
| Sample | This will give it a hint on what to write in a function, if you want to control the node via a Node-Red function node. |
|
|
605
632
|
|
|
606
633
|
<br/>
|
|
607
634
|
|
|
@@ -669,9 +696,9 @@ msg = {
|
|
|
669
696
|
}
|
|
670
697
|
````
|
|
671
698
|
|
|
672
|
-
<br
|
|
699
|
+
<br/>
|
|
673
700
|
|
|
674
|
-
[
|
|
701
|
+
[DONATE HERE, THANK YOU!](https://www.paypal.me/techtoday)
|
|
675
702
|
|
|
676
703
|
|
|
677
704
|
|
package/nodes/knxUltimate.js
CHANGED
|
@@ -26,8 +26,8 @@ module.exports = function (RED) {
|
|
|
26
26
|
node.initialread = Number(config.initialread);
|
|
27
27
|
node.listenallga = config.listenallga || false;
|
|
28
28
|
node.outputtype = config.outputtype || 'write';// When the node is used as output
|
|
29
|
-
node.outputRBE = config.outputRBE || false; // Apply or not RBE to the output (Messages coming from flow)
|
|
30
|
-
node.inputRBE = config.inputRBE || false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
29
|
+
node.outputRBE = config.outputRBE || 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
30
|
+
node.inputRBE = config.inputRBE || 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
31
31
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
32
32
|
node.icountMessageInWindow = 0; // Used to prevent looping messages
|
|
33
33
|
node.messageQueue = []; // 01/01/2020 All messages from the flow to the node, will be queued and will be sent separated by 60 milliseconds each. Use uf the underlying api "minimumDelay" is not possible because the telegram order isn't mantained.
|
|
@@ -234,7 +234,7 @@ module.exports = function (RED) {
|
|
|
234
234
|
} else {
|
|
235
235
|
if (node.listenallga == false) {
|
|
236
236
|
// 23/12/2020 Applying RBE filter
|
|
237
|
-
if (node.outputRBE
|
|
237
|
+
if (node.outputRBE === "true") {
|
|
238
238
|
// 19/01/2023 CHECKING THE INPUT PAYLOAD (ROUND, ETC) BASED ON THE NODE CONFIG
|
|
239
239
|
//* ********************************************************
|
|
240
240
|
const pTest = payloadRounder.Manipulate(node, msg.payload);
|
|
@@ -314,7 +314,7 @@ msg = {
|
|
|
314
314
|
|
|
315
315
|
<br/><a href="https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-SamplesHome" target="_blank"><i class="fa fa-code"></i> Samples</a>
|
|
316
316
|
|
|
317
|
-
[
|
|
317
|
+
[DONATE HERE, THANK YOU!](https://www.paypal.me/techtoday)
|
|
318
318
|
|
|
319
319
|
|
|
320
320
|
|
|
@@ -42,8 +42,8 @@ module.exports = function (RED) {
|
|
|
42
42
|
node.initialread = false
|
|
43
43
|
node.listenallga = true
|
|
44
44
|
node.outputtype = 'write'
|
|
45
|
-
node.outputRBE = false // Apply or not RBE to the output (Messages coming from flow)
|
|
46
|
-
node.inputRBE = false // Apply or not RBE to the input (Messages coming from BUS)
|
|
45
|
+
node.outputRBE = 'false' // Apply or not RBE to the output (Messages coming from flow)
|
|
46
|
+
node.inputRBE = 'false' // Apply or not RBE to the input (Messages coming from BUS)
|
|
47
47
|
node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
|
|
48
48
|
node.passthrough = 'no'
|
|
49
49
|
node.formatmultiplyvalue = 1
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('knxUltimateHATranslator', {
|
|
3
|
+
category: 'KNX Ultimate',
|
|
4
|
+
defaults: {
|
|
5
|
+
name: { value: "" },
|
|
6
|
+
payloadPropName: { value: "payload", required: false },
|
|
7
|
+
commandText: { value: 'on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false', required: false }
|
|
8
|
+
},
|
|
9
|
+
inputs: 1,
|
|
10
|
+
outputs: 1,
|
|
11
|
+
icon: "node-ha-icon.svg",
|
|
12
|
+
label: function () {
|
|
13
|
+
return (this.name || 'HA Translator');
|
|
14
|
+
},
|
|
15
|
+
color: '#AED6F1',
|
|
16
|
+
paletteLabel: "Homeassistant translator",
|
|
17
|
+
oneditprepare: function () {
|
|
18
|
+
var node = this;
|
|
19
|
+
node.editor = RED.editor.createEditor({
|
|
20
|
+
id: 'node-input-editorcommandText',
|
|
21
|
+
mode: 'ace/mode/text',
|
|
22
|
+
value: node.commandText
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
oneditsave: function () {
|
|
26
|
+
var node = this;
|
|
27
|
+
node.commandText = node.editor.getValue();
|
|
28
|
+
node.editor.destroy();
|
|
29
|
+
delete node.editor;
|
|
30
|
+
},
|
|
31
|
+
oneditcancel: function () {
|
|
32
|
+
var node = this;
|
|
33
|
+
node.editor.destroy();
|
|
34
|
+
delete node.editor;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<script type="text/html" data-template-name="knxUltimateHATranslator">
|
|
40
|
+
<div class="form-row">
|
|
41
|
+
<label for="node-config-input-name">
|
|
42
|
+
<i class="fa fa-tag"></i> Name
|
|
43
|
+
</label>
|
|
44
|
+
<input type="text" id="node-config-input-name">
|
|
45
|
+
</div>
|
|
46
|
+
<div class="form-row">
|
|
47
|
+
<label for="node-input-payloadPropName"><i class="fa fa-ellipsis-h"></i> Input</label>
|
|
48
|
+
<input type="text" id="node-input-payloadPropName">
|
|
49
|
+
</div>
|
|
50
|
+
<div class="form-row">
|
|
51
|
+
<label style="width:300px;" for="node-input-commandText"><i class="fa fa-tasks"></i> Translate (Homassistant:KNX)</label>
|
|
52
|
+
<div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-editorcommandText"></div>
|
|
53
|
+
</div>
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<script type="text/markdown" data-help-name="knxUltimateHATranslator">
|
|
57
|
+
<p>This node translates the input msg to valid true/false values.<p>
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
It can translate an input payload, to a true/false boolean values.<br />
|
|
61
|
+
Each row in the text box, represents a translation command. <br/>
|
|
62
|
+
You can add your own translation row.<br/>
|
|
63
|
+
|
|
64
|
+
|Property|Description|
|
|
65
|
+
|--|--|
|
|
66
|
+
| Name | The node name. |
|
|
67
|
+
| Input | The input msg property to be evaluated and translated. |
|
|
68
|
+
| Translate | Add, delete or edit your own translation command. The row's translation command must be **input string from HA:KNX value** (*KNX value* as true or false). For example: <code>open:true</code> <code>closed:false</code>. |
|
|
69
|
+
|
|
70
|
+
<br/>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
[Find it useful?](https://www.paypal.me/techtoday)
|
|
74
|
+
</script>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* eslint-disable prefer-arrow-callback */
|
|
2
|
+
module.exports = function (RED) {
|
|
3
|
+
function knxUltimateHATranslator(config) {
|
|
4
|
+
RED.nodes.createNode(this, config);
|
|
5
|
+
this.config = config;
|
|
6
|
+
var node = this;
|
|
7
|
+
|
|
8
|
+
function setNodeStatus({ fill, shape, text }) {
|
|
9
|
+
let dDate = new Date();
|
|
10
|
+
node.status({
|
|
11
|
+
fill: fill,
|
|
12
|
+
shape: shape,
|
|
13
|
+
text:
|
|
14
|
+
text +
|
|
15
|
+
" (" +
|
|
16
|
+
dDate.getDate() +
|
|
17
|
+
", " +
|
|
18
|
+
dDate.toLocaleTimeString() +
|
|
19
|
+
")",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setNodeStatus({ fill: "grey", shape: "dot", text: "Waiting" });
|
|
24
|
+
|
|
25
|
+
this.on("input", function (msg) {
|
|
26
|
+
// 11/11/2021 Clone input message and replace only relevant topics
|
|
27
|
+
const utils = require("./utils/utils.js");
|
|
28
|
+
let sPayload = utils.fetchFromObject(
|
|
29
|
+
msg,
|
|
30
|
+
config.payloadPropName || "payload"
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// 15/11/2021 inform user about undefined topic or payload
|
|
34
|
+
if (sPayload === undefined) {
|
|
35
|
+
setNodeStatus({
|
|
36
|
+
fill: "red",
|
|
37
|
+
shape: "dot",
|
|
38
|
+
text: "Received invalid payload from " + msg.topic || "",
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var bRes = null;
|
|
44
|
+
try {
|
|
45
|
+
bRes = utils.ToBoolean(
|
|
46
|
+
sPayload,
|
|
47
|
+
RED.nodes.getNode(config.translatorConfig) // Retrieve the config node. It can be null, but it's handled in utils.js; // 15/11/2021 Convert input to boolean.);
|
|
48
|
+
);
|
|
49
|
+
} catch (error) { }
|
|
50
|
+
if (bRes === undefined || bRes === null) {
|
|
51
|
+
setNodeStatus({
|
|
52
|
+
fill: "red",
|
|
53
|
+
shape: "dot",
|
|
54
|
+
text:
|
|
55
|
+
"Received non convertible boolean value " +
|
|
56
|
+
sPayload +
|
|
57
|
+
" from " +
|
|
58
|
+
msg.topic,
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var msgOUt = RED.util.cloneMessage(msg);
|
|
64
|
+
try {
|
|
65
|
+
msgOUt.payload = bRes;
|
|
66
|
+
setNodeStatus({
|
|
67
|
+
fill: "green",
|
|
68
|
+
shape: "dot",
|
|
69
|
+
text: "(Send) " + msgOUt.payload,
|
|
70
|
+
});
|
|
71
|
+
node.send(msgOUt);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
setNodeStatus({
|
|
74
|
+
fill: "red",
|
|
75
|
+
shape: "dot",
|
|
76
|
+
text: "Unable to invert the input payload " + bRes,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
RED.nodes.registerType("knxUltimateHATranslator", knxUltimateHATranslator);
|
|
83
|
+
};
|
|
@@ -15,8 +15,8 @@ module.exports = function (RED) {
|
|
|
15
15
|
node.initialread = true;
|
|
16
16
|
node.listenallga = true; // Don't remove
|
|
17
17
|
node.outputtype = 'write';
|
|
18
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
18
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
20
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
21
21
|
node.passthrough = 'no';
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
@@ -17,8 +17,8 @@ module.exports = function (RED) {
|
|
|
17
17
|
node.initialread = true;
|
|
18
18
|
node.listenallga = true; // Don't remove
|
|
19
19
|
node.outputtype = 'write';
|
|
20
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
21
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
21
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
22
22
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
23
23
|
node.passthrough = 'no';
|
|
24
24
|
node.formatmultiplyvalue = 1;
|
|
@@ -1539,7 +1539,7 @@ The Dimming function works in **KNX mode `start` and `stop`**. To start dimming,
|
|
|
1539
1539
|
|
|
1540
1540
|
<br/>
|
|
1541
1541
|
|
|
1542
|
-
[
|
|
1542
|
+
[DONATE HERE, THANK YOU!](https://www.paypal.me/techtoday)
|
|
1543
1543
|
|
|
1544
1544
|
<br/>
|
|
1545
1545
|
</script>
|
|
@@ -40,8 +40,8 @@ module.exports = function (RED) {
|
|
|
40
40
|
node.initialread = true;
|
|
41
41
|
node.listenallga = true; // Don't remove
|
|
42
42
|
node.outputtype = "write";
|
|
43
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
44
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
43
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
44
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
45
45
|
node.currentPayload = ""; // Current value for the RBE input and for the .previouspayload msg
|
|
46
46
|
node.passthrough = "no";
|
|
47
47
|
node.formatmultiplyvalue = 1;
|
|
@@ -209,9 +209,10 @@ module.exports = function (RED) {
|
|
|
209
209
|
const dretXY = hueColorConverter.ColorConverter.calculateXYFromRGB(colorChoosen.red, colorChoosen.green, colorChoosen.blue, gamut);
|
|
210
210
|
const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(colorChoosen.red, colorChoosen.green, colorChoosen.blue);
|
|
211
211
|
node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0);
|
|
212
|
+
if (node.currentHUEDevice.color !== undefined) node.currentHUEDevice.color.xy = dretXY; // 26/03/2024
|
|
212
213
|
node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
|
|
213
214
|
state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } };
|
|
214
|
-
//state = { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } };
|
|
215
|
+
// state = { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } };
|
|
215
216
|
} else if (temperatureChoosen !== undefined) {
|
|
216
217
|
// Kelvin
|
|
217
218
|
const mirek = hueColorConverter.ColorConverter.kelvinToMirek(temperatureChoosen);
|
|
@@ -220,10 +221,10 @@ module.exports = function (RED) {
|
|
|
220
221
|
node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness);
|
|
221
222
|
// Kelvin temp
|
|
222
223
|
state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } } : { on: { on: false } };
|
|
223
|
-
//state = { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } };
|
|
224
|
+
// state = { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } };
|
|
224
225
|
} else if (brightnessChoosen !== undefined) {
|
|
225
226
|
state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen } } : { on: { on: false } };
|
|
226
|
-
//state = { on: { on: true }, dimming: { brightness: brightnessChoosen } };
|
|
227
|
+
// state = { on: { on: true }, dimming: { brightness: brightnessChoosen } };
|
|
227
228
|
} else {
|
|
228
229
|
state = { on: { on: true } };
|
|
229
230
|
}
|
|
@@ -307,7 +308,7 @@ module.exports = function (RED) {
|
|
|
307
308
|
try {
|
|
308
309
|
const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice);
|
|
309
310
|
node.HUELightsBelongingToGroupWhileDaytime = cloneDeep(retLights); // DayTime has switched to false: save the lights belonging to the group into the HUELightsBelongingToGroupWhileDaytime array
|
|
310
|
-
} catch (error) { }
|
|
311
|
+
} catch (error) { /* empty */ }
|
|
311
312
|
})();
|
|
312
313
|
}
|
|
313
314
|
}
|
|
@@ -530,6 +531,7 @@ module.exports = function (RED) {
|
|
|
530
531
|
try {
|
|
531
532
|
let hueTelegram = {};
|
|
532
533
|
let numStep = 10; // Steps from 0 to 100 by 10
|
|
534
|
+
const extendedConf = {};
|
|
533
535
|
|
|
534
536
|
if (_KNXbrightness_Direction === 0 && _KNXaction === 0) {
|
|
535
537
|
// STOP DIM
|
|
@@ -539,6 +541,12 @@ module.exports = function (RED) {
|
|
|
539
541
|
return;
|
|
540
542
|
}
|
|
541
543
|
|
|
544
|
+
// 26/03/2024 set the extended configuration as well, because the light was off (so i've been unable to set it up elsewhere)
|
|
545
|
+
if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
|
|
546
|
+
// if (node.currentHUEDevice.color !== undefined) extendedConf.color = { xy: node.currentHUEDevice.color.xy }; // DO NOT ADD THE COLOR, BECAUSE THE COLOR HAS ALSO THE BRIGHTNESS, SO ALL THE DATA NEEDED TO BE SWITCHED ON CORRECLY
|
|
547
|
+
if (node.currentHUEDevice.color_temperature !== undefined) extendedConf.color_temperature = { mirek: node.currentHUEDevice.color_temperature.mirek };
|
|
548
|
+
}
|
|
549
|
+
|
|
542
550
|
// If i'm dimming up while the light is off, start the dim with the initial brightness set to zero
|
|
543
551
|
if (_KNXbrightness_Direction > 0 && _KNXaction === 1 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
|
|
544
552
|
node.brightnessStep = null;
|
|
@@ -575,7 +583,9 @@ module.exports = function (RED) {
|
|
|
575
583
|
// Switch on the light if off
|
|
576
584
|
if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
|
|
577
585
|
hueTelegram.on = { on: true };
|
|
586
|
+
Object.assign(hueTelegram, extendedConf); // 26/03/2024 add extended conf
|
|
578
587
|
}
|
|
588
|
+
//console.log(hueTelegram)
|
|
579
589
|
node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, hueTelegram, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
|
|
580
590
|
if (node.brightnessStep >= maxDimLevelLight) clearInterval(node.timerStepDim);
|
|
581
591
|
}, _dimSpeedInMillisecs);
|
|
@@ -851,7 +861,7 @@ module.exports = function (RED) {
|
|
|
851
861
|
|
|
852
862
|
node.handleSendHUE = (_event) => {
|
|
853
863
|
try {
|
|
854
|
-
|
|
864
|
+
const deviceByRef = cloneDeep(_event);
|
|
855
865
|
if (deviceByRef.id === node.hueDevice) {
|
|
856
866
|
if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
|
|
857
867
|
node.setNodeStatusHue({
|
|
@@ -1107,11 +1117,11 @@ module.exports = function (RED) {
|
|
|
1107
1117
|
// };
|
|
1108
1118
|
|
|
1109
1119
|
/**
|
|
1110
|
-
* Update the KNC colors and HSV states group addresses
|
|
1111
|
-
* @param {object} _value {xy:{x,y}} in 0-1 scale
|
|
1112
|
-
* @param {string} _outputtype "write" is the default KNX command
|
|
1113
|
-
* @returns {}
|
|
1114
|
-
*/
|
|
1120
|
+
* Update the KNC colors and HSV states group addresses
|
|
1121
|
+
* @param {object} _value {xy:{x,y}} in 0-1 scale
|
|
1122
|
+
* @param {string} _outputtype "write" is the default KNX command
|
|
1123
|
+
* @returns {}
|
|
1124
|
+
*/
|
|
1115
1125
|
node.updateKNXLightColorState = function updateKNXLightColorState(_value, _outputtype = "write") {
|
|
1116
1126
|
if (config.GALightColorState !== undefined && config.GALightColorState !== "") {
|
|
1117
1127
|
if (_value.xy === undefined || _value.xy.x === undefined) return;
|
|
@@ -15,8 +15,8 @@ module.exports = function (RED) {
|
|
|
15
15
|
node.initialread = true;
|
|
16
16
|
node.listenallga = true; // Don't remove
|
|
17
17
|
node.outputtype = 'write';
|
|
18
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
18
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
20
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
21
21
|
node.passthrough = 'no';
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
@@ -15,8 +15,8 @@ module.exports = function (RED) {
|
|
|
15
15
|
node.initialread = true;
|
|
16
16
|
node.listenallga = true; // Don't remove
|
|
17
17
|
node.outputtype = "write";
|
|
18
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
18
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
20
|
node.currentPayload = ""; // Current value for the RBE input and for the .previouspayload msg
|
|
21
21
|
node.passthrough = "no";
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
@@ -18,8 +18,8 @@ module.exports = function (RED) {
|
|
|
18
18
|
node.initialread = true;
|
|
19
19
|
node.listenallga = true; // Don't remove
|
|
20
20
|
node.outputtype = 'write';
|
|
21
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
22
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
21
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
22
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
23
23
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
24
24
|
node.passthrough = 'no';
|
|
25
25
|
node.formatmultiplyvalue = 1;
|
|
@@ -16,8 +16,8 @@ module.exports = function (RED) {
|
|
|
16
16
|
node.initialread = true;
|
|
17
17
|
node.listenallga = true; // Don't remove
|
|
18
18
|
node.outputtype = 'write';
|
|
19
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
20
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
19
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
20
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
21
21
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
22
22
|
node.passthrough = 'no';
|
|
23
23
|
node.formatmultiplyvalue = 1;
|
|
@@ -15,8 +15,8 @@ module.exports = function (RED) {
|
|
|
15
15
|
node.initialread = true;
|
|
16
16
|
node.listenallga = true; // Don't remove
|
|
17
17
|
node.outputtype = 'write';
|
|
18
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
18
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
20
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
21
21
|
node.passthrough = 'no';
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
@@ -15,8 +15,8 @@ module.exports = function (RED) {
|
|
|
15
15
|
node.initialread = true;
|
|
16
16
|
node.listenallga = true; // Don't remove
|
|
17
17
|
node.outputtype = 'write';
|
|
18
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
18
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
19
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
20
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
21
21
|
node.passthrough = 'no';
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = function (RED) {
|
|
2
|
-
function knxUltimateLogger
|
|
2
|
+
function knxUltimateLogger(config) {
|
|
3
3
|
RED.nodes.createNode(this, config)
|
|
4
4
|
const node = this
|
|
5
5
|
node.server = RED.nodes.getNode(config.server)
|
|
@@ -11,8 +11,8 @@ module.exports = function (RED) {
|
|
|
11
11
|
node.initialread = false
|
|
12
12
|
node.listenallga = true
|
|
13
13
|
node.outputtype = 'write'
|
|
14
|
-
node.outputRBE = false
|
|
15
|
-
node.inputRBE = false
|
|
14
|
+
node.outputRBE = 'false'
|
|
15
|
+
node.inputRBE = 'false'
|
|
16
16
|
node.currentPayload = ''
|
|
17
17
|
node.topic = config.topic !== undefined ? config.topic : ''
|
|
18
18
|
node.autoStartTimerCreateETSXML = config.autoStartTimerCreateETSXML !== undefined ? config.autoStartTimerCreateETSXML : true
|
|
@@ -44,7 +44,7 @@ module.exports = function (RED) {
|
|
|
44
44
|
if (!node.server) return
|
|
45
45
|
|
|
46
46
|
// 26/03/2020 Create and output the XML for ETS bus monitor
|
|
47
|
-
function createETSXML
|
|
47
|
+
function createETSXML() {
|
|
48
48
|
let sFile = '<CommunicationLog xmlns="http://knx.org/xml/telegrams/01">\n'
|
|
49
49
|
for (let index = 0; index < node.etsXMLRow.length; index++) {
|
|
50
50
|
const element = node.etsXMLRow[index]
|
|
@@ -58,7 +58,7 @@ module.exports = function (RED) {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// 25/10/2021 Count Telegrams. Requested by RicharddeCrep https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/149#issue-1034644956
|
|
61
|
-
function countTelegrams
|
|
61
|
+
function countTelegrams() {
|
|
62
62
|
node.send([null, { topic: node.topic, payload: node.telegramCount, countIntervalInSeconds: node.intervalTelegramCount / 1000, currentTime: new Date().toLocaleString() }])
|
|
63
63
|
node.setNodeStatus({ fill: 'green', shape: 'dot', text: 'Payload Telegram counter sent.', payload: node.telegramCount, GA: '', dpt: '', devicename: '' })
|
|
64
64
|
node.telegramCount = 0
|
|
@@ -17,8 +17,8 @@ module.exports = function (RED) {
|
|
|
17
17
|
node.initialread = false;
|
|
18
18
|
node.listenallga = true;
|
|
19
19
|
node.outputtype = 'write';
|
|
20
|
-
node.outputRBE = false; // Apply or not RBE to the output (Messages coming from flow)
|
|
21
|
-
node.inputRBE = false; // Apply or not RBE to the input (Messages coming from BUS)
|
|
20
|
+
node.outputRBE = 'false'; // Apply or not RBE to the output (Messages coming from flow)
|
|
21
|
+
node.inputRBE = 'false'; // Apply or not RBE to the input (Messages coming from BUS)
|
|
22
22
|
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
23
23
|
node.passthrough = 'no';
|
|
24
24
|
node.formatmultiplyvalue = 1;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const ping = require('ping')
|
|
2
2
|
|
|
3
3
|
module.exports = function (RED) {
|
|
4
|
-
function knxUltimateWatchDog
|
|
4
|
+
function knxUltimateWatchDog(config) {
|
|
5
5
|
RED.nodes.createNode(this, config)
|
|
6
6
|
const node = this
|
|
7
7
|
node.server = RED.nodes.getNode(config.server)
|
|
@@ -14,8 +14,8 @@ module.exports = function (RED) {
|
|
|
14
14
|
node.initialread = false
|
|
15
15
|
node.listenallga = false
|
|
16
16
|
node.outputtype = 'write'
|
|
17
|
-
node.outputRBE = false
|
|
18
|
-
node.inputRBE = false
|
|
17
|
+
node.outputRBE = 'false'
|
|
18
|
+
node.inputRBE = 'false'
|
|
19
19
|
node.currentPayload = ''
|
|
20
20
|
node.topic = config.topic !== undefined ? config.topic : ''
|
|
21
21
|
node.retryInterval = config.retryInterval !== undefined ? config.retryInterval * 1000 : 10000
|
|
@@ -46,7 +46,7 @@ module.exports = function (RED) {
|
|
|
46
46
|
|
|
47
47
|
if (!node.server) return
|
|
48
48
|
|
|
49
|
-
function handleTheDog
|
|
49
|
+
function handleTheDog() {
|
|
50
50
|
node.beatNumber += 1
|
|
51
51
|
if (node.beatNumber > node.maxRetry) {
|
|
52
52
|
// Confirmed connection error
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module.exports.ToBoolean = function ToBoolean(value, _configTranslationNode) {
|
|
2
|
+
let res = false;
|
|
3
|
+
let decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/;
|
|
4
|
+
|
|
5
|
+
if (typeof value === "boolean") {
|
|
6
|
+
return value;
|
|
7
|
+
} else if (typeof value === "string") {
|
|
8
|
+
try {
|
|
9
|
+
let translationTable = [];
|
|
10
|
+
if (_configTranslationNode === null) {
|
|
11
|
+
translationTable = DEFAULTTRANSLATIONINPUT.split("\n");
|
|
12
|
+
} else {
|
|
13
|
+
translationTable = _configTranslationNode.commandText.split("\n");
|
|
14
|
+
}
|
|
15
|
+
for (let index = 0; index < translationTable.length; index++) {
|
|
16
|
+
let inputPayloadToBeTranslated = translationTable[index].split(":")[0];
|
|
17
|
+
let outputBoolean = Boolean(translationTable[index].split(":")[1]);
|
|
18
|
+
if (
|
|
19
|
+
value.toLowerCase() === inputPayloadToBeTranslated.toLowerCase() &&
|
|
20
|
+
inputPayloadToBeTranslated.toLowerCase() !== ""
|
|
21
|
+
) {
|
|
22
|
+
return translationTable[index].split(":")[1] === "true"
|
|
23
|
+
? true
|
|
24
|
+
: false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.log("Boolean-Logic-Ultimate:utils:toBoolean: " + error.message);
|
|
29
|
+
}
|
|
30
|
+
} else if (typeof value === "number") {
|
|
31
|
+
// Is it formated as a decimal number?
|
|
32
|
+
if (decimal.test(value)) {
|
|
33
|
+
res = parseFloat(value) != 0;
|
|
34
|
+
} else {
|
|
35
|
+
res = value.toLowerCase() === "true";
|
|
36
|
+
}
|
|
37
|
+
return res;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
module.exports.fetchFromObject = function fetchFromObject(
|
|
42
|
+
_msg,
|
|
43
|
+
_payloadPropName
|
|
44
|
+
) {
|
|
45
|
+
// The output cannot be an oblect. In case, return undefined.
|
|
46
|
+
var _index = _payloadPropName.indexOf(".");
|
|
47
|
+
if (_index > -1) {
|
|
48
|
+
return fetchFromObject(
|
|
49
|
+
_msg[_payloadPropName.substring(0, _index)],
|
|
50
|
+
_payloadPropName.substr(_index + 1)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (typeof _msg[_payloadPropName] === "object") return undefined;
|
|
54
|
+
return _msg[_payloadPropName];
|
|
55
|
+
};
|
|
56
|
+
const DEFAULTTRANSLATIONINPUT =
|
|
57
|
+
"on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false\nnormal:false\nviolated:true";
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=16.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.4.
|
|
6
|
+
"version": "2.4.10",
|
|
7
7
|
"description": "Control your KNX intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"binary-parser": "2.2.1",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"knxUltimateHueTemperatureSensor": "/nodes/knxUltimateHueTemperatureSensor.js",
|
|
45
45
|
"knxUltimateHueScene": "/nodes/knxUltimateHueScene.js",
|
|
46
46
|
"knxUltimateHueBattery": "/nodes/knxUltimateHueBattery.js",
|
|
47
|
-
"knxUltimateHueZigbeeConnectivity": "/nodes/knxUltimateHueZigbeeConnectivity.js"
|
|
47
|
+
"knxUltimateHueZigbeeConnectivity": "/nodes/knxUltimateHueZigbeeConnectivity.js",
|
|
48
|
+
"knxUltimateHATranslator": "/nodes/knxUltimateHATranslator.js"
|
|
48
49
|
}
|
|
49
50
|
},
|
|
50
51
|
"repository": {
|