node-red-contrib-knx-ultimate 2.3.5 → 2.4.1
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/.github/ISSUE_TEMPLATE/bug_report.md +7 -7
- package/CHANGELOG.md +26 -0
- package/KNXEngine/CHANGELOG.md +5 -1
- package/KNXEngine/package.json +1 -1
- package/KNXEngine/src/dptlib/dpt275.js +60 -0
- package/KNXEngine/src/dptlib/index.js +79 -65
- package/nodes/commonFunctions.js +419 -0
- package/nodes/hue-config.html +56 -40
- package/nodes/hue-config.js +0 -108
- package/nodes/knxUltimate-config.html +1 -1
- package/nodes/knxUltimate-config.js +13 -232
- package/nodes/knxUltimate.html +2 -2
- package/nodes/knxUltimateHueBattery.html +2 -2
- package/nodes/knxUltimateHueButton.html +3 -3
- package/nodes/knxUltimateHueLight.html +969 -924
- package/nodes/knxUltimateHueLight.js +17 -9
- package/nodes/knxUltimateHueLightSensor.html +2 -2
- package/nodes/knxUltimateHueMotion.html +2 -2
- package/nodes/knxUltimateHueScene.html +3 -3
- package/nodes/knxUltimateHueTapDial.html +2 -2
- package/nodes/knxUltimateHueTemperatureSensor.html +2 -2
- package/nodes/knxUltimateLoadControl.html +1 -1
- package/nodes/knxUltimateSceneController.html +6 -6
- package/nodes/knxUltimateSceneController.js +1 -9
- package/package.json +2 -2
- package/nodes/utils/commonFunctions.js +0 -21
|
@@ -225,6 +225,10 @@ module.exports = function (RED) {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
} else {
|
|
228
|
+
// Stop color cycle
|
|
229
|
+
if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle);
|
|
230
|
+
// Stop Blinking
|
|
231
|
+
if (node.timerBlink !== undefined) clearInterval(node.timerBlink);
|
|
228
232
|
state = { on: { on: false } };
|
|
229
233
|
}
|
|
230
234
|
|
|
@@ -250,11 +254,9 @@ module.exports = function (RED) {
|
|
|
250
254
|
let kelvinValue = 0;
|
|
251
255
|
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin));
|
|
252
256
|
if (config.dptLightKelvin === "7.600") {
|
|
253
|
-
if (msg.payload >
|
|
254
|
-
if (msg.payload <
|
|
255
|
-
|
|
256
|
-
// knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
|
|
257
|
-
kelvinValue = hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [2000, 6535]);
|
|
257
|
+
if (msg.payload > 6535) msg.payload = 6535;
|
|
258
|
+
if (msg.payload < 2000) msg.payload = 2000;
|
|
259
|
+
kelvinValue = msg.payload;//hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [2000, 6535]);
|
|
258
260
|
retMirek = hueColorConverter.ColorConverter.kelvinToMirek(kelvinValue);
|
|
259
261
|
} else if (config.dptLightKelvin === "9.002") {
|
|
260
262
|
// Relative temperature in Kelvin. Use HUE scale.
|
|
@@ -389,7 +391,7 @@ module.exports = function (RED) {
|
|
|
389
391
|
? { on: { on: true }, dimming: { brightness: 100 }, dynamics: { duration: 0 } }
|
|
390
392
|
: { on: { on: false }, dimming: { brightness: 0 }, dynamics: { duration: 0 } };
|
|
391
393
|
node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, state, node.isGrouped_light === false ? "setLight" : "setGroupedLight");
|
|
392
|
-
},
|
|
394
|
+
}, 1500);
|
|
393
395
|
} else {
|
|
394
396
|
if (node.timerBlink !== undefined) clearInterval(node.timerBlink);
|
|
395
397
|
node.serverHue.hueManager.writeHueQueueAdd(
|
|
@@ -514,8 +516,14 @@ module.exports = function (RED) {
|
|
|
514
516
|
return;
|
|
515
517
|
}
|
|
516
518
|
|
|
519
|
+
// If i'm dimming up while the light is off, start the dim with the initial brightness set to zero
|
|
520
|
+
if (_KNXbrightness_Direction > 0 && _KNXaction === 1 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
|
|
521
|
+
node.brightnessStep = null;
|
|
522
|
+
node.currentHUEDevice.dimming.brightness = 0;
|
|
523
|
+
}
|
|
524
|
+
|
|
517
525
|
// Set the actual brightness to start with
|
|
518
|
-
if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness
|
|
526
|
+
if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness !== undefined ? node.currentHUEDevice.dimming.brightness : 50;
|
|
519
527
|
node.brightnessStep = Math.ceil(Number(node.brightnessStep));
|
|
520
528
|
|
|
521
529
|
// We have also minDimLevelLight and maxDimLevelLight to take care of.
|
|
@@ -540,7 +548,7 @@ module.exports = function (RED) {
|
|
|
540
548
|
node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
|
|
541
549
|
node.brightnessStep += numStep;
|
|
542
550
|
if (node.brightnessStep > maxDimLevelLight) node.brightnessStep = maxDimLevelLight;
|
|
543
|
-
hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs +
|
|
551
|
+
hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 300 } }; // + 100 is to avoid ladder effect
|
|
544
552
|
// Switch on the light if off
|
|
545
553
|
if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
|
|
546
554
|
hueTelegram.on = { on: true };
|
|
@@ -557,7 +565,7 @@ module.exports = function (RED) {
|
|
|
557
565
|
node.updateKNXBrightnessState(node.brightnessStep); // Unnecessary, but necessary to set the KNX Status in real time.
|
|
558
566
|
node.brightnessStep -= numStep;
|
|
559
567
|
if (node.brightnessStep < minDimLevelLight) node.brightnessStep = minDimLevelLight;
|
|
560
|
-
hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs +
|
|
568
|
+
hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 300 } };// + 100 is to avoid ladder effect
|
|
561
569
|
// Switch off the light if on
|
|
562
570
|
if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStep === 0) {
|
|
563
571
|
hueTelegram.on = { on: false };
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
|
|
70
70
|
// DPT
|
|
71
71
|
// ########################
|
|
72
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
72
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
73
73
|
data.forEach(dpt => {
|
|
74
74
|
if (dpt.value.startsWith("9.004")) {
|
|
75
75
|
$("#node-input-dptlightsensor").append($("<option></option>")
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
$("#node-input-name").autocomplete({
|
|
121
121
|
minLength: 1,
|
|
122
122
|
source: function (request, response) {
|
|
123
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=light_level&
|
|
123
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=light_level&serverId=" + oNodeServerHue.id, (data) => {
|
|
124
124
|
response($.map(data.devices, function (value, key) {
|
|
125
125
|
//alert(JSON.stringify(value) + " "+ key)
|
|
126
126
|
var sSearch = (value.name);
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
|
|
69
69
|
// DPT
|
|
70
70
|
// ########################
|
|
71
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
71
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
72
72
|
data.forEach(dpt => {
|
|
73
73
|
if (dpt.value.startsWith("1.")) {
|
|
74
74
|
$("#node-input-dptmotion").append($("<option></option>")
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
$("#node-input-name").autocomplete({
|
|
120
120
|
minLength: 1,
|
|
121
121
|
source: function (request, response) {
|
|
122
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=motion&
|
|
122
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=motion&serverId=" + oNodeServerHue.id, (data) => {
|
|
123
123
|
response($.map(data.devices, function (value, key) {
|
|
124
124
|
//alert(JSON.stringify(value) + " "+ key)
|
|
125
125
|
var sSearch = (value.name);
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
|
|
97
97
|
// DPT
|
|
98
98
|
// ########################
|
|
99
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
99
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
100
100
|
data.forEach(dpt => {
|
|
101
101
|
if (dpt.value.startsWith("1.") || dpt.value.startsWith("18.")) {
|
|
102
102
|
$("#node-input-dptscene").append($("<option></option>")
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
$("#node-input-name").autocomplete({
|
|
245
245
|
minLength: 1,
|
|
246
246
|
source: function (request, response) {
|
|
247
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=scene&
|
|
247
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=scene&serverId=" + oNodeServerHue.id, (data) => {
|
|
248
248
|
response($.map(data.devices, function (value, key) {
|
|
249
249
|
//alert(JSON.stringify(value) + " "+ key)
|
|
250
250
|
var sSearch = (value.name);
|
|
@@ -340,7 +340,7 @@
|
|
|
340
340
|
rowRuleHUESceneName.autocomplete({
|
|
341
341
|
minLength: 1,
|
|
342
342
|
source: function (request, response) {
|
|
343
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=scene&
|
|
343
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=scene&serverId=" + oNodeServerHue.id, (data) => {
|
|
344
344
|
response($.map(data.devices, function (value, key) {
|
|
345
345
|
//alert(JSON.stringify(value) + " "+ key)
|
|
346
346
|
var sSearch = (value.name);
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
|
|
70
70
|
// DPT repeat
|
|
71
71
|
// ########################
|
|
72
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
72
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
73
73
|
data.forEach(dpt => {
|
|
74
74
|
if (dpt.value.startsWith("3.007") || dpt.value.startsWith("5.001") || dpt.value.startsWith("232.600")) {
|
|
75
75
|
$("#node-input-dptrepeat").append($("<option></option>")
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
$("#node-input-name").autocomplete({
|
|
122
122
|
minLength: 1,
|
|
123
123
|
source: function (request, response) {
|
|
124
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=relative_rotary&
|
|
124
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=relative_rotary&serverId=" + oNodeServerHue.id, (data) => {
|
|
125
125
|
response($.map(data.devices, function (value, key) {
|
|
126
126
|
//alert(JSON.stringify(value) + " "+ key)
|
|
127
127
|
var sSearch = (value.name);
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
|
|
70
70
|
// DPT
|
|
71
71
|
// ########################
|
|
72
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
72
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
73
73
|
data.forEach(dpt => {
|
|
74
74
|
if (dpt.value.startsWith("9.001")) {
|
|
75
75
|
$("#node-input-dpttemperaturesensor").append($("<option></option>")
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
$("#node-input-name").autocomplete({
|
|
121
121
|
minLength: 1,
|
|
122
122
|
source: function (request, response) {
|
|
123
|
-
$.getJSON("KNXUltimateGetResourcesHUE?rtype=temperature&
|
|
123
|
+
$.getJSON("KNXUltimateGetResourcesHUE?rtype=temperature&serverId=" + oNodeServerHue.id, (data) => {
|
|
124
124
|
response($.map(data.devices, function (value, key) {
|
|
125
125
|
//alert(JSON.stringify(value) + " "+ key)
|
|
126
126
|
var sSearch = (value.name);
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
return i == aSearchWords.length;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
$.getJSON("knxUltimateDpts", (data) => {
|
|
93
|
+
$.getJSON("knxUltimateDpts?serverId=" + $("#node-input-server").val(), (data) => {
|
|
94
94
|
data.forEach(dpt => {
|
|
95
95
|
$("#node-input-dpt").append($("<option></option>").attr("value", dpt.value).text(dpt.text));
|
|
96
96
|
for (let index = 1; index < 6; index++) {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
|
|
64
64
|
// DPT of Scene Recall
|
|
65
65
|
// ########################
|
|
66
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
66
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
67
67
|
data.forEach(dpt => {
|
|
68
68
|
$("#node-input-dpt").append($("<option></option>")
|
|
69
69
|
.attr("value", dpt.value)
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
|
|
186
186
|
// DPT of Scene Save
|
|
187
187
|
// ########################
|
|
188
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
188
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
189
189
|
data.forEach(dpt => {
|
|
190
190
|
$("#node-input-dptSave").append($("<option></option>")
|
|
191
191
|
.attr("value", dpt.value)
|
|
@@ -297,7 +297,7 @@
|
|
|
297
297
|
opt.r = {};
|
|
298
298
|
// Delete saved scene
|
|
299
299
|
// ##########################################################
|
|
300
|
-
$.getJSON("knxultimatescenecontrollerdelete?FileName=" + node.id, new Date().getTime(), (data) => { });
|
|
300
|
+
$.getJSON("knxultimatescenecontrollerdelete?FileName=" + node.id + "&serverId=" + $("node-input-server").val(), new Date().getTime(), (data) => { });
|
|
301
301
|
// ##########################################################
|
|
302
302
|
}
|
|
303
303
|
var rule = opt.r;
|
|
@@ -324,7 +324,7 @@
|
|
|
324
324
|
resizeRule(container);
|
|
325
325
|
});
|
|
326
326
|
|
|
327
|
-
$.getJSON('knxUltimateDpts', (data) => {
|
|
327
|
+
$.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => {
|
|
328
328
|
data.forEach(dpt => {
|
|
329
329
|
oDPTField.append($("<option></option>")
|
|
330
330
|
.attr("value", dpt.value)
|
|
@@ -381,8 +381,8 @@
|
|
|
381
381
|
removable: true
|
|
382
382
|
});
|
|
383
383
|
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
// Put some spaces after the container
|
|
385
|
+
$('<br/><br/><br/>').insertAfter($("#node-input-rule-container"));
|
|
386
386
|
|
|
387
387
|
// 10/03/2020 For each rule, create a row
|
|
388
388
|
for (var i = 0; i < this.rules.length; i++) {
|
|
@@ -31,15 +31,7 @@ module.exports = function (RED) {
|
|
|
31
31
|
node.icountMessageInWindow = 0
|
|
32
32
|
node.disabled = false // 21/09/2020 you can now disable the scene controller
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
RED.httpAdmin.get('/knxultimatescenecontrollerdelete', RED.auth.needsPermission('knxUltimateSceneController.read'), function (req, res) {
|
|
36
|
-
// Delete the file
|
|
37
|
-
try {
|
|
38
|
-
const newPath = node.userDir + '/scenecontroller/SceneController_' + req.query.FileName
|
|
39
|
-
fs.unlinkSync(newPath)
|
|
40
|
-
} catch (error) { if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.warn('e ' + error) }
|
|
41
|
-
res.json({ status: 220 })
|
|
42
|
-
})
|
|
34
|
+
|
|
43
35
|
|
|
44
36
|
// 03/09/2021
|
|
45
37
|
async function delay(ms) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=16.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.4.1",
|
|
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",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"node-red": {
|
|
24
24
|
"version": ">=2.0.0",
|
|
25
25
|
"nodes": {
|
|
26
|
-
"commonFunctions": "/nodes/
|
|
26
|
+
"commonFunctions": "/nodes/commonFunctions.js",
|
|
27
27
|
"knxUltimate": "/nodes/knxUltimate.js",
|
|
28
28
|
"knxUltimateSceneController": "/nodes/knxUltimateSceneController.js",
|
|
29
29
|
"knxUltimateWatchDog": "/nodes/knxUltimateWatchDog.js",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Utility function
|
|
2
|
-
// until node-red 3.1.0, there is a bug creating a plugin, so for backward compatibility, i must use a JS as a node.
|
|
3
|
-
const yaml = require('js-yaml');
|
|
4
|
-
module.exports = function (RED) {
|
|
5
|
-
|
|
6
|
-
//RED.log.error("###############################################################")
|
|
7
|
-
RED.httpAdmin.post("/banana", RED.auth.needsPermission("write"), (req, res) => {
|
|
8
|
-
var node = RED.nodes.getNode(req.params.id);
|
|
9
|
-
if (node != null) {
|
|
10
|
-
try {
|
|
11
|
-
if (req.body) {
|
|
12
|
-
console.log(body);
|
|
13
|
-
}
|
|
14
|
-
} catch (err) { }
|
|
15
|
-
}
|
|
16
|
-
res.json(req.body)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|