Skip to content

Commit

Permalink
Update to v4.1.0
Browse files Browse the repository at this point in the history
* 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](#282)) (thx)
* "Hue Bridghtness" node was optimized to output more accurate "dark" and "dayLight" values
* Several optimizations in the documentation of some nodes
  • Loading branch information
Foddy committed Jan 18, 2022
1 parent 5972266 commit 7a0d17d
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 43 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ If the "fetch" command has been used on the node, the bridge outputs the corresp

#### Global status messages under `msg.updated` (optional)

Unless deactivated, the node outputs an updated status message for each resource on the bridge. The status message under * msg.updated * follows the pattern of the respective resource and varies depending on the type of device that was last updated.
Unless deactivated, the node outputs an updated status message for each resource on the bridge. The status message under `msg.updated` follows the pattern of the respective resource and varies depending on the type of device that was last updated.

#### Last command under `msg.command` (optional)

Expand Down Expand Up @@ -172,7 +172,7 @@ To play or stop an animation, pass an object with the following content to the n
|--|--|
| payload (boolean) | `true`, starts the animation, `false`, stops the animation |

### Own animations
### Custom animations

If you pass your own animation to the node, the preselected, pre-defined animation (if set) will be temporarily replaced by yours. Own HueMagic animations are a sequence of commands that have been combined in an array. Each array element forms a step - whereby a step can also consist of several frames (transition effects).

Expand Down Expand Up @@ -273,7 +273,7 @@ In addition to simply switching it on and off, there are also many other options
| gradient (object {hex []}) | An object with a supported color object (e.g. `hex`,` rgb`, ...) and several colors to set a gradient to supported lights |
| mixColor (object) | A color to be mixed with the current light color. Can accept `color`, `hex`, `rgb` or `xyColor` objects and optionally `amount` (int) to indicate the mixing ratio in percent |
| image (string) | Path of an image (local or on the web) to set the current color of the light to the average color of the image |
| saturation (int) | percentage of the saturation of the current color (beta) |
| saturation (int) | Percentage of the saturation of the current color (beta) |
| colorTemp (int / string) | Value between 153 and 500 to set the color temperature of the light or the values `cold`, `normal`, `warm`, `hot` and `auto` - where `auto` is the color temperature based on the current time |
| incrementColorTemp (int / boolean) | Value by how much the color temperature should be warmer or `true` to make the color temperature warmer in steps of 50 |
| decrementColorTemp (int / boolean) | Value by how much the color temperature should be colder or `true` to make the color temperature colder in steps of 50 |
Expand Down Expand Up @@ -796,7 +796,14 @@ If the status of the node has changed via a certain command, the entire command

# Changelog

### v4.0.5 (latest)
### v4.1.0 (latest)

* 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
* Several optimizations in the documentation of some nodes

### v4.0.5

* The "Hue Group" node now contains the "resources" information with all linked resources behind the group/zone
* Fixed an issue that caused Node-RED to restart if a command was sent before a node was initialized
Expand Down
7 changes: 7 additions & 0 deletions huemagic/hue-bridge-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
</button>
</div>
</div>
<div class="form-row">
<label for="node-config-input-worker"><i class="fa fa-cogs"></i> <span>Worker</span></label>
<input type="text" id="node-config-input-worker" placeholder="10" style="width: calc(100% - 105px)">
</div>
<div class="form-row" style="margin-top: 30px">
<div style="display: inline-flex; width: calc(100% - 105px)">
<input type="checkbox" id="node-input-autoupdates" style="flex: 15px;">
Expand All @@ -47,6 +51,9 @@
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)
}},
autoupdates: { value: true },
disableupdates: { value: false }
},
Expand Down
56 changes: 38 additions & 18 deletions huemagic/hue-bridge-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = function(RED)
const diff = require("deep-object-diff").diff;
const axios = require('axios');
const https = require('https');
const fastq = require('fastq');

// READABLE RESOURCE MESSAGES
const { HueBridgeMessage,
Expand All @@ -32,6 +33,7 @@ module.exports = function(RED)
this.resourcesInGroups = {};
this.lastStates = {};
this.events = new events.EventEmitter();
this.patchQueue = null;

// RESOURCE ID PATTERN
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;
Expand Down Expand Up @@ -435,24 +437,41 @@ module.exports = function(RED)
{
return new Promise(function(resolve, reject)
{
// GET SERVICE ID
if(version !== 1 && scope.resources[id] && scope.resources[id]["services"] && scope.resources[id]["services"][type])
if(!scope.patchQueue) { return false; }
scope.patchQueue.push({ type: type, id: id, patch: patch, version: version }, function (error, response)
{
const targetResource = Object.values(scope.resources[id]["services"][type])[0];
id = targetResource.id;
}

// ACTION!
API.request({ config: config, method: "PUT", resource: (version === 2) ? (type+"/"+id) : id, data: patch, version: version })
.then(function(response) {
resolve(response);
})
.catch(function(error) {
reject(error);
if(error)
{
reject(error);
}
else
{
resolve(response);
}
});
});
}

// PATCH RESOURCE (WORKER) / 7 PROCESSES IN PARALLEL
this.patchQueue = fastq(function({ type, id, patch, version }, callback)
{
// GET SERVICE ID
if(version !== 1 && scope.resources[id] && scope.resources[id]["services"] && scope.resources[id]["services"][type])
{
const targetResource = Object.values(scope.resources[id]["services"][type])[0];
id = targetResource.id;
}

// ACTION!
API.request({ config: config, method: "PUT", resource: (version === 2) ? (type+"/"+id) : id, data: patch, version: version })
.then(function(response) {
callback(null, response);
})
.catch(function(error) {
callback(error, null);
});
}, config.worker ? parseInt(config.worker) : 10);

// RE-FETCH RULE (RECEIVES NO UPDATES VIA SSE)
this.refetchRule = function(id)
{
Expand Down Expand Up @@ -546,8 +565,6 @@ module.exports = function(RED)
if((config.autoupdates && config.autoupdates == true) || typeof config.autoupdates == 'undefined')
{
if(scope.firmwareUpdateTimeout !== null) { clearTimeout(scope.firmwareUpdateTimeout); };

scope.log("Checking for Hue Bridge firmware updates…");
API.request({
config: config,
method: "PUT",
Expand All @@ -564,15 +581,15 @@ module.exports = function(RED)
{
if(scope.nodeActive == true)
{
scope.firmwareUpdateTimeout = setTimeout(function(){ scope.autoUpdateFirmware(); }, 60000 * 180);
scope.firmwareUpdateTimeout = setTimeout(function(){ scope.autoUpdateFirmware(); }, 60000 * 720);
}
})
.catch(function(error)
{
// NO UPDATES AVAILABLE // TRY AGAIN IN 3H
// NO UPDATES AVAILABLE // TRY AGAIN IN 12H
if(scope.nodeActive == true)
{
scope.firmwareUpdateTimeout = setTimeout(function(){ scope.autoUpdateFirmware(); }, 60000 * 180);
scope.firmwareUpdateTimeout = setTimeout(function(){ scope.autoUpdateFirmware(); }, 60000 * 720);
}
});
}
Expand All @@ -597,6 +614,9 @@ module.exports = function(RED)

// REMOVE FIRMWARE UPDATE TIMEOUT
if(scope.firmwareUpdateTimeout !== null) { clearTimeout(scope.firmwareUpdateTimeout); }

// KILL QUEUE
scope.patchQueue.kill();
});
}

Expand Down
2 changes: 1 addition & 1 deletion huemagic/hue-brightness.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ module.exports = function(RED)
let currentState = bridge.get("light_level", tempSensorID);
if(!currentState)
{
scope.error("The sensor in not yet available. Please wait for the bridge to connect before sending any command.");
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
10 changes: 5 additions & 5 deletions huemagic/hue-buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ module.exports = function(RED)
bridge.subscribe("button", config.sensorid, function(info)
{
let currentState = bridge.get("button", info.id);
if(!currentState)
{
scope.error("The button/switch in not yet available. Please wait for the bridge to connect before sending any command.");
return false;
}

// RESOURCE FOUND?
if(currentState !== false)
Expand Down Expand Up @@ -137,6 +132,11 @@ 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..");
return false;
}

// GET CURRENT STATE
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
Expand Down
2 changes: 1 addition & 1 deletion huemagic/hue-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,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 for the bridge to connect before sending any command.");
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
2 changes: 1 addition & 1 deletion huemagic/hue-light.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ module.exports = function(RED)
let currentState = bridge.get("light", tempLightID, { colornames: config.colornamer ? true : false });
if(!currentState)
{
scope.error("The light in not yet available. Please wait for the bridge to connect before sending any command.");
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..");
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion huemagic/hue-motion.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module.exports = function(RED)
let currentState = bridge.get("motion", tempSensorID);
if(!currentState)
{
scope.error("The sensor in not yet available. Please wait for the bridge to connect before sending any command.");
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
2 changes: 1 addition & 1 deletion huemagic/hue-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ module.exports = function(RED)
let currentState = bridge.get("rule", "rule_" + tempRuleID);
if(!currentState)
{
scope.error("The rule in not yet available. Please wait for the bridge to connect before sending any command.");
scope.error("The rule 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
10 changes: 5 additions & 5 deletions huemagic/hue-temperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ module.exports = function(RED)
bridge.subscribe("temperature", config.sensorid, function(info)
{
let currentState = bridge.get("temperature", info.id);
if(!currentState)
{
scope.error("The sensor in not yet available. Please wait for the bridge to connect before sending any command.");
return false;
}

// RESOURCE FOUND?
if(currentState !== false)
Expand Down Expand Up @@ -121,6 +116,11 @@ module.exports = function(RED)
}

let currentState = bridge.get("temperature", 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..");
return false;
}

// GET CURRENT STATE
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
Expand Down
8 changes: 8 additions & 0 deletions huemagic/locales/de/hue-bridge-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@

Geben Sie den Hue Bridge API-Schlüssel manuell ein oder drücken Sie den Button, um einen neuen Schlüssel zu erstellen. Wenn Sie einen neuen Schlüssel erstellen möchten, müssen Sie innerhalb des Zeitfensters von 20 Sekunden den physischen Button der Bridge betätigen, um den Prozess abzuschließen.

### Worker

Der "Worker"-Wert bestimmt die Anzahl der parallelen Befehle, die HueMagic an die Bridge gleichzeitig schicken darf. Laut offizieller Dokumentation der Philips Hue Bridge, sollten nicht mehr als 10 Befehle pro Sekunde abgeschickt werden, da sonst die Gefahr besteht, dass die Bridge die Anfragen nicht so schnell verarbeiten kann und Fehler auswirft.

Wenn mehr Befehle gleichzeitig abgeschickt werden als der hier gesetzte Wert, wird HueMagic die Befehle nacheinander ausführen, sobald der Durchsatz wieder möglich ist.

Setzen Sie hier einen Wert unter 10 (z. B. 4 bis 7), wenn Sie auch außerhalb von HueMagic Befehle an die Bridge senden, um den von Philips Hue empfohlenen Durchsatz an Befehlen / Sekunde einzuhalten.

### Automatische Firmware-Updates

HueMagic prüft periodisch nach verfügbaren Philips Hue Firmware Updates und installiert sie automatisch, wenn sie verfügbar sind. Sie können dieses Verhalten deaktivieren, indem Sie die entsprechende Checkbox anklicken.
Expand Down
8 changes: 8 additions & 0 deletions huemagic/locales/en-US/hue-bridge-config.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@

Enter the Hue Bridge API key manually or press the button to create a new key. If you want to create a new key, you have to press the physical button of the bridge within the time window of 20 seconds to complete the process.

### Worker

The "Worker" value determines the number of parallel commands that HueMagic is allowed to send to the bridge at the same time. According to the official documentation of the Philips Hue bridge, no more than 10 commands should be sent per second, otherwise there is a risk that the bridge will not be able to process the requests as quickly and will throw errors.

If more commands are sent at the same time than the value set here, HueMagic will execute the commands in sequence as soon as throughput is possible again.

Set this to a value below 10 (e.g. 4 to 7) if you also send commands to the bridge outside of HueMagic in order to comply with the Philips Hue recommended throughput of commands/second.

### Automatic firmware updates

HueMagic periodically checks for available Philips Hue firmware updates and automatically installs them when they are available. You can deactivate this behavior by clicking the corresponding checkbox.
Expand Down
2 changes: 1 addition & 1 deletion huemagic/locales/en-US/hue-bridge.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

#### Global status messages under `msg.updated` (optional)

Unless deactivated, the node outputs an updated status message for each resource on the bridge. The status message under * msg.updated * follows the pattern of the respective resource and varies depending on the type of device that was last updated.
Unless deactivated, the node outputs an updated status message for each resource on the bridge. The status message under `msg.updated` follows the pattern of the respective resource and varies depending on the type of device that was last updated.

#### Last command under `msg.command` (optional)

Expand Down
2 changes: 1 addition & 1 deletion huemagic/locales/en-US/hue-light.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
: gradient (object {hex […]}): An object with a supported color object (e.g. `hex`,` rgb`, ...) and several colors to set a gradient to supported lights
: mixColor (object): A color to be mixed with the current light color. Can accept `color`, `hex`, `rgb` or `xyColor` objects and optionally `amount` (int) to indicate the mixing ratio in percent
: image (string): Path of an image (local or on the web) to set the current color of the light to the average color of the image
: saturation (int): percentage of the saturation of the current color (beta)
: saturation (int): Percentage of the saturation of the current color (beta)
: colorTemp (int | string): Value between 153 and 500 to set the color temperature of the light or the values `cold`, `normal`, `warm`, `hot` and `auto` - where `auto` is the color temperature based on the current time
: incrementColorTemp (int | boolean): Value by how much the color temperature should be warmer or `true` to make the color temperature warmer in steps of 50
: decrementColorTemp (int | boolean): Value by how much the color temperature should be colder or `true` to make the color temperature colder in steps of 50
Expand Down
2 changes: 1 addition & 1 deletion huemagic/locales/en-US/hue-magic.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

: payload (boolean): `true`, starts the animation, `false`, stops the animation

### Own animations
### Custom animations

If you pass your own animation to the node, the preselected, pre-defined animation (if set) will be temporarily replaced by yours. Own HueMagic animations are a sequence of commands that have been combined in an array. Each array element forms a step - whereby a step can also consist of several frames (transition effects).

Expand Down
4 changes: 2 additions & 2 deletions huemagic/utils/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ class HueBrightnessMessage
this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown"; // NEW!
this.message.payload.lux = realLUX;
this.message.payload.lightLevel = service.light.light_level;
this.message.payload.dark = (realLUX < 200);
this.message.payload.daylight = (realLUX > 200);
this.message.payload.dark = (realLUX < 90);
this.message.payload.daylight = (realLUX >= 90);
this.message.payload.updated = resource.updated;

this.message.info = {};
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-huemagic",
"version": "4.0.5",
"version": "4.1.0",
"description": "Philips Hue node to control bridges, lights, groups, scenes, rules, taps, switches, buttons, motion sensors, temperature sensors and Lux sensors using Node-RED.",
"author": "foddy",
"homepage": "https://github.com/Foddy/node-red-contrib-huemagic",
Expand Down Expand Up @@ -52,6 +52,7 @@
"dayjs": "^1.10.7",
"deep-object-diff": "^1.1.0",
"eventsource": "^1.1.0",
"fastq": "^1.13.0",
"get-image-colors": "^4.0.0"
}
}

0 comments on commit 7a0d17d

Please sign in to comment.