node-red-contrib-huemagic 4.1.0 → 4.2.2
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 +77 -2
- package/README.md +20 -13
- package/huemagic/hue-bridge-config.html +2 -2
- package/huemagic/hue-bridge-config.js +133 -71
- package/huemagic/hue-brightness.js +26 -4
- package/huemagic/hue-buttons.js +1 -1
- package/huemagic/hue-group.js +149 -56
- package/huemagic/hue-light.js +192 -72
- package/huemagic/hue-magic.html +0 -2
- package/huemagic/hue-motion.js +27 -5
- package/huemagic/hue-rules.js +26 -7
- package/huemagic/hue-scene.js +62 -16
- package/huemagic/hue-temperature.js +26 -4
- package/huemagic/locales/de/hue-bridge-config.html +1 -1
- package/huemagic/utils/api.js +11 -17
- package/huemagic/utils/messages.js +52 -50
- package/package.json +6 -3
package/huemagic/hue-group.js
CHANGED
|
@@ -8,6 +8,7 @@ module.exports = function(RED)
|
|
|
8
8
|
|
|
9
9
|
const scope = this;
|
|
10
10
|
const bridge = RED.nodes.getNode(config.bridge);
|
|
11
|
+
const async = require('async');
|
|
11
12
|
|
|
12
13
|
// EXPORT CONFIG
|
|
13
14
|
this.exportedConfig = config;
|
|
@@ -112,7 +113,7 @@ module.exports = function(RED)
|
|
|
112
113
|
let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
|
|
113
114
|
if(!currentState)
|
|
114
115
|
{
|
|
115
|
-
scope.error("The group in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid
|
|
116
|
+
scope.error("The group in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid.");
|
|
116
117
|
return false;
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -158,18 +159,41 @@ module.exports = function(RED)
|
|
|
158
159
|
"bri": msg.payload.brightness ? Math.round((254/100)*msg.payload.brightness) : 254
|
|
159
160
|
};
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
162
|
+
// PATCH!
|
|
163
|
+
async.retry({
|
|
164
|
+
times: 3,
|
|
165
|
+
errorFilter: function(err) {
|
|
166
|
+
return (err.status == 503);
|
|
167
|
+
},
|
|
168
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
169
|
+
},
|
|
170
|
+
function(callback, results)
|
|
171
|
+
{
|
|
172
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
173
|
+
.then(function(status) {
|
|
174
|
+
// RESET COLORLOOP ANIMATION AFTER X SECONDS
|
|
175
|
+
setTimeout(function()
|
|
176
|
+
{
|
|
177
|
+
bridge.patch("group", currentState.info.idV1 + "/action", { "effect": "none" }, 1)
|
|
178
|
+
.then(function() { if(done) { done(); }});
|
|
179
|
+
}, parseInt(msg.payload.colorloop) * 1000);
|
|
180
|
+
callback(null, true);
|
|
181
|
+
})
|
|
182
|
+
.catch(function(errors) {
|
|
183
|
+
callback(errors, null);
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
function(errors, success)
|
|
187
|
+
{
|
|
188
|
+
if(errors)
|
|
189
|
+
{
|
|
190
|
+
scope.error(errors);
|
|
191
|
+
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
192
|
+
}
|
|
193
|
+
else if(done)
|
|
194
|
+
{
|
|
195
|
+
done();
|
|
196
|
+
}
|
|
173
197
|
});
|
|
174
198
|
|
|
175
199
|
return false;
|
|
@@ -240,42 +264,65 @@ module.exports = function(RED)
|
|
|
240
264
|
// SET ALERT EFFECT
|
|
241
265
|
patchObject["alert"] = "lselect";
|
|
242
266
|
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
267
|
+
// PATCH!
|
|
268
|
+
async.retry({
|
|
269
|
+
times: 3,
|
|
270
|
+
errorFilter: function(err) {
|
|
271
|
+
return (err.status == 503);
|
|
272
|
+
},
|
|
273
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
274
|
+
},
|
|
275
|
+
function(callback, results)
|
|
276
|
+
{
|
|
277
|
+
// 1. TURN ON THE LIGHT BULB
|
|
278
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
279
|
+
.then(function(status)
|
|
247
280
|
{
|
|
248
|
-
|
|
249
|
-
var tempPreviousStatePatch = {};
|
|
250
|
-
|
|
251
|
-
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
252
|
-
if(tempPreviousState.payload.xyColor)
|
|
253
|
-
{
|
|
254
|
-
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
|
|
255
|
-
}
|
|
256
|
-
else if(tempPreviousState.payload.colorTemp)
|
|
281
|
+
setTimeout(function()
|
|
257
282
|
{
|
|
258
|
-
|
|
259
|
-
|
|
283
|
+
const tempPreviousState = scope.context().get('groupPreviousState');
|
|
284
|
+
var tempPreviousStatePatch = {};
|
|
260
285
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
{
|
|
264
|
-
return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
|
|
265
|
-
})
|
|
266
|
-
.then(function(status) {
|
|
267
|
-
if(done) { done(); }
|
|
268
|
-
if(tempPreviousState.payload.on === true)
|
|
286
|
+
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
287
|
+
if(tempPreviousState.payload.xyColor)
|
|
269
288
|
{
|
|
270
|
-
|
|
289
|
+
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
|
|
271
290
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
291
|
+
else if(tempPreviousState.payload.colorTemp)
|
|
292
|
+
{
|
|
293
|
+
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
bridge.patch("group", currentState.info.idV1 + "/action", tempPreviousStatePatch, 1)
|
|
297
|
+
.then(function(status)
|
|
298
|
+
{
|
|
299
|
+
return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
|
|
300
|
+
})
|
|
301
|
+
.then(function(status) {
|
|
302
|
+
if(tempPreviousState.payload.on === true)
|
|
303
|
+
{
|
|
304
|
+
bridge.patch("group", currentState.info.idV1, { on: true }, 1);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}, parseInt(msg.payload.alert) * 1000);
|
|
308
|
+
|
|
309
|
+
callback(null, true);
|
|
310
|
+
})
|
|
311
|
+
.catch(function(errors) {
|
|
312
|
+
callback(errors, null);
|
|
313
|
+
});
|
|
314
|
+
},
|
|
315
|
+
function(errors, success)
|
|
316
|
+
{
|
|
317
|
+
if(errors)
|
|
318
|
+
{
|
|
319
|
+
scope.error(errors);
|
|
320
|
+
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
321
|
+
}
|
|
322
|
+
else if(done)
|
|
323
|
+
{
|
|
324
|
+
done();
|
|
325
|
+
}
|
|
279
326
|
});
|
|
280
327
|
}
|
|
281
328
|
// ANIMATION STARTED?
|
|
@@ -300,19 +347,44 @@ module.exports = function(RED)
|
|
|
300
347
|
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
|
|
301
348
|
}
|
|
302
349
|
|
|
303
|
-
|
|
304
|
-
|
|
350
|
+
// PATCH!
|
|
351
|
+
async.retry({
|
|
352
|
+
times: 3,
|
|
353
|
+
errorFilter: function(err) {
|
|
354
|
+
return (err.status == 503);
|
|
355
|
+
},
|
|
356
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
357
|
+
},
|
|
358
|
+
function(callback, results)
|
|
305
359
|
{
|
|
306
|
-
|
|
360
|
+
bridge.patch("light", currentState.info.lightIds[l], tempPreviousStatePatch).
|
|
361
|
+
then(function(status)
|
|
307
362
|
{
|
|
308
|
-
|
|
363
|
+
if(tempPreviousState.payload.on === false)
|
|
364
|
+
{
|
|
365
|
+
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
|
|
366
|
+
.then(function() { callback(null, true); });
|
|
367
|
+
}
|
|
368
|
+
else
|
|
369
|
+
{
|
|
370
|
+
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
|
|
371
|
+
.then(function(status) {
|
|
372
|
+
callback(null, true);
|
|
373
|
+
return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } });
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
})
|
|
377
|
+
.catch(function(errors) { callback(errors, null); });
|
|
378
|
+
},
|
|
379
|
+
function(errors, success)
|
|
380
|
+
{
|
|
381
|
+
if(errors)
|
|
382
|
+
{
|
|
383
|
+
scope.error(errors);
|
|
309
384
|
}
|
|
310
|
-
else
|
|
385
|
+
else if(done)
|
|
311
386
|
{
|
|
312
|
-
|
|
313
|
-
.then(function(status) {
|
|
314
|
-
return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } })
|
|
315
|
-
});
|
|
387
|
+
done();
|
|
316
388
|
}
|
|
317
389
|
});
|
|
318
390
|
}
|
|
@@ -516,9 +588,30 @@ module.exports = function(RED)
|
|
|
516
588
|
}
|
|
517
589
|
|
|
518
590
|
// PATCH!
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
591
|
+
async.retry({
|
|
592
|
+
times: 3,
|
|
593
|
+
errorFilter: function(err) {
|
|
594
|
+
return (err.status == 503);
|
|
595
|
+
},
|
|
596
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
597
|
+
},
|
|
598
|
+
function(callback, results)
|
|
599
|
+
{
|
|
600
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
601
|
+
.then(function() { callback(null, true); })
|
|
602
|
+
.catch(function(errors) { callback(errors, null); });
|
|
603
|
+
},
|
|
604
|
+
function(errors, success)
|
|
605
|
+
{
|
|
606
|
+
if(errors)
|
|
607
|
+
{
|
|
608
|
+
scope.error(errors);
|
|
609
|
+
}
|
|
610
|
+
else if(done)
|
|
611
|
+
{
|
|
612
|
+
done();
|
|
613
|
+
}
|
|
614
|
+
});
|
|
522
615
|
}
|
|
523
616
|
else
|
|
524
617
|
{
|
package/huemagic/hue-light.js
CHANGED
|
@@ -8,6 +8,7 @@ module.exports = function(RED)
|
|
|
8
8
|
|
|
9
9
|
const scope = this;
|
|
10
10
|
const bridge = RED.nodes.getNode(config.bridge);
|
|
11
|
+
const async = require('async');
|
|
11
12
|
|
|
12
13
|
// SAVE FUTURE PATCH
|
|
13
14
|
this.futurePatchState = {};
|
|
@@ -125,7 +126,7 @@ module.exports = function(RED)
|
|
|
125
126
|
let currentState = bridge.get("light", tempLightID, { colornames: config.colornamer ? true : false });
|
|
126
127
|
if(!currentState)
|
|
127
128
|
{
|
|
128
|
-
scope.error("The light in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid
|
|
129
|
+
scope.error("The light in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid.");
|
|
129
130
|
return false;
|
|
130
131
|
}
|
|
131
132
|
|
|
@@ -171,18 +172,43 @@ module.exports = function(RED)
|
|
|
171
172
|
"bri": msg.payload.brightness ? Math.round((254/100)*msg.payload.brightness) : currentState.brightnessLevel
|
|
172
173
|
};
|
|
173
174
|
|
|
174
|
-
|
|
175
|
-
.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
175
|
+
// PATCH!
|
|
176
|
+
async.retry({
|
|
177
|
+
times: 3,
|
|
178
|
+
errorFilter: function(err) {
|
|
179
|
+
return (err.status == 503);
|
|
180
|
+
},
|
|
181
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
182
|
+
},
|
|
183
|
+
function(callback, results)
|
|
184
|
+
{
|
|
185
|
+
bridge.patch("light", currentState.info.idV1 + "/state", patchObject, 1)
|
|
186
|
+
.then(function(status)
|
|
187
|
+
{
|
|
188
|
+
// RESET COLORLOOP ANIMATION AFTER X SECONDS
|
|
189
|
+
setTimeout(function()
|
|
190
|
+
{
|
|
191
|
+
bridge.patch("light", currentState.info.idV1 + "/state", { "effect": "none" }, 1);
|
|
192
|
+
}, parseInt(msg.payload.colorloop) * 1000);
|
|
193
|
+
|
|
194
|
+
callback(null, true);
|
|
195
|
+
})
|
|
196
|
+
.catch(function(errors)
|
|
197
|
+
{
|
|
198
|
+
callback(errors, null);
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
function(errors, success)
|
|
202
|
+
{
|
|
203
|
+
if(errors)
|
|
204
|
+
{
|
|
205
|
+
scope.error(errors);
|
|
206
|
+
scope.status({fill: "red", shape: "ring", text: "hue-light.node.error-input"});
|
|
207
|
+
}
|
|
208
|
+
else if(done)
|
|
209
|
+
{
|
|
210
|
+
done();
|
|
211
|
+
}
|
|
186
212
|
});
|
|
187
213
|
|
|
188
214
|
return false;
|
|
@@ -261,48 +287,72 @@ module.exports = function(RED)
|
|
|
261
287
|
scope.status({fill: "grey", shape: "ring", text: "hue-light.node.command"});
|
|
262
288
|
}
|
|
263
289
|
|
|
264
|
-
// 1. TURN ON THE LIGHT BULB
|
|
265
|
-
bridge.patch("light", tempLightID, patchObject)
|
|
266
|
-
.then(function(status) {
|
|
267
|
-
// 2. APPLY ALERT EFFECT
|
|
268
|
-
const alertEffect = { alert: { action: "breathe" }};
|
|
269
|
-
return bridge.patch("light", tempLightID, alertEffect);
|
|
270
|
-
})
|
|
271
|
-
.then(function(status) {
|
|
272
|
-
// 3. RESET PREVIOUS STATE (AFTER X SECONDS)
|
|
273
|
-
setTimeout(function()
|
|
274
|
-
{
|
|
275
|
-
const tempPreviousState = scope.context().get('lightPreviousState');
|
|
276
|
-
var tempPreviousStatePatch = {};
|
|
277
|
-
|
|
278
|
-
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
279
|
-
if(tempPreviousState.payload.xyColor)
|
|
280
|
-
{
|
|
281
|
-
tempPreviousStatePatch.color = { xy: tempPreviousState.payload.xyColor };
|
|
282
|
-
}
|
|
283
|
-
else if(tempPreviousState.payload.colorTemp)
|
|
284
|
-
{
|
|
285
|
-
tempPreviousStatePatch.color_temperature = { mirek: tempPreviousState.payload.colorTemp };
|
|
286
|
-
}
|
|
287
290
|
|
|
288
|
-
|
|
289
|
-
|
|
291
|
+
// APPLY THE EFFECT
|
|
292
|
+
async.retry({
|
|
293
|
+
times: 3,
|
|
294
|
+
errorFilter: function(err) {
|
|
295
|
+
return (err.status == 503);
|
|
296
|
+
},
|
|
297
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
298
|
+
},
|
|
299
|
+
function(callback, results)
|
|
300
|
+
{
|
|
301
|
+
// 1. TURN ON THE LIGHT BULB
|
|
302
|
+
bridge.patch("light", tempLightID, patchObject)
|
|
303
|
+
.then(function(status) {
|
|
304
|
+
// 2. APPLY ALERT EFFECT
|
|
305
|
+
const alertEffect = { alert: { action: "breathe" }};
|
|
306
|
+
return bridge.patch("light", tempLightID, alertEffect);
|
|
307
|
+
})
|
|
308
|
+
.then(function(status) {
|
|
309
|
+
// 3. RESET PREVIOUS STATE (AFTER X SECONDS)
|
|
310
|
+
setTimeout(function()
|
|
290
311
|
{
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if(tempPreviousState.payload.
|
|
312
|
+
const tempPreviousState = scope.context().get('lightPreviousState');
|
|
313
|
+
var tempPreviousStatePatch = {};
|
|
314
|
+
|
|
315
|
+
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
316
|
+
if(tempPreviousState.payload.xyColor)
|
|
296
317
|
{
|
|
297
|
-
|
|
298
|
-
|
|
318
|
+
tempPreviousStatePatch.color = { xy: tempPreviousState.payload.xyColor };
|
|
319
|
+
}
|
|
320
|
+
else if(tempPreviousState.payload.colorTemp)
|
|
321
|
+
{
|
|
322
|
+
tempPreviousStatePatch.color_temperature = { mirek: tempPreviousState.payload.colorTemp };
|
|
299
323
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
324
|
+
|
|
325
|
+
bridge.patch("light", tempLightID, tempPreviousStatePatch).
|
|
326
|
+
then(function(status)
|
|
327
|
+
{
|
|
328
|
+
return bridge.patch("light", tempLightID, { on: { on: false } })
|
|
329
|
+
.then(function() { if(done) { done(); }});
|
|
330
|
+
})
|
|
331
|
+
.then(function(status) {
|
|
332
|
+
if(tempPreviousState.payload.on === true)
|
|
333
|
+
{
|
|
334
|
+
bridge.patch("light", tempLightID, { on: { on: true } })
|
|
335
|
+
.then(function() { if(done) { done(); }});
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}, parseInt(msg.payload.alert) * 1000);
|
|
339
|
+
callback(null, true);
|
|
340
|
+
})
|
|
341
|
+
.catch(function(errors) {
|
|
342
|
+
callback(errors, null);
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
function(errors, success)
|
|
346
|
+
{
|
|
347
|
+
if(errors)
|
|
348
|
+
{
|
|
349
|
+
scope.error(errors);
|
|
350
|
+
scope.status({fill: "red", shape: "ring", text: "hue-light.node.error-input"});
|
|
351
|
+
}
|
|
352
|
+
else if(done)
|
|
353
|
+
{
|
|
354
|
+
done();
|
|
355
|
+
}
|
|
306
356
|
});
|
|
307
357
|
}
|
|
308
358
|
// ANIMATION STARTED?
|
|
@@ -327,21 +377,44 @@ module.exports = function(RED)
|
|
|
327
377
|
tempPreviousStatePatch.color_temperature = { mirek: tempPreviousState.payload.colorTemp };
|
|
328
378
|
}
|
|
329
379
|
|
|
330
|
-
|
|
331
|
-
|
|
380
|
+
// PATCH!
|
|
381
|
+
async.retry({
|
|
382
|
+
times: 3,
|
|
383
|
+
errorFilter: function(err) {
|
|
384
|
+
return (err.status == 503);
|
|
385
|
+
},
|
|
386
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
387
|
+
},
|
|
388
|
+
function(callback, results)
|
|
332
389
|
{
|
|
333
|
-
|
|
390
|
+
bridge.patch("light", tempLightID, tempPreviousStatePatch)
|
|
391
|
+
.then(function(status)
|
|
334
392
|
{
|
|
335
|
-
|
|
336
|
-
|
|
393
|
+
if(tempPreviousState.payload.on === false)
|
|
394
|
+
{
|
|
395
|
+
bridge.patch("light", tempLightID, { on: { on: false } })
|
|
396
|
+
.then(function() { callback(null, true); });
|
|
397
|
+
}
|
|
398
|
+
else
|
|
399
|
+
{
|
|
400
|
+
bridge.patch("light", tempLightID, { on: { on: false } })
|
|
401
|
+
.then(function(status) {
|
|
402
|
+
callback(null, true);
|
|
403
|
+
return bridge.patch("light", tempLightID, { on: { on: true } });
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
})
|
|
407
|
+
.catch(function(errors) { callback(errors, null); });
|
|
408
|
+
},
|
|
409
|
+
function(errors, success)
|
|
410
|
+
{
|
|
411
|
+
if(errors)
|
|
412
|
+
{
|
|
413
|
+
scope.error(errors);
|
|
337
414
|
}
|
|
338
|
-
else
|
|
415
|
+
else if(done)
|
|
339
416
|
{
|
|
340
|
-
|
|
341
|
-
.then(function(status) {
|
|
342
|
-
if(done) { done(); }
|
|
343
|
-
return bridge.patch("light", tempLightID, { on: { on: true } })
|
|
344
|
-
});
|
|
417
|
+
done();
|
|
345
418
|
}
|
|
346
419
|
});
|
|
347
420
|
}
|
|
@@ -613,16 +686,42 @@ module.exports = function(RED)
|
|
|
613
686
|
}
|
|
614
687
|
|
|
615
688
|
// SET DOMINANT COLORS FROM IMAGE
|
|
616
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.image != 'undefined' && typeof currentState.payload.xyColor != 'undefined')
|
|
689
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.image != 'undefined' && (typeof currentState.payload.xyColor != 'undefined' || typeof currentState.payload.gradient != 'undefined'))
|
|
617
690
|
{
|
|
618
|
-
|
|
691
|
+
let colors = await colorUtils.getColors(msg.payload.image);
|
|
619
692
|
if(colors.length > 0)
|
|
620
693
|
{
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
694
|
+
let colorsHEX = colors.map(color => color.hex());
|
|
695
|
+
|
|
696
|
+
// SET MULTIPLE COLORS ON SUPPORTED LIGHTS
|
|
697
|
+
if(typeof currentState.payload.gradient != 'undefined')
|
|
698
|
+
{
|
|
699
|
+
let XYColorSet = [];
|
|
700
|
+
|
|
701
|
+
for (var i = 0; i < currentState.payload.gradient.totalColors; i++)
|
|
702
|
+
{
|
|
703
|
+
if(typeof colorsHEX[i] != 'undefined')
|
|
704
|
+
{
|
|
705
|
+
let rgbFromHex = colorUtils.hexRgb(colorsHEX[i]);
|
|
706
|
+
XYColorSet.push({
|
|
707
|
+
color: { xy: colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2], currentState.info.model.colorGamut) }
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if(XYColorSet.length > 0)
|
|
713
|
+
{
|
|
714
|
+
patchObject["gradient"] = { points: XYColorSet };
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
// SET SINGLE COLOR
|
|
718
|
+
else
|
|
719
|
+
{
|
|
720
|
+
let rgbFromHex = colorUtils.hexRgb(colorsHEX[0]);
|
|
721
|
+
patchObject["color"] = {
|
|
722
|
+
xy: colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2], currentState.info.model.colorGamut)
|
|
723
|
+
};
|
|
724
|
+
}
|
|
626
725
|
}
|
|
627
726
|
}
|
|
628
727
|
|
|
@@ -718,9 +817,30 @@ module.exports = function(RED)
|
|
|
718
817
|
}
|
|
719
818
|
|
|
720
819
|
// PATCH!
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
820
|
+
async.retry({
|
|
821
|
+
times: 3,
|
|
822
|
+
errorFilter: function(err) {
|
|
823
|
+
return (err.status == 503);
|
|
824
|
+
},
|
|
825
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
826
|
+
},
|
|
827
|
+
function(callback, results)
|
|
828
|
+
{
|
|
829
|
+
bridge.patch("light", tempLightID, patchObject)
|
|
830
|
+
.then(function() { callback(null, true); })
|
|
831
|
+
.catch(function(errors) { callback(errors, null); });
|
|
832
|
+
},
|
|
833
|
+
function(errors, success)
|
|
834
|
+
{
|
|
835
|
+
if(errors)
|
|
836
|
+
{
|
|
837
|
+
scope.error(errors);
|
|
838
|
+
}
|
|
839
|
+
else if(done)
|
|
840
|
+
{
|
|
841
|
+
done();
|
|
842
|
+
}
|
|
843
|
+
});
|
|
724
844
|
}
|
|
725
845
|
else
|
|
726
846
|
{
|
package/huemagic/hue-magic.html
CHANGED
package/huemagic/hue-motion.js
CHANGED
|
@@ -8,6 +8,7 @@ module.exports = function(RED)
|
|
|
8
8
|
|
|
9
9
|
const scope = this;
|
|
10
10
|
const bridge = RED.nodes.getNode(config.bridge);
|
|
11
|
+
const async = require('async');
|
|
11
12
|
|
|
12
13
|
// SAVE LAST COMMAND
|
|
13
14
|
this.lastCommand = null;
|
|
@@ -110,7 +111,7 @@ module.exports = function(RED)
|
|
|
110
111
|
let currentState = bridge.get("motion", tempSensorID);
|
|
111
112
|
if(!currentState)
|
|
112
113
|
{
|
|
113
|
-
scope.error("The sensor in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid
|
|
114
|
+
scope.error("The sensor in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid.");
|
|
114
115
|
return false;
|
|
115
116
|
}
|
|
116
117
|
|
|
@@ -151,9 +152,30 @@ module.exports = function(RED)
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
// PATCH!
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
async.retry({
|
|
156
|
+
times: 3,
|
|
157
|
+
errorFilter: function(err) {
|
|
158
|
+
return (err.status == 503);
|
|
159
|
+
},
|
|
160
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
161
|
+
},
|
|
162
|
+
function(callback, results)
|
|
163
|
+
{
|
|
164
|
+
bridge.patch("motion", tempSensorID, patchObject)
|
|
165
|
+
.then(function() { if(done) { callback(null, true); }})
|
|
166
|
+
.catch(function(errors) { callback(errors, null); });
|
|
167
|
+
},
|
|
168
|
+
function(errors, success)
|
|
169
|
+
{
|
|
170
|
+
if(errors)
|
|
171
|
+
{
|
|
172
|
+
scope.error(errors);
|
|
173
|
+
}
|
|
174
|
+
else if(done)
|
|
175
|
+
{
|
|
176
|
+
done();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
157
179
|
}
|
|
158
180
|
else
|
|
159
181
|
{
|
|
@@ -175,4 +197,4 @@ module.exports = function(RED)
|
|
|
175
197
|
}
|
|
176
198
|
|
|
177
199
|
RED.nodes.registerType("hue-motion", HueMotion);
|
|
178
|
-
}
|
|
200
|
+
}
|