node-red-contrib-knx-ultimate 2.1.63 → 2.2.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/CHANGELOG.md +7 -0
- package/KNXEngine/package.json +1 -1
- package/nodes/hue-config.html +2 -2
- package/nodes/hue-config.js +75 -34
- package/nodes/knxUltimate-config.js +158 -156
- package/nodes/knxUltimateHueBattery.html +2 -2
- package/nodes/knxUltimateHueButton.html +1 -1
- package/nodes/knxUltimateHueButton.js +152 -116
- package/nodes/knxUltimateHueLight.html +64 -24
- package/nodes/knxUltimateHueLight.js +132 -137
- package/nodes/knxUltimateHueLightSensor.html +1 -1
- package/nodes/knxUltimateHueLightSensor.js +2 -2
- package/nodes/knxUltimateHueMotion.html +2 -2
- package/nodes/knxUltimateHueScene.html +1 -1
- package/nodes/knxUltimateHueTapDial.html +1 -1
- package/nodes/knxUltimateHueTapDial.js +1 -2
- package/nodes/knxUltimateHueTemperatureSensor.html +2 -2
- package/nodes/knxUltimateLoadControl.html +1 -1
- package/nodes/utils/hueEngine.js +5 -25
- package/package.json +2 -2
- package/nodes/utils/iro.js +0 -1835
|
@@ -1,188 +1,224 @@
|
|
|
1
1
|
module.exports = function (RED) {
|
|
2
|
-
const dptlib = require(
|
|
2
|
+
const dptlib = require("../KNXEngine/src/dptlib");
|
|
3
3
|
|
|
4
4
|
function knxUltimateHueButton(config) {
|
|
5
|
-
RED.nodes.createNode(this, config)
|
|
6
|
-
const node = this
|
|
7
|
-
node.server = RED.nodes.getNode(config.server)
|
|
8
|
-
node.serverHue = RED.nodes.getNode(config.serverHue)
|
|
9
|
-
node.topic = node.name
|
|
10
|
-
node.name = config.name === undefined ? 'Hue' : config.name
|
|
11
|
-
node.dpt = ''
|
|
12
|
-
node.notifyreadrequest = false
|
|
13
|
-
node.notifyreadrequestalsorespondtobus = 'false'
|
|
14
|
-
node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = ''
|
|
15
|
-
node.notifyresponse = false
|
|
16
|
-
node.notifywrite = true
|
|
17
|
-
node.initialread = true
|
|
18
|
-
node.listenallga = true // Don't remove
|
|
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)
|
|
22
|
-
node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
|
|
23
|
-
node.passthrough = 'no'
|
|
24
|
-
node.formatmultiplyvalue = 1
|
|
25
|
-
node.formatnegativevalue = 'leave'
|
|
26
|
-
node.formatdecimalsvalue = 2
|
|
27
|
-
node.short_releaseValue = false
|
|
28
|
-
node.isTimerDimStopRunning = false
|
|
5
|
+
RED.nodes.createNode(this, config);
|
|
6
|
+
const node = this;
|
|
7
|
+
node.server = RED.nodes.getNode(config.server);
|
|
8
|
+
node.serverHue = RED.nodes.getNode(config.serverHue);
|
|
9
|
+
node.topic = node.name;
|
|
10
|
+
node.name = config.name === undefined ? 'Hue' : config.name;
|
|
11
|
+
node.dpt = '';
|
|
12
|
+
node.notifyreadrequest = false;
|
|
13
|
+
node.notifyreadrequestalsorespondtobus = 'false';
|
|
14
|
+
node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = '';
|
|
15
|
+
node.notifyresponse = false;
|
|
16
|
+
node.notifywrite = true;
|
|
17
|
+
node.initialread = true;
|
|
18
|
+
node.listenallga = true; // Don't remove
|
|
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)
|
|
22
|
+
node.currentPayload = ''; // Current value for the RBE input and for the .previouspayload msg
|
|
23
|
+
node.passthrough = 'no';
|
|
24
|
+
node.formatmultiplyvalue = 1;
|
|
25
|
+
node.formatnegativevalue = 'leave';
|
|
26
|
+
node.formatdecimalsvalue = 2;
|
|
27
|
+
node.short_releaseValue = false;
|
|
28
|
+
node.isTimerDimStopRunning = false;
|
|
29
29
|
|
|
30
30
|
// Used to call the status update from the config node.
|
|
31
|
-
node.setNodeStatus = ({
|
|
31
|
+
node.setNodeStatus = ({
|
|
32
|
+
fill, shape, text, payload,
|
|
33
|
+
}) => {
|
|
32
34
|
|
|
33
|
-
}
|
|
35
|
+
};
|
|
34
36
|
// Used to call the status update from the HUE config node.
|
|
35
|
-
node.setNodeStatusHue = ({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
node.setNodeStatusHue = ({
|
|
38
|
+
fill, shape, text, payload,
|
|
39
|
+
}) => {
|
|
40
|
+
if (payload === undefined) return;
|
|
41
|
+
const dDate = new Date();
|
|
42
|
+
payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString();
|
|
43
|
+
node.status({ fill, shape, text: `${text} ${payload} (${dDate.getDate()}, ${dDate.toLocaleTimeString()})` });
|
|
44
|
+
};
|
|
41
45
|
|
|
42
46
|
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
43
|
-
node.handleSend = msg => {
|
|
44
|
-
const state = {}
|
|
47
|
+
node.handleSend = (msg) => {
|
|
48
|
+
const state = {};
|
|
45
49
|
try {
|
|
46
50
|
switch (msg.knx.destination) {
|
|
47
51
|
case config.GAshort_releaseStatus:
|
|
48
|
-
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptshort_release))
|
|
49
|
-
node.short_releaseValue = msg.payload
|
|
50
|
-
node.setNodeStatusHue({
|
|
51
|
-
|
|
52
|
+
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptshort_release));
|
|
53
|
+
node.short_releaseValue = msg.payload;
|
|
54
|
+
node.setNodeStatusHue({
|
|
55
|
+
fill: 'green', shape: 'dot', text: 'KNX->HUE Short Release Status', payload: msg.payload,
|
|
56
|
+
});
|
|
57
|
+
break;
|
|
52
58
|
case config.GArepeatStatus:
|
|
53
|
-
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptrepeat))
|
|
54
|
-
node.toggleGArepeat = msg.payload.decr_incr === 1
|
|
55
|
-
node.setNodeStatusHue({
|
|
56
|
-
|
|
59
|
+
msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptrepeat));
|
|
60
|
+
node.toggleGArepeat = msg.payload.decr_incr === 1;
|
|
61
|
+
node.setNodeStatusHue({
|
|
62
|
+
fill: 'green', shape: 'dot', text: 'KNX->HUE Repeat Status', payload: msg.payload,
|
|
63
|
+
});
|
|
64
|
+
break;
|
|
57
65
|
default:
|
|
58
|
-
break
|
|
66
|
+
break;
|
|
59
67
|
}
|
|
60
68
|
} catch (error) {
|
|
61
|
-
node.setNodeStatusHue({
|
|
69
|
+
node.setNodeStatusHue({
|
|
70
|
+
fill: 'red', shape: 'dot', text: `KNX->HUE error ${error.message}`, payload: '',
|
|
71
|
+
});
|
|
62
72
|
}
|
|
63
|
-
}
|
|
73
|
+
};
|
|
64
74
|
|
|
65
|
-
node.handleSendHUE = _event => {
|
|
75
|
+
node.handleSendHUE = (_event) => {
|
|
66
76
|
try {
|
|
67
77
|
if (_event.id === config.hueDevice) {
|
|
68
|
-
const knxMsgPayload = {}
|
|
69
|
-
let flowMsgPayload = true
|
|
78
|
+
const knxMsgPayload = {};
|
|
79
|
+
let flowMsgPayload = true;
|
|
70
80
|
// Handling events with toggles
|
|
71
81
|
// KNX Dimming reminder tips
|
|
72
82
|
// { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
|
|
73
83
|
// { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
|
|
74
84
|
switch (_event.button.last_event) {
|
|
75
85
|
case 'initial_press':
|
|
76
|
-
if (node.initial_pressValue === undefined) node.initial_pressValue = false
|
|
77
|
-
node.initial_pressValue = config.toggleValues ? !node.initial_pressValue : true
|
|
78
|
-
flowMsgPayload = node.initial_pressValue
|
|
79
|
-
break
|
|
86
|
+
if (node.initial_pressValue === undefined) node.initial_pressValue = false;
|
|
87
|
+
node.initial_pressValue = config.toggleValues ? !node.initial_pressValue : true;
|
|
88
|
+
flowMsgPayload = node.initial_pressValue;
|
|
89
|
+
break;
|
|
80
90
|
case 'long_release':
|
|
81
|
-
flowMsgPayload = node.long_pressValue
|
|
91
|
+
flowMsgPayload = node.long_pressValue;
|
|
82
92
|
// if the dimmer was running, send the STOP telegram to the KNX bus wires, using the GArepeat Group address and dpt.
|
|
83
93
|
if (node.isTimerDimStopRunning) {
|
|
84
|
-
knxMsgPayload.topic = config.GArepeat
|
|
85
|
-
knxMsgPayload.dpt = config.dptrepeat
|
|
86
|
-
node.stopDIM(knxMsgPayload)
|
|
94
|
+
knxMsgPayload.topic = config.GArepeat;
|
|
95
|
+
knxMsgPayload.dpt = config.dptrepeat;
|
|
96
|
+
node.stopDIM(knxMsgPayload);
|
|
87
97
|
}
|
|
88
|
-
break
|
|
98
|
+
break;
|
|
89
99
|
case 'double_short_release':
|
|
90
|
-
if (node.double_short_releaseValue === undefined) node.double_short_releaseValue = false
|
|
91
|
-
node.double_short_releaseValue = config.toggleValues ? !node.double_short_releaseValue : true
|
|
92
|
-
flowMsgPayload = node.double_short_releaseValue
|
|
93
|
-
break
|
|
100
|
+
if (node.double_short_releaseValue === undefined) node.double_short_releaseValue = false;
|
|
101
|
+
node.double_short_releaseValue = config.toggleValues ? !node.double_short_releaseValue : true;
|
|
102
|
+
flowMsgPayload = node.double_short_releaseValue;
|
|
103
|
+
break;
|
|
94
104
|
case 'long_press':
|
|
95
|
-
if (node.long_pressValue === undefined) node.long_pressValue = false
|
|
96
|
-
node.long_pressValue = config.toggleValues ? !node.long_pressValue : true
|
|
97
|
-
flowMsgPayload = node.long_pressValue
|
|
98
|
-
break
|
|
105
|
+
if (node.long_pressValue === undefined) node.long_pressValue = false;
|
|
106
|
+
node.long_pressValue = config.toggleValues ? !node.long_pressValue : true;
|
|
107
|
+
flowMsgPayload = node.long_pressValue;
|
|
108
|
+
break;
|
|
99
109
|
case 'short_release':
|
|
100
|
-
node.short_releaseValue = config.toggleValues ? !node.short_releaseValue : true
|
|
101
|
-
flowMsgPayload = node.short_releaseValue
|
|
110
|
+
node.short_releaseValue = config.toggleValues ? !node.short_releaseValue : true;
|
|
111
|
+
flowMsgPayload = node.short_releaseValue;
|
|
102
112
|
if (config.GAshort_release !== undefined && config.GAshort_release !== '') {
|
|
103
|
-
knxMsgPayload.topic = config.GAshort_release
|
|
104
|
-
knxMsgPayload.dpt = config.dptshort_release
|
|
105
|
-
knxMsgPayload.payload = node.short_releaseValue
|
|
113
|
+
knxMsgPayload.topic = config.GAshort_release;
|
|
114
|
+
knxMsgPayload.dpt = config.dptshort_release;
|
|
115
|
+
knxMsgPayload.payload = node.short_releaseValue;
|
|
106
116
|
// Send to KNX bus
|
|
107
|
-
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined)
|
|
108
|
-
|
|
117
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
118
|
+
node.server.writeQueueAdd({
|
|
119
|
+
grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
123
|
+
node.setNodeStatusHue({
|
|
124
|
+
fill: 'blue', shape: 'dot', text: `HUE->KNX ${_event.button.last_event}`, payload: knxMsgPayload.payload,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
109
127
|
}
|
|
110
|
-
break
|
|
128
|
+
break;
|
|
111
129
|
case 'repeat':
|
|
112
|
-
flowMsgPayload = true
|
|
130
|
+
flowMsgPayload = true;
|
|
113
131
|
if (config.GArepeat !== undefined && config.GArepeat !== '') {
|
|
114
132
|
if (node.isTimerDimStopRunning === false) {
|
|
115
133
|
// Set KNX Dim up/down start
|
|
116
|
-
knxMsgPayload.topic = config.GArepeat
|
|
117
|
-
knxMsgPayload.dpt = config.dptrepeat
|
|
118
|
-
knxMsgPayload.payload = node.long_pressValue ? { decr_incr: 0, data: 3 } : { decr_incr: 1, data: 3 } // If the light is turned on, the initial DIM direction must be down, otherwise, up
|
|
134
|
+
knxMsgPayload.topic = config.GArepeat;
|
|
135
|
+
knxMsgPayload.dpt = config.dptrepeat;
|
|
136
|
+
knxMsgPayload.payload = node.long_pressValue ? { decr_incr: 0, data: 3 } : { decr_incr: 1, data: 3 }; // If the light is turned on, the initial DIM direction must be down, otherwise, up
|
|
119
137
|
// Send to KNX bus
|
|
120
|
-
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined)
|
|
121
|
-
|
|
138
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
139
|
+
node.server.writeQueueAdd({
|
|
140
|
+
grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
144
|
+
node.setNodeStatusHue({
|
|
145
|
+
fill: 'blue', shape: 'dot', text: 'HUE->KNX START DIM', payload: '',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
122
148
|
}
|
|
123
|
-
node.startDimStopper(knxMsgPayload)
|
|
149
|
+
node.startDimStopper(knxMsgPayload);
|
|
124
150
|
}
|
|
125
|
-
break
|
|
151
|
+
break;
|
|
126
152
|
default:
|
|
127
|
-
break
|
|
153
|
+
break;
|
|
128
154
|
}
|
|
129
155
|
|
|
130
156
|
// Setup the output msg
|
|
131
|
-
const flowMsg = {}
|
|
132
|
-
flowMsg.name = node.name
|
|
133
|
-
flowMsg.event = _event.button.last_event
|
|
134
|
-
flowMsg.rawEvent = _event
|
|
135
|
-
flowMsg.payload = flowMsgPayload
|
|
136
|
-
node.send(flowMsg)
|
|
137
|
-
//node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: flowMsg.rawEvent + ' ' + flowMsg.payload })
|
|
157
|
+
const flowMsg = {};
|
|
158
|
+
flowMsg.name = node.name;
|
|
159
|
+
flowMsg.event = _event.button.last_event;
|
|
160
|
+
flowMsg.rawEvent = _event;
|
|
161
|
+
flowMsg.payload = flowMsgPayload;
|
|
162
|
+
node.send(flowMsg);
|
|
163
|
+
// node.setNodeStatusHue({ fill: 'blue', shape: 'ring', text: 'HUE->KNX', payload: flowMsg.rawEvent + ' ' + flowMsg.payload })
|
|
138
164
|
}
|
|
139
165
|
} catch (error) {
|
|
140
|
-
node.setNodeStatusHue({
|
|
166
|
+
node.setNodeStatusHue({
|
|
167
|
+
fill: 'red', shape: 'dot', text: `HUE->KNX error ${error.message}`, payload: '',
|
|
168
|
+
});
|
|
141
169
|
}
|
|
142
|
-
}
|
|
170
|
+
};
|
|
143
171
|
|
|
144
172
|
// Timer to stop the dimming sequence
|
|
145
173
|
node.startDimStopper = function (knxMsgPayload) {
|
|
146
|
-
if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop)
|
|
147
|
-
node.isTimerDimStopRunning = true
|
|
174
|
+
if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop);
|
|
175
|
+
node.isTimerDimStopRunning = true;
|
|
148
176
|
node.timerDimStop = setTimeout(() => {
|
|
149
|
-
node.stopDIM(knxMsgPayload)
|
|
150
|
-
}, 2000)
|
|
151
|
-
}
|
|
177
|
+
node.stopDIM(knxMsgPayload);
|
|
178
|
+
}, 2000);
|
|
179
|
+
};
|
|
152
180
|
|
|
153
181
|
node.stopDIM = function (knxMsgPayload) {
|
|
154
182
|
// KNX Stop DIM
|
|
155
|
-
if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop)
|
|
156
|
-
node.isTimerDimStopRunning = false
|
|
157
|
-
knxMsgPayload.payload = { decr_incr: 0, data: 0 } // Payload for the output msg
|
|
183
|
+
if (node.timerDimStop !== undefined) clearTimeout(node.timerDimStop);
|
|
184
|
+
node.isTimerDimStopRunning = false;
|
|
185
|
+
knxMsgPayload.payload = { decr_incr: 0, data: 0 }; // Payload for the output msg
|
|
158
186
|
// Send to KNX bus
|
|
159
|
-
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined)
|
|
160
|
-
|
|
161
|
-
|
|
187
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
188
|
+
node.server.writeQueueAdd({
|
|
189
|
+
grpaddr: knxMsgPayload.topic, payload: knxMsgPayload.payload, dpt: knxMsgPayload.dpt, outputtype: 'write', nodecallerid: node.id,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
|
|
193
|
+
node.setNodeStatusHue({
|
|
194
|
+
fill: 'grey', shape: 'ring', text: 'HUE->KNX STOP DIM', payload: knxMsgPayload.payload,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
};
|
|
162
198
|
|
|
163
199
|
// On each deploy, unsubscribe+resubscribe
|
|
164
200
|
if (node.server) {
|
|
165
|
-
node.server.removeClient(node)
|
|
166
|
-
node.server.addClient(node)
|
|
201
|
+
node.server.removeClient(node);
|
|
202
|
+
node.server.addClient(node);
|
|
167
203
|
}
|
|
168
204
|
if (node.serverHue) {
|
|
169
|
-
node.serverHue.removeClient(node)
|
|
170
|
-
node.serverHue.addClient(node)
|
|
205
|
+
node.serverHue.removeClient(node);
|
|
206
|
+
node.serverHue.addClient(node);
|
|
171
207
|
}
|
|
172
208
|
|
|
173
|
-
node.on('input',
|
|
209
|
+
node.on('input', (msg) => {
|
|
174
210
|
|
|
175
|
-
})
|
|
211
|
+
});
|
|
176
212
|
|
|
177
|
-
node.on('close',
|
|
213
|
+
node.on('close', (done) => {
|
|
178
214
|
if (node.server) {
|
|
179
|
-
node.server.removeClient(node)
|
|
215
|
+
node.server.removeClient(node);
|
|
180
216
|
}
|
|
181
217
|
if (node.serverHue) {
|
|
182
|
-
node.serverHue.removeClient(node)
|
|
218
|
+
node.serverHue.removeClient(node);
|
|
183
219
|
}
|
|
184
|
-
done()
|
|
185
|
-
})
|
|
220
|
+
done();
|
|
221
|
+
});
|
|
186
222
|
}
|
|
187
|
-
RED.nodes.registerType('knxUltimateHueButton', knxUltimateHueButton)
|
|
188
|
-
}
|
|
223
|
+
RED.nodes.registerType('knxUltimateHueButton', knxUltimateHueButton);
|
|
224
|
+
};
|
|
@@ -67,6 +67,9 @@
|
|
|
67
67
|
|
|
68
68
|
specifySwitchOnBrightness: { value: "yes" },
|
|
69
69
|
updateKNXBrightnessStatusOnHUEOnOff: { value: "onhueoff" },
|
|
70
|
+
dimSpeed: { value: 5000, required: false},
|
|
71
|
+
minDimLevelLight: { value: 3, required: false },
|
|
72
|
+
maxDimLevelLight: { value: 100, required: false },
|
|
70
73
|
|
|
71
74
|
hueDevice: { value: "" }
|
|
72
75
|
},
|
|
@@ -282,7 +285,9 @@
|
|
|
282
285
|
.text(dpt.text))
|
|
283
286
|
}
|
|
284
287
|
});
|
|
285
|
-
|
|
288
|
+
// Eval
|
|
289
|
+
const format = "node." + _destinationWidget.replace("#node-input-", "");
|
|
290
|
+
$(_destinationWidget).val(eval(format).toString());
|
|
286
291
|
})
|
|
287
292
|
}
|
|
288
293
|
|
|
@@ -316,7 +321,7 @@
|
|
|
316
321
|
// Select the option value
|
|
317
322
|
$(_destinationWidgetDPT).val(optVal);
|
|
318
323
|
}
|
|
319
|
-
});
|
|
324
|
+
});
|
|
320
325
|
}
|
|
321
326
|
|
|
322
327
|
getDPT("1.", "#node-input-dptLightSwitch")
|
|
@@ -376,18 +381,18 @@
|
|
|
376
381
|
|
|
377
382
|
// Show/Hide the div of the color at swich on
|
|
378
383
|
if (this.specifySwitchOnBrightness === 'yes') {
|
|
379
|
-
$("#
|
|
384
|
+
$("#divColorsAtSwitchOn").show()
|
|
380
385
|
} else {
|
|
381
|
-
$("#
|
|
386
|
+
$("#divColorsAtSwitchOn").hide()
|
|
382
387
|
$("#node-input-colorAtSwitchOnDayTime").val('')
|
|
383
388
|
}
|
|
384
389
|
|
|
385
390
|
$("#node-input-specifySwitchOnBrightness").on('change', function () {
|
|
386
391
|
if ($("#node-input-specifySwitchOnBrightness").val() === 'yes') {
|
|
387
|
-
$("#
|
|
392
|
+
$("#divColorsAtSwitchOn").show()
|
|
388
393
|
if ($("#node-input-colorAtSwitchOnDayTime").val() === '') $("#node-input-colorAtSwitchOnDayTime").val('{ "red": 255, "green": 255, "blue": 255 }')
|
|
389
394
|
} else {
|
|
390
|
-
$("#
|
|
395
|
+
$("#divColorsAtSwitchOn").hide()
|
|
391
396
|
$("#node-input-colorAtSwitchOnDayTime").val('')
|
|
392
397
|
}
|
|
393
398
|
})
|
|
@@ -480,8 +485,16 @@
|
|
|
480
485
|
});
|
|
481
486
|
});
|
|
482
487
|
|
|
483
|
-
|
|
488
|
+
for (let index = 1; index <= 90; index++) {
|
|
489
|
+
$('#node-input-minDimLevelLight').append($('<option>').val(index).text(index.toString() + "%"))
|
|
490
|
+
}
|
|
491
|
+
$('#node-input-minDimLevelLight').val(node.minDimLevelLight)
|
|
492
|
+
for (let index = 100; index >= 10; index--) {
|
|
493
|
+
$('#node-input-maxDimLevelLight').append($('<option>').val(index).text(index.toString() + "%"))
|
|
494
|
+
}
|
|
495
|
+
$('#node-input-maxDimLevelLight').val(node.maxDimLevelLight)
|
|
484
496
|
|
|
497
|
+
if (this.hueDevice !== "") $('#tabs').show();
|
|
485
498
|
},
|
|
486
499
|
oneditsave: function () {
|
|
487
500
|
RED.sidebar.removeTab("tabNRColor");
|
|
@@ -496,7 +509,6 @@
|
|
|
496
509
|
</script>
|
|
497
510
|
<script src="https://kit.fontawesome.com/11f26b4500.js" crossorigin="anonymous"></script>
|
|
498
511
|
<script src="https://cdn.jsdelivr.net/npm/@jaames/iro@5"></script>
|
|
499
|
-
<!-- <script src="https://wzrd.in/standalone/copy-to-clipboard@latest" async></script> -->
|
|
500
512
|
|
|
501
513
|
<script type="text/html" data-template-name="knxUltimateHueLight">
|
|
502
514
|
|
|
@@ -553,7 +565,7 @@
|
|
|
553
565
|
<div id="tabs-1">
|
|
554
566
|
<p>
|
|
555
567
|
<div class="form-row">
|
|
556
|
-
<label for="node-input-nameLightSwitch" style="width:110px;"><i class="fa fa-play-circle-o"></i>
|
|
568
|
+
<label for="node-input-nameLightSwitch" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control</label>
|
|
557
569
|
|
|
558
570
|
<label for="node-input-GALightSwitch" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightSwitch"></span></label>
|
|
559
571
|
<input type="text" id="node-input-GALightSwitch" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
@@ -581,7 +593,7 @@
|
|
|
581
593
|
<div id="tabs-2">
|
|
582
594
|
<p>
|
|
583
595
|
<div class="form-row">
|
|
584
|
-
<label for="node-input-nameLightDIM" style="width:110px;"><i class="fa fa-play-circle-o"></i>
|
|
596
|
+
<label for="node-input-nameLightDIM" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control</label>
|
|
585
597
|
|
|
586
598
|
<label for="node-input-GALightDIM" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
|
|
587
599
|
<input type="text" id="node-input-GALightDIM" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
@@ -593,7 +605,7 @@
|
|
|
593
605
|
<input type="text" id="node-input-nameLightDIM" style="width:190px;margin-left: 5px; text-align: left;">
|
|
594
606
|
</div>
|
|
595
607
|
<div class="form-row">
|
|
596
|
-
<label for="node-input-nameLightBrightness" style="width:110px;"><i class="fa fa-play-circle-o"></i>
|
|
608
|
+
<label for="node-input-nameLightBrightness" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control %</label>
|
|
597
609
|
|
|
598
610
|
<label for="node-input-GALightBrightness" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
|
|
599
611
|
<input type="text" id="node-input-GALightBrightness" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
@@ -622,7 +634,7 @@
|
|
|
622
634
|
<div id="tabs-3">
|
|
623
635
|
<p>
|
|
624
636
|
<div class="form-row">
|
|
625
|
-
<label for="node-input-nameLightHSV" style="width:110px;"><i class="fa fa-play-circle-o"></i>
|
|
637
|
+
<label for="node-input-nameLightHSV" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control</label>
|
|
626
638
|
|
|
627
639
|
<label for="node-input-GALightHSV" style="width:20px;">GA</label>
|
|
628
640
|
<input type="text" id="node-input-GALightHSV" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
@@ -634,7 +646,7 @@
|
|
|
634
646
|
<input type="text" id="node-input-nameLightHSV" style="width:190px;margin-left: 5px; text-align: left;">
|
|
635
647
|
</div>
|
|
636
648
|
<div class="form-row">
|
|
637
|
-
<label for="node-input-nameLightHSVPercentage" style="width:110px;"><i class="fa fa-play-circle-o"></i>
|
|
649
|
+
<label for="node-input-nameLightHSVPercentage" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control %</label>
|
|
638
650
|
|
|
639
651
|
<label for="node-input-GALightHSVPercentage" style="width:20px;">GA</label>
|
|
640
652
|
<input type="text" id="node-input-GALightHSVPercentage" placeholder="Ex: 1/1/1"
|
|
@@ -663,7 +675,7 @@
|
|
|
663
675
|
<div id="tabs-4">
|
|
664
676
|
<p>
|
|
665
677
|
<div class="form-row">
|
|
666
|
-
<label for="node-input-nameLightColor" style="width:110px;"><i class="fa fa-play-circle-o"></i
|
|
678
|
+
<label for="node-input-nameLightColor" style="width:110px;"><i class="fa fa-play-circle-o"></i> Control</label>
|
|
667
679
|
|
|
668
680
|
<label for="node-input-GALightColor" style="width:20px;"><span data-i18n="knxUltimateHueLight.node-input-GALightState"></span></label>
|
|
669
681
|
<input type="text" id="node-input-GALightColor" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;">
|
|
@@ -739,9 +751,9 @@
|
|
|
739
751
|
<option value="yes">Yes</option>
|
|
740
752
|
<option value="no">No</option>
|
|
741
753
|
</select>
|
|
742
|
-
</div>
|
|
743
|
-
|
|
744
|
-
<div class="form-row"
|
|
754
|
+
</div>
|
|
755
|
+
<div id="divColorsAtSwitchOn">
|
|
756
|
+
<div class="form-row" >
|
|
745
757
|
<label for="node-input-colorAtSwitchOnDayTime" style="width:260px">
|
|
746
758
|
<i class="fa fa-sun-o"></i> Switch On - color/brightness
|
|
747
759
|
</label>
|
|
@@ -758,6 +770,7 @@
|
|
|
758
770
|
<option value="no">No</option>
|
|
759
771
|
</select>
|
|
760
772
|
</div>
|
|
773
|
+
|
|
761
774
|
<div id="DivEnableDayNightLighting">
|
|
762
775
|
<div class="form-row">
|
|
763
776
|
<label for="node-input-colorAtSwitchOnNightTime" style="width:260px">
|
|
@@ -793,7 +806,28 @@
|
|
|
793
806
|
|
|
794
807
|
</div>
|
|
795
808
|
</div>
|
|
796
|
-
</div>
|
|
809
|
+
</div>
|
|
810
|
+
<div class="form-row">
|
|
811
|
+
<label for="node-input-dimSpeed" style="width:260px">
|
|
812
|
+
<i class="fa fa-bolt"></i> Dim Speed (ms)
|
|
813
|
+
</label>
|
|
814
|
+
<input type="text" id="node-input-dimSpeed" placeholder='5000' style="width:260px">
|
|
815
|
+
</div>
|
|
816
|
+
<div class="form-row">
|
|
817
|
+
<label for="node-input-minDimLevelLight" style="width:260px;">
|
|
818
|
+
<i class="fa fa-clone"></i> Min Dim Brightness
|
|
819
|
+
</label>
|
|
820
|
+
<select id="node-input-minDimLevelLight">
|
|
821
|
+
<option value="useHueLightLevel">Use minimum brightness specified in the HUE light</option>
|
|
822
|
+
</select>
|
|
823
|
+
</div>
|
|
824
|
+
<div class="form-row">
|
|
825
|
+
<label for="node-input-maxDimLevelLight" style="width:260px;">
|
|
826
|
+
<i class="fa fa-clone"></i> Max Dim Brightness
|
|
827
|
+
</label>
|
|
828
|
+
<select id="node-input-maxDimLevelLight"></select>
|
|
829
|
+
</div>
|
|
830
|
+
|
|
797
831
|
</p>
|
|
798
832
|
</div>
|
|
799
833
|
|
|
@@ -820,7 +854,7 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
820
854
|
**Switching**
|
|
821
855
|
|Property|Description|
|
|
822
856
|
|--|--|
|
|
823
|
-
|
|
|
857
|
+
| Control | This GA is used to turn on/off the HUE light via a boolean KNX value true/false|
|
|
824
858
|
| Status | Link this to the light's switch status group address|
|
|
825
859
|
|
|
826
860
|
<br/>
|
|
@@ -828,8 +862,8 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
828
862
|
**Dim/Brightness**
|
|
829
863
|
|Property|Description|
|
|
830
864
|
|--|--|
|
|
831
|
-
|
|
|
832
|
-
|
|
|
865
|
+
| Control | Relative DIM the HUE light. You can set the dimming speed in the ***Behaviour*** tab. |
|
|
866
|
+
| Control % | Changes the absolute HUE light's brightness (0-100%)|
|
|
833
867
|
| Status| Link this to the light's brightness status group address |
|
|
834
868
|
|
|
835
869
|
<br/>
|
|
@@ -837,8 +871,8 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
837
871
|
**Tunable white**
|
|
838
872
|
|Property|Description|
|
|
839
873
|
|--|--|
|
|
840
|
-
|
|
|
841
|
-
|
|
|
874
|
+
| Control| Changes the HUE light's white temperature, using DPT 3.007 dimming. You can set the dimming speed in the ***Behaviour*** tab.|
|
|
875
|
+
| Control % | Changes the HUE light's white temperature, using the DPT 5.001. A value of 0 is full warm, a value of 100 is full cold.|
|
|
842
876
|
| Status | Link this to the light temperature status group address. Datapoint is 5.001 absolute value. 0 is full warm, 100 is full cold.|
|
|
843
877
|
|
|
844
878
|
<br/>
|
|
@@ -846,7 +880,7 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
846
880
|
**Colors**
|
|
847
881
|
|Property|Description|
|
|
848
882
|
|--|--|
|
|
849
|
-
|
|
|
883
|
+
| Control | This command is used to change the HUE light's color. Accepted datapoint is RGB triplet (r,g,b). The node handles the gamut color correction. As soon as you send a color KNX telegran, the light turns on and sets color and brightness, derived from the brightness human perception. As soon as you send a KNX telegram with r,g,b set to zero, the light turns off |
|
|
850
884
|
| Status | Link this to the light's color status group address. Accepted datapoint is RGB triplet (r,g,b)|
|
|
851
885
|
|
|
852
886
|
<br/>
|
|
@@ -870,6 +904,12 @@ Start typing in the GA field, the name or group address of your KNX device, the
|
|
|
870
904
|
| Switch On - color/brightness at Nighttime | You can choose the color/brightness of your light, at switch on, on night time. Set it as JSON object. Default value if you leave blank is **{ "red": 100, "green": 0, "blue": 0 }** |
|
|
871
905
|
| Day/Night | Select the group address used to set the day/night behaviour. The group address value is *true* if daytime, *false* if nighttime. |
|
|
872
906
|
| Invert day/night values | Invert the values of *Day/Night* group address. Default value is **unchecked**.|
|
|
907
|
+
| Dim Speed (ms) | The dimming speed, in Milliseconds. This applies to the **light** and also to the **tunable white** dimming datapoints. It' calculated from 0% to 100%.|
|
|
908
|
+
| Min Dim brightness | Tha Minimum brightness that the lamp can reach. For example, if you are dimming the light down, the light will stop dimming at the specified brightness %. |
|
|
909
|
+
| Max Dim brightness | Tha Maximum brightness that the lamp can reach. For example, if you are dimming the light up, the light will stop dimming at the specified brightness %. |
|
|
910
|
+
|
|
911
|
+
### Note
|
|
912
|
+
The Dimming function works in **KNX mode `start` and `stop`**. To start dimming, send only one "start" KNX telegram. To stop dimming, send a "stop" KNX telegram. Please **remember that**, when you set your wall swiches properties.
|
|
873
913
|
|
|
874
914
|
<br/>
|
|
875
915
|
|