node-red-contrib-huemagic 4.1.0 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/huemagic/hue-bridge-config.html +2 -2
- package/huemagic/hue-bridge-config.js +130 -70
- 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-motion.js +26 -4
- 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 +3 -10
- package/huemagic/utils/messages.js +52 -50
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -796,11 +796,21 @@ If the status of the node has changed via a certain command, the entire command
|
|
|
796
796
|
|
|
797
797
|
# Changelog
|
|
798
798
|
|
|
799
|
-
### v4.
|
|
799
|
+
### v4.2.0 (latest)
|
|
800
|
+
|
|
801
|
+
* Commands are now re-executed up to three times if they fail due to a bridge timeout
|
|
802
|
+
* The "image" option on the "Hue Light" node will now set the corresponding gradient colors on supported resources
|
|
803
|
+
* Better handling of broken connections to the bridge ([#309](https://github.com/Foddy/node-red-contrib-huemagic/pull/309)) (thx)
|
|
804
|
+
* Fixed an error with the "Hue Scenes" node on newer bridge firmwares ([#335](https://github.com/Foddy/node-red-contrib-huemagic/issues/335)) ([#339](https://github.com/Foddy/node-red-contrib-huemagic/pull/339)) (thx)
|
|
805
|
+
* Fixed an uncaught exception on newer bridge firmwares ([#302](https://github.com/Foddy/node-red-contrib-huemagic/issues/302)) ([#309](https://github.com/Foddy/node-red-contrib-huemagic/pull/309)) (thx)
|
|
806
|
+
* Updated dependencies to the latest versions
|
|
807
|
+
* Fixed some typos here and there
|
|
808
|
+
|
|
809
|
+
### v4.1.0
|
|
800
810
|
|
|
801
811
|
* New queue worker throttles the number of parallel requests to the bridge to avoid 503 API limit errors (can be configured in the Bridge configuration)
|
|
802
|
-
* Resources are now alphabetically sorted in the node´s configuration
|
|
803
|
-
* "Hue
|
|
812
|
+
* Resources are now alphabetically sorted in the node´s configuration interface ([#282](https://github.com/Foddy/node-red-contrib-huemagic/pull/282)) (thx)
|
|
813
|
+
* "Hue Brightness" node was optimized to output more accurate "dark" and "dayLight" values
|
|
804
814
|
* Several optimizations in the documentation of some nodes
|
|
805
815
|
|
|
806
816
|
### v4.0.5
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
name: { value:"Hue Bridge", required: true },
|
|
52
52
|
bridge: { value:"", required: true },
|
|
53
53
|
key: { value:"", required: true },
|
|
54
|
-
worker: { value: 10, required: true, validate:function(v) {
|
|
55
|
-
return (!isNaN(v) && v > 0)
|
|
54
|
+
worker: { value: 10, required: true, validate: function(v) {
|
|
55
|
+
return (!isNaN(v) && v > 0);
|
|
56
56
|
}},
|
|
57
57
|
autoupdates: { value: true },
|
|
58
58
|
disableupdates: { value: false }
|
|
@@ -34,6 +34,7 @@ module.exports = function(RED)
|
|
|
34
34
|
this.lastStates = {};
|
|
35
35
|
this.events = new events.EventEmitter();
|
|
36
36
|
this.patchQueue = null;
|
|
37
|
+
this.timerWatchDog = null; // 31/01/2022 Supergiovane: watchdog for the connection with the bridge
|
|
37
38
|
|
|
38
39
|
// RESOURCE ID PATTERN
|
|
39
40
|
this.validResourceID = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi;
|
|
@@ -44,9 +45,35 @@ module.exports = function(RED)
|
|
|
44
45
|
// CREATE NODE
|
|
45
46
|
RED.nodes.createNode(scope, config);
|
|
46
47
|
|
|
48
|
+
this.startWatchdog = function() {
|
|
49
|
+
// 31/01/2022 Supergiovane: Check wether the bridge is connected.
|
|
50
|
+
if (this.timerWatchDog !== null) clearTimeout(this.timerWatchDog);
|
|
51
|
+
this.timerWatchDog = setTimeout(() => {
|
|
52
|
+
try {
|
|
53
|
+
API.request({ config: config, resource: "/config", version: 1 })
|
|
54
|
+
.then(function(bridgeInformation)
|
|
55
|
+
{
|
|
56
|
+
// The bridge is still connected
|
|
57
|
+
scope.startWatchdog();
|
|
58
|
+
})
|
|
59
|
+
.catch(function(error)
|
|
60
|
+
{
|
|
61
|
+
// Error connecting to the bridge
|
|
62
|
+
scope.log("Error requesting info from the bridge. Reconnect in some secs. " + error.message);
|
|
63
|
+
scope.start();
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
scope.log("Lost connection with the bridge. Reconnect in some secs. " + error.message);
|
|
67
|
+
scope.start();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}, 10000);
|
|
71
|
+
}
|
|
47
72
|
// INITIALIZE
|
|
48
73
|
this.start = function()
|
|
49
74
|
{
|
|
75
|
+
this.startWatchdog(); // 31/01/2022 Supergiovane: starts the watchdog.
|
|
76
|
+
|
|
50
77
|
scope.log("Initializing the bridge ("+config.bridge+")…");
|
|
51
78
|
API.init({ config: config })
|
|
52
79
|
.then(function(bridge) {
|
|
@@ -303,96 +330,129 @@ module.exports = function(RED)
|
|
|
303
330
|
|
|
304
331
|
if(type == "bridge")
|
|
305
332
|
{
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
333
|
+
try {
|
|
334
|
+
const message = new HueBridgeMessage(targetResource, options);
|
|
335
|
+
|
|
336
|
+
// GET CURRENT STATE MESSAGE
|
|
337
|
+
let currentState = message.msg;
|
|
338
|
+
return currentState;
|
|
339
|
+
} catch (error) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
|
|
311
343
|
}
|
|
312
344
|
else if(type == "light")
|
|
313
345
|
{
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
346
|
+
try {
|
|
347
|
+
const message = new HueLightMessage(targetResource, options);
|
|
348
|
+
|
|
349
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
350
|
+
let currentState = message.msg;
|
|
351
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
352
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
353
|
+
currentState.lastState = lastState;
|
|
354
|
+
|
|
355
|
+
return currentState;
|
|
356
|
+
} catch (error) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
323
359
|
}
|
|
324
360
|
else if(type == "group")
|
|
325
361
|
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
362
|
+
try {
|
|
363
|
+
// GET MESSAGE
|
|
364
|
+
const message = new HueGroupMessage(targetResource, { resources: scope.resources, ...options});
|
|
365
|
+
|
|
366
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
367
|
+
let currentState = message.msg;
|
|
368
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
369
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
370
|
+
currentState.lastState = lastState;
|
|
371
|
+
|
|
372
|
+
return currentState;
|
|
373
|
+
} catch (error) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
336
376
|
}
|
|
337
377
|
else if(type == "button")
|
|
338
378
|
{
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
379
|
+
try {
|
|
380
|
+
const message = new HueButtonsMessage(targetResource, options);
|
|
381
|
+
|
|
382
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
383
|
+
let currentState = message.msg;
|
|
384
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
385
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
386
|
+
currentState.lastState = lastState;
|
|
387
|
+
|
|
388
|
+
return currentState;
|
|
389
|
+
} catch (error) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
348
392
|
}
|
|
349
393
|
else if(type == "motion")
|
|
350
394
|
{
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
395
|
+
try {
|
|
396
|
+
const message = new HueMotionMessage(targetResource, options);
|
|
397
|
+
|
|
398
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
399
|
+
let currentState = message.msg;
|
|
400
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
401
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
402
|
+
currentState.lastState = lastState;
|
|
403
|
+
|
|
404
|
+
return currentState;
|
|
405
|
+
} catch (error) {
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
360
408
|
}
|
|
361
409
|
else if(type == "temperature")
|
|
362
410
|
{
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
411
|
+
try {
|
|
412
|
+
const message = new HueTemperatureMessage(targetResource, options);
|
|
413
|
+
|
|
414
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
415
|
+
let currentState = message.msg;
|
|
416
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
417
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
418
|
+
currentState.lastState = lastState;
|
|
419
|
+
|
|
420
|
+
return currentState;
|
|
421
|
+
} catch (error) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
372
424
|
}
|
|
373
425
|
else if(type == "light_level")
|
|
374
426
|
{
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
427
|
+
try {
|
|
428
|
+
const message = new HueBrightnessMessage(targetResource, options);
|
|
429
|
+
|
|
430
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
431
|
+
let currentState = message.msg;
|
|
432
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
433
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
434
|
+
currentState.lastState = lastState;
|
|
435
|
+
|
|
436
|
+
return currentState;
|
|
437
|
+
} catch (error) {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
384
440
|
}
|
|
385
441
|
else if(type == "rule")
|
|
386
442
|
{
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
443
|
+
try {
|
|
444
|
+
const message = new HueRulesMessage(targetResource, options);
|
|
445
|
+
|
|
446
|
+
// GET & SAVE LAST STATE AND DIFFERENCES
|
|
447
|
+
let currentState = message.msg;
|
|
448
|
+
scope.lastStates[type+targetResource.id] = Object.assign({}, currentState);
|
|
449
|
+
currentState.updated = (lastState === false) ? {} : diff(lastState, currentState);
|
|
450
|
+
currentState.lastState = lastState;
|
|
451
|
+
|
|
452
|
+
return currentState;
|
|
453
|
+
} catch (error) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
396
456
|
}
|
|
397
457
|
else
|
|
398
458
|
{
|
|
@@ -598,7 +658,7 @@ module.exports = function(RED)
|
|
|
598
658
|
//
|
|
599
659
|
// START THE MAGIC
|
|
600
660
|
this.start();
|
|
601
|
-
|
|
661
|
+
|
|
602
662
|
//
|
|
603
663
|
// CLOSE NODE / REMOVE EVENT LISTENER
|
|
604
664
|
this.on('close', function()
|
|
@@ -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;
|
|
@@ -116,7 +117,7 @@ module.exports = function(RED)
|
|
|
116
117
|
let currentState = bridge.get("light_level", tempSensorID);
|
|
117
118
|
if(!currentState)
|
|
118
119
|
{
|
|
119
|
-
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
|
|
120
|
+
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.");
|
|
120
121
|
return false;
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -157,9 +158,30 @@ module.exports = function(RED)
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
// PATCH!
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
async.retry({
|
|
162
|
+
times: 3,
|
|
163
|
+
errorFilter: function(err) {
|
|
164
|
+
return (err.status == 503);
|
|
165
|
+
},
|
|
166
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
167
|
+
},
|
|
168
|
+
function(callback, results)
|
|
169
|
+
{
|
|
170
|
+
bridge.patch("light_level", tempSensorID, patchObject)
|
|
171
|
+
.then(function() { callback(null, true); })
|
|
172
|
+
.catch(function(errors) { callback(errors, null); });
|
|
173
|
+
},
|
|
174
|
+
function(errors, success)
|
|
175
|
+
{
|
|
176
|
+
if(errors)
|
|
177
|
+
{
|
|
178
|
+
scope.error(errors);
|
|
179
|
+
}
|
|
180
|
+
else if(done)
|
|
181
|
+
{
|
|
182
|
+
done();
|
|
183
|
+
}
|
|
184
|
+
});
|
|
163
185
|
}
|
|
164
186
|
else
|
|
165
187
|
{
|
package/huemagic/hue-buttons.js
CHANGED
|
@@ -134,7 +134,7 @@ module.exports = function(RED)
|
|
|
134
134
|
let currentState = bridge.get("button", tempSensorID);
|
|
135
135
|
if(!currentState)
|
|
136
136
|
{
|
|
137
|
-
scope.error("The button/switch 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
|
|
137
|
+
scope.error("The button/switch 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.");
|
|
138
138
|
return false;
|
|
139
139
|
}
|
|
140
140
|
|
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
|
{
|