Skip to content

Commit

Permalink
Update to v4.2.0
Browse files Browse the repository at this point in the history
* Commands are now re-executed up to three times if they fail due to a bridge timeout
* The "image" option on the "Hue Light" node will now set the corresponding gradient colors on supported resources
* Better handling of broken connections to the bridge ([#309](#309)) (thx)
* Fixed an error with the "Hue Scenes" node on newer bridge firmwares ([#335](#335)) ([#339](#339)) (thx)
* Fixed an error with uncaught exception on newer bridge firmwares ([#302](#302)) ([#309](#309)) (thx)
* Updated dependencies to the latest versions
* Fixed some typos here and there
  • Loading branch information
Foddy committed Mar 20, 2022
1 parent c8db299 commit 1341843
Show file tree
Hide file tree
Showing 14 changed files with 570 additions and 219 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,21 @@ If the status of the node has changed via a certain command, the entire command

# Changelog

### v4.1.0 (latest)
### v4.2.0 (latest)

* Commands are now re-executed up to three times if they fail due to a bridge timeout
* The "image" option on the "Hue Light" node will now set the corresponding gradient colors on supported resources
* Better handling of broken connections to the bridge ([#309](https://github.com/Foddy/node-red-contrib-huemagic/pull/309)) (thx)
* 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)
* Fixed an error with 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)
* Updated dependencies to the latest versions
* Fixed some typos here and there

### v4.1.0

* 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)
* Resources are now alphabetically sorted in the node´s configuration inetrface ([#282](https://github.com/Foddy/node-red-contrib-huemagic/pull/282)) (thx)
* "Hue Bridghtness" node was optimized to output more accurate "dark" and "dayLight" values
* Resources are now alphabetically sorted in the node´s configuration interface ([#282](https://github.com/Foddy/node-red-contrib-huemagic/pull/282)) (thx)
* "Hue Brightness" node was optimized to output more accurate "dark" and "dayLight" values
* Several optimizations in the documentation of some nodes

### v4.0.5
Expand Down
4 changes: 2 additions & 2 deletions huemagic/hue-bridge-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
name: { value:"Hue Bridge", required: true },
bridge: { value:"", required: true },
key: { value:"", required: true },
worker: { value: 10, required: true, validate:function(v) {
return (!isNaN(v) && v > 0)
worker: { value: 10, required: true, validate: function(v) {
return (!isNaN(v) && v > 0);
}},
autoupdates: { value: true },
disableupdates: { value: false }
Expand Down
30 changes: 26 additions & 4 deletions huemagic/hue-brightness.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = function(RED)

const scope = this;
const bridge = RED.nodes.getNode(config.bridge);
const async = require('async');

// SAVE LAST COMMAND
this.lastCommand = null;
Expand Down Expand Up @@ -116,7 +117,7 @@ module.exports = function(RED)
let currentState = bridge.get("light_level", tempSensorID);
if(!currentState)
{
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..");
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.");
return false;
}

Expand Down Expand Up @@ -157,9 +158,30 @@ module.exports = function(RED)
}

// PATCH!
bridge.patch("light_level", tempSensorID, patchObject)
.then(function() { if(done) { done(); }})
.catch(function(errors) { scope.error(errors); });
async.retry({
times: 3,
errorFilter: function(err) {
return (err.status == 503);
},
interval: function(retryCount) { return retryCount*2000; }
},
function(callback, results)
{
bridge.patch("light_level", tempSensorID, patchObject)
.then(function() { callback(null, true); })
.catch(function(errors) { callback(errors, null); });
},
function(errors, success)
{
if(errors)
{
scope.error(errors);
}
else if(done)
{
done();
}
});
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion huemagic/hue-buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ module.exports = function(RED)
let currentState = bridge.get("button", tempSensorID);
if(!currentState)
{
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..");
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.");
return false;
}

Expand Down
205 changes: 149 additions & 56 deletions huemagic/hue-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = function(RED)

const scope = this;
const bridge = RED.nodes.getNode(config.bridge);
const async = require('async');

// EXPORT CONFIG
this.exportedConfig = config;
Expand Down Expand Up @@ -112,7 +113,7 @@ module.exports = function(RED)
let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
if(!currentState)
{
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..");
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.");
return false;
}

Expand Down Expand Up @@ -158,18 +159,41 @@ module.exports = function(RED)
"bri": msg.payload.brightness ? Math.round((254/100)*msg.payload.brightness) : 254
};

bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function(status) {
// RESET COLORLOOP ANIMATION AFTER X SECONDS
setTimeout(function()
{
bridge.patch("group", currentState.info.idV1 + "/action", { "effect": "none" }, 1)
.then(function() { if(done) { done(); }});
}, parseInt(msg.payload.colorloop) * 1000);
})
.catch(function(errors) {
scope.error(errors);
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
// PATCH!
async.retry({
times: 3,
errorFilter: function(err) {
return (err.status == 503);
},
interval: function(retryCount) { return retryCount*2000; }
},
function(callback, results)
{
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function(status) {
// RESET COLORLOOP ANIMATION AFTER X SECONDS
setTimeout(function()
{
bridge.patch("group", currentState.info.idV1 + "/action", { "effect": "none" }, 1)
.then(function() { if(done) { done(); }});
}, parseInt(msg.payload.colorloop) * 1000);
callback(null, true);
})
.catch(function(errors) {
callback(errors, null);
});
},
function(errors, success)
{
if(errors)
{
scope.error(errors);
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
}
else if(done)
{
done();
}
});

return false;
Expand Down Expand Up @@ -240,42 +264,65 @@ module.exports = function(RED)
// SET ALERT EFFECT
patchObject["alert"] = "lselect";

// 1. TURN ON THE LIGHT BULB
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function(status) {
setTimeout(function()
// PATCH!
async.retry({
times: 3,
errorFilter: function(err) {
return (err.status == 503);
},
interval: function(retryCount) { return retryCount*2000; }
},
function(callback, results)
{
// 1. TURN ON THE LIGHT BULB
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function(status)
{
const tempPreviousState = scope.context().get('groupPreviousState');
var tempPreviousStatePatch = {};

tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
if(tempPreviousState.payload.xyColor)
{
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
}
else if(tempPreviousState.payload.colorTemp)
setTimeout(function()
{
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
}
const tempPreviousState = scope.context().get('groupPreviousState');
var tempPreviousStatePatch = {};

bridge.patch("group", currentState.info.idV1 + "/action", tempPreviousStatePatch, 1)
.then(function(status)
{
return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
})
.then(function(status) {
if(done) { done(); }
if(tempPreviousState.payload.on === true)
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
if(tempPreviousState.payload.xyColor)
{
bridge.patch("group", currentState.info.idV1, { on: true }, 1);
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
}
});
}, parseInt(msg.payload.alert) * 1000);
})
.catch(function(errors) {
scope.error(errors);
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
if(done) { done(error); }
else if(tempPreviousState.payload.colorTemp)
{
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
}

bridge.patch("group", currentState.info.idV1 + "/action", tempPreviousStatePatch, 1)
.then(function(status)
{
return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
})
.then(function(status) {
if(tempPreviousState.payload.on === true)
{
bridge.patch("group", currentState.info.idV1, { on: true }, 1);
}
});
}, parseInt(msg.payload.alert) * 1000);

callback(null, true);
})
.catch(function(errors) {
callback(errors, null);
});
},
function(errors, success)
{
if(errors)
{
scope.error(errors);
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
}
else if(done)
{
done();
}
});
}
// ANIMATION STARTED?
Expand All @@ -300,19 +347,44 @@ module.exports = function(RED)
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
}

bridge.patch("light", currentState.info.lightIds[l], tempPreviousStatePatch).
then(function(status)
// PATCH!
async.retry({
times: 3,
errorFilter: function(err) {
return (err.status == 503);
},
interval: function(retryCount) { return retryCount*2000; }
},
function(callback, results)
{
if(tempPreviousState.payload.on === false)
bridge.patch("light", currentState.info.lightIds[l], tempPreviousStatePatch).
then(function(status)
{
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
if(tempPreviousState.payload.on === false)
{
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
.then(function() { callback(null, true); });
}
else
{
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
.then(function(status) {
callback(null, true);
return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } });
});
}
})
.catch(function(errors) { callback(errors, null); });
},
function(errors, success)
{
if(errors)
{
scope.error(errors);
}
else
else if(done)
{
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
.then(function(status) {
return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } })
});
done();
}
});
}
Expand Down Expand Up @@ -516,9 +588,30 @@ module.exports = function(RED)
}

// PATCH!
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function() { if(done) { done(); }})
.catch(function(errors) { scope.error(errors); });
async.retry({
times: 3,
errorFilter: function(err) {
return (err.status == 503);
},
interval: function(retryCount) { return retryCount*2000; }
},
function(callback, results)
{
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
.then(function() { callback(null, true); })
.catch(function(errors) { callback(errors, null); });
},
function(errors, success)
{
if(errors)
{
scope.error(errors);
}
else if(done)
{
done();
}
});
}
else
{
Expand Down

0 comments on commit 1341843

Please sign in to comment.