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-rules.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;
|
|
@@ -100,7 +101,7 @@ module.exports = function(RED)
|
|
|
100
101
|
let currentState = bridge.get("rule", "rule_" + tempRuleID);
|
|
101
102
|
if(!currentState)
|
|
102
103
|
{
|
|
103
|
-
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
|
|
104
|
+
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.");
|
|
104
105
|
return false;
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -111,12 +112,30 @@ module.exports = function(RED)
|
|
|
111
112
|
patchObject["status"] = (msg.payload == true) ? 'enabled' : 'disabled';
|
|
112
113
|
|
|
113
114
|
// PATCH!
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
async.retry({
|
|
116
|
+
times: 3,
|
|
117
|
+
errorFilter: function(err) {
|
|
118
|
+
return (err.status == 503);
|
|
119
|
+
},
|
|
120
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
121
|
+
},
|
|
122
|
+
function(callback, results)
|
|
123
|
+
{
|
|
124
|
+
bridge.patch("rules", "/rules/"+tempRuleID, patchObject, 1)
|
|
125
|
+
.then(function(response) { bridge.refetchRule(tempRuleID); callback(null, true); })
|
|
126
|
+
.catch(function(errors) { callback(errors, null); });
|
|
127
|
+
},
|
|
128
|
+
function(errors, success)
|
|
129
|
+
{
|
|
130
|
+
if(errors)
|
|
131
|
+
{
|
|
132
|
+
scope.error(errors);
|
|
133
|
+
}
|
|
134
|
+
else if(done)
|
|
135
|
+
{
|
|
136
|
+
done();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
120
139
|
}
|
|
121
140
|
else
|
|
122
141
|
{
|
package/huemagic/hue-scene.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
|
// GET TARGET WIRED GROUPS
|
|
13
14
|
this.targetGroups = {};
|
|
@@ -72,9 +73,32 @@ module.exports = function(RED)
|
|
|
72
73
|
|
|
73
74
|
if(targetGroup)
|
|
74
75
|
{
|
|
75
|
-
|
|
76
|
-
.
|
|
77
|
-
|
|
76
|
+
// PATCH!
|
|
77
|
+
async.retry({
|
|
78
|
+
times: 3,
|
|
79
|
+
errorFilter: function(err) {
|
|
80
|
+
return (err.status == 503);
|
|
81
|
+
},
|
|
82
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
83
|
+
},
|
|
84
|
+
function(callback, results)
|
|
85
|
+
{
|
|
86
|
+
bridge.patch("group", targetGroup.info.idV1 + "/action", { "scene": targetSceneID }, 1)
|
|
87
|
+
.then(function() { callback(null, true); })
|
|
88
|
+
.catch(function(errors) {
|
|
89
|
+
callback(errors, null);
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
function(errors, success)
|
|
93
|
+
{
|
|
94
|
+
if(errors)
|
|
95
|
+
{
|
|
96
|
+
scope.error(errors);
|
|
97
|
+
}
|
|
98
|
+
else if(done)
|
|
99
|
+
{
|
|
100
|
+
done();
|
|
101
|
+
}
|
|
78
102
|
});
|
|
79
103
|
}
|
|
80
104
|
}
|
|
@@ -87,27 +111,49 @@ module.exports = function(RED)
|
|
|
87
111
|
else
|
|
88
112
|
{
|
|
89
113
|
// RECALL SCENE
|
|
90
|
-
patchObject["recall"] = {
|
|
114
|
+
patchObject["recall"] = { action: "active" };
|
|
91
115
|
|
|
92
116
|
// CHANGE NODE UI STATE
|
|
93
117
|
scope.status({fill: "grey", shape: "ring", text: "hue-scene.node.command"});
|
|
94
118
|
|
|
95
119
|
// PATCH!
|
|
96
|
-
|
|
97
|
-
|
|
120
|
+
async.retry({
|
|
121
|
+
times: 3,
|
|
122
|
+
errorFilter: function(err) {
|
|
123
|
+
return (err.status == 503);
|
|
124
|
+
},
|
|
125
|
+
interval: function(retryCount) { return retryCount*2000; }
|
|
126
|
+
},
|
|
127
|
+
function(callback, results)
|
|
98
128
|
{
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
bridge.patch("scene", sceneDef, patchObject)
|
|
130
|
+
.then(function()
|
|
131
|
+
{
|
|
132
|
+
scope.status({fill: "blue", shape: "dot", text: "hue-scene.node.recalled"});
|
|
133
|
+
|
|
134
|
+
// RESET STATUS AFTER 1 SECOND
|
|
135
|
+
setTimeout(function() {
|
|
136
|
+
scope.status({});
|
|
137
|
+
}, 1000);
|
|
138
|
+
|
|
139
|
+
callback(null, true);
|
|
140
|
+
})
|
|
141
|
+
.catch(function(errors) { callback(errors, null); });
|
|
142
|
+
},
|
|
143
|
+
function(errors, success)
|
|
144
|
+
{
|
|
145
|
+
if(errors)
|
|
146
|
+
{
|
|
147
|
+
scope.error(errors);
|
|
148
|
+
}
|
|
149
|
+
else if(done)
|
|
150
|
+
{
|
|
151
|
+
done();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
108
154
|
}
|
|
109
155
|
});
|
|
110
156
|
}
|
|
111
157
|
|
|
112
158
|
RED.nodes.registerType("hue-scene", HueScene);
|
|
113
|
-
}
|
|
159
|
+
}
|
|
@@ -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;
|
|
@@ -118,7 +119,7 @@ module.exports = function(RED)
|
|
|
118
119
|
let currentState = bridge.get("temperature", tempSensorID);
|
|
119
120
|
if(!currentState)
|
|
120
121
|
{
|
|
121
|
-
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
|
|
122
|
+
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.");
|
|
122
123
|
return false;
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -159,9 +160,30 @@ module.exports = function(RED)
|
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
// PATCH!
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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("temperature", tempSensorID, patchObject)
|
|
173
|
+
.then(function() { callback(null, true); })
|
|
174
|
+
.catch(function(errors) { callback(errors, null); });
|
|
175
|
+
},
|
|
176
|
+
function(errors, success)
|
|
177
|
+
{
|
|
178
|
+
if(errors)
|
|
179
|
+
{
|
|
180
|
+
scope.error(errors);
|
|
181
|
+
}
|
|
182
|
+
else if(done)
|
|
183
|
+
{
|
|
184
|
+
done();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
165
187
|
}
|
|
166
188
|
else
|
|
167
189
|
{
|
|
@@ -15,7 +15,7 @@ Geben Sie den Hue Bridge API-Schlüssel manuell ein oder drücken Sie den Button
|
|
|
15
15
|
|
|
16
16
|
### Worker
|
|
17
17
|
|
|
18
|
-
Der
|
|
18
|
+
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.
|
|
19
19
|
|
|
20
20
|
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.
|
|
21
21
|
|
package/huemagic/utils/api.js
CHANGED
|
@@ -90,14 +90,7 @@ function API()
|
|
|
90
90
|
{
|
|
91
91
|
if(version === 2)
|
|
92
92
|
{
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
reject(response.data.errors);
|
|
96
|
-
}
|
|
97
|
-
else
|
|
98
|
-
{
|
|
99
|
-
resolve(response.data.data);
|
|
100
|
-
}
|
|
93
|
+
resolve(response.data.data);
|
|
101
94
|
}
|
|
102
95
|
else if(version === 1)
|
|
103
96
|
{
|
|
@@ -106,7 +99,7 @@ function API()
|
|
|
106
99
|
})
|
|
107
100
|
.catch(function(error)
|
|
108
101
|
{
|
|
109
|
-
reject(error);
|
|
102
|
+
reject({ status: error.response.status, errors: error.response.data.errors ? error.response.data.errors : error.response.data});
|
|
110
103
|
});
|
|
111
104
|
});
|
|
112
105
|
}
|
|
@@ -154,7 +147,7 @@ function API()
|
|
|
154
147
|
// ERROR? -> RETRY?
|
|
155
148
|
scope.events[config.id].onerror = function(error)
|
|
156
149
|
{
|
|
157
|
-
console.log("HueMagic:", "Connection to bridge lost. Trying to reconnect again in 30 seconds…",
|
|
150
|
+
console.log("HueMagic:", "Connection to bridge lost. Trying to reconnect again in 30 seconds…", error);
|
|
158
151
|
setTimeout(function(){ scope.subscribe(config, callback); }, 30000);
|
|
159
152
|
resolve(true);
|
|
160
153
|
}
|
|
@@ -259,15 +252,16 @@ function API()
|
|
|
259
252
|
}
|
|
260
253
|
|
|
261
254
|
// RESOURCE HAS GROUPED SERVICES?
|
|
262
|
-
if(fullResource["
|
|
255
|
+
if (fullResource["services"])
|
|
263
256
|
{
|
|
264
|
-
for (
|
|
257
|
+
for (serviceType in fullResource["services"])
|
|
265
258
|
{
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
259
|
+
const grouped_services = fullResource['services'][serviceType];
|
|
260
|
+
for (groupedServiceID in grouped_services)
|
|
261
|
+
{
|
|
262
|
+
if (!processedResources["_groupsOf"][groupedServiceID]) { processedResources["_groupsOf"][groupedServiceID] = []; }
|
|
263
|
+
processedResources["_groupsOf"][groupedServiceID].push(fullResource.id);
|
|
264
|
+
}
|
|
271
265
|
}
|
|
272
266
|
}
|
|
273
267
|
|
|
@@ -14,7 +14,7 @@ class HueBridgeMessage
|
|
|
14
14
|
this.message.payload.factoryNew = resource.factorynew;
|
|
15
15
|
this.message.payload.replacesBridgeId = resource.replacesbridgeid ? resource.replacesbridgeid : false;
|
|
16
16
|
this.message.payload.dataStoreVersion = resource.datastoreversion;
|
|
17
|
-
this.message.payload.starterKitId = resource.starterkitid.length > 0 ? resource.starterkitid : false;
|
|
17
|
+
this.message.payload.starterKitId = resource.starterkitid && resource.starterkitid.length > 0 ? resource.starterkitid : false;
|
|
18
18
|
this.message.payload.softwareVersion = resource.swversion;
|
|
19
19
|
this.message.payload.apiVersion = resource.apiversion;
|
|
20
20
|
this.message.payload.zigbeeChannel = resource.zigbeechannel;
|
|
@@ -33,8 +33,8 @@ class HueBridgeMessage
|
|
|
33
33
|
this.message.payload.linkButtonEnabled = resource.linkbutton;
|
|
34
34
|
this.message.payload.touchlinkEnabled = (resource["touchlink"] && resource["touchlink"] == true) ? true : false;
|
|
35
35
|
this.message.payload.autoUpdatesEnabled = options["autoupdate"] ? options["autoupdate"] : false;
|
|
36
|
-
this.message.payload.users = [];
|
|
37
|
-
this.message.payload.updated = resource.updated;
|
|
36
|
+
this.message.payload.users = [];
|
|
37
|
+
this.message.payload.updated = resource.updated;
|
|
38
38
|
|
|
39
39
|
this.message.payload.model = {};
|
|
40
40
|
this.message.payload.model.id = resource.modelid;
|
|
@@ -42,14 +42,16 @@ class HueBridgeMessage
|
|
|
42
42
|
this.message.payload.model.name = "Hue v2";
|
|
43
43
|
|
|
44
44
|
// GET USERS
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
if (resource["whitelist"]) {
|
|
46
|
+
for (const [userID, user] of Object.entries(resource["whitelist"]))
|
|
47
|
+
{
|
|
48
|
+
this.message.payload.users.push({
|
|
49
|
+
user: userID,
|
|
50
|
+
name: user["name"],
|
|
51
|
+
created: user["create date"],
|
|
52
|
+
lastAccess: user["last use date"]
|
|
53
|
+
});
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -75,9 +77,9 @@ class HueBrightnessMessage
|
|
|
75
77
|
|
|
76
78
|
this.message = {};
|
|
77
79
|
this.message.payload = {};
|
|
78
|
-
this.message.payload.active = service.enabled;
|
|
79
|
-
this.message.payload.reachable = connectivity ? (connectivity.status === "connected") : "unknown";
|
|
80
|
-
this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown";
|
|
80
|
+
this.message.payload.active = service.enabled;
|
|
81
|
+
this.message.payload.reachable = connectivity ? (connectivity.status === "connected") : "unknown";
|
|
82
|
+
this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown";
|
|
81
83
|
this.message.payload.lux = realLUX;
|
|
82
84
|
this.message.payload.lightLevel = service.light.light_level;
|
|
83
85
|
this.message.payload.dark = (realLUX < 90);
|
|
@@ -86,21 +88,21 @@ class HueBrightnessMessage
|
|
|
86
88
|
|
|
87
89
|
this.message.info = {};
|
|
88
90
|
this.message.info.id = service.id;
|
|
89
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
91
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
90
92
|
this.message.info.uniqueId = resource.id + "-" + service.id;
|
|
91
|
-
this.message.info.deviceId = resource.id;
|
|
93
|
+
this.message.info.deviceId = resource.id;
|
|
92
94
|
this.message.info.name = resource.metadata.name;
|
|
93
95
|
this.message.info.type = "light_level";
|
|
94
96
|
this.message.info.softwareVersion = resource.product_data.software_version;
|
|
95
97
|
this.message.info.battery = Object.values(resource.services.device_power)[0].power_state.battery_level;
|
|
96
|
-
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
98
|
+
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
97
99
|
|
|
98
100
|
this.message.info.model = {};
|
|
99
101
|
this.message.info.model.id = resource.product_data.model_id;
|
|
100
102
|
this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
|
|
101
103
|
this.message.info.model.name = resource.product_data.product_name;
|
|
102
104
|
this.message.info.model.type = resource.product_data.product_archetype;
|
|
103
|
-
this.message.info.model.certified = resource.product_data.certified;
|
|
105
|
+
this.message.info.model.certified = resource.product_data.certified;
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
get msg()
|
|
@@ -133,9 +135,9 @@ class HueGroupMessage
|
|
|
133
135
|
|
|
134
136
|
this.message.info = {};
|
|
135
137
|
this.message.info.id = resource.id;
|
|
136
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
138
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
137
139
|
this.message.info.name = resource.metadata ? resource.metadata.name : "all";
|
|
138
|
-
this.message.info.resources = allResourcesInsideGroup;
|
|
140
|
+
this.message.info.resources = allResourcesInsideGroup;
|
|
139
141
|
this.message.info.type = "group";
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -161,14 +163,14 @@ class HueLightMessage
|
|
|
161
163
|
this.message.payload.brightness = service.dimming ? service.dimming.brightness : false;
|
|
162
164
|
this.message.payload.brightnessLevel = service.dimming ? Math.round((254/100)*this.message.payload.brightness) : false;
|
|
163
165
|
this.message.payload.reachable = connectivity ? (connectivity.status === "connected") : "unknown";
|
|
164
|
-
this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown";
|
|
166
|
+
this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown";
|
|
165
167
|
this.message.payload.updated = resource.updated;
|
|
166
168
|
|
|
167
169
|
this.message.info = {};
|
|
168
170
|
this.message.info.id = service.id;
|
|
169
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
171
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
170
172
|
this.message.info.uniqueId = resource.id + "-" + service.id;
|
|
171
|
-
this.message.info.deviceId = resource.id;
|
|
173
|
+
this.message.info.deviceId = resource.id;
|
|
172
174
|
this.message.info.name = service.metadata.name;
|
|
173
175
|
this.message.info.type = "light";
|
|
174
176
|
this.message.info.softwareVersion = resource.product_data.software_version;
|
|
@@ -178,7 +180,7 @@ class HueLightMessage
|
|
|
178
180
|
this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
|
|
179
181
|
this.message.info.model.name = resource.product_data.product_name;
|
|
180
182
|
this.message.info.model.type = resource.product_data.product_archetype;
|
|
181
|
-
this.message.info.model.certified = resource.product_data.certified;
|
|
183
|
+
this.message.info.model.certified = resource.product_data.certified;
|
|
182
184
|
this.message.info.model.friendsOfHue = true;
|
|
183
185
|
|
|
184
186
|
// HAS COLOR CAPABILITIES?
|
|
@@ -187,7 +189,7 @@ class HueLightMessage
|
|
|
187
189
|
let RGB = colorUtils.xyBriToRgb(service.color.xy.x, service.color.xy.y, (service.dimming ? service.dimming.brightness : 100));
|
|
188
190
|
this.message.payload.rgb = [RGB.r, RGB.g, RGB.b];
|
|
189
191
|
this.message.payload.hex = colorUtils.rgbHex(RGB.r, RGB.g, RGB.b);
|
|
190
|
-
this.message.payload.xyColor = service.color.xy;
|
|
192
|
+
this.message.payload.xyColor = service.color.xy;
|
|
191
193
|
|
|
192
194
|
if(options.colornames == true)
|
|
193
195
|
{
|
|
@@ -195,8 +197,8 @@ class HueLightMessage
|
|
|
195
197
|
this.message.payload.color = cNamesArray.basic[0]["name"];
|
|
196
198
|
}
|
|
197
199
|
|
|
198
|
-
this.message.info.model.colorGamut = service.color.gamut;
|
|
199
|
-
this.message.info.model.colorGamutType = service.color.gamut_type;
|
|
200
|
+
this.message.info.model.colorGamut = service.color.gamut;
|
|
201
|
+
this.message.info.model.colorGamutType = service.color.gamut_type;
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
// HAS COLOR TEMPERATURE CAPABILITIES?
|
|
@@ -205,14 +207,14 @@ class HueLightMessage
|
|
|
205
207
|
this.message.payload.colorTemp = service.color_temperature.mirek ? service.color_temperature.mirek : false;
|
|
206
208
|
|
|
207
209
|
if(!this.message.payload.colorTemp) { this.message.payload.colorTempName = "unknown"; }
|
|
208
|
-
else if(this.message.payload.colorTemp < 200) { this.message.payload.colorTempName = "cold"; }
|
|
210
|
+
else if(this.message.payload.colorTemp < 200) { this.message.payload.colorTempName = "cold"; }
|
|
209
211
|
else if(this.message.payload.colorTemp < 350) { this.message.payload.colorTempName = "normal"; }
|
|
210
212
|
else if(this.message.payload.colorTemp < 410) { this.message.payload.colorTempName = "warm"; }
|
|
211
213
|
else { this.message.payload.colorTempName = "hot"; }
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
// HAS GRADIENT COLOR CAPABILITIES?
|
|
215
|
-
if(service["gradient"])
|
|
217
|
+
if(service["gradient"])
|
|
216
218
|
{
|
|
217
219
|
this.message.payload.gradient = {};
|
|
218
220
|
this.message.payload.gradient.colors = [];
|
|
@@ -254,28 +256,28 @@ class HueMotionMessage
|
|
|
254
256
|
this.message.payload = {
|
|
255
257
|
active: service.enabled,
|
|
256
258
|
reachable: connectivity ? (connectivity.status === "connected") : "unknown",
|
|
257
|
-
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
259
|
+
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
258
260
|
motion: (service.motion.motion && service.motion.motion_valid),
|
|
259
261
|
updated: resource.updated
|
|
260
262
|
};
|
|
261
263
|
|
|
262
264
|
this.message.info = {};
|
|
263
265
|
this.message.info.id = service.id;
|
|
264
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
266
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
265
267
|
this.message.info.uniqueId = resource.id + "-" + service.id;
|
|
266
|
-
this.message.info.deviceId = resource.id;
|
|
268
|
+
this.message.info.deviceId = resource.id;
|
|
267
269
|
this.message.info.name = resource.metadata.name;
|
|
268
270
|
this.message.info.type = "motion";
|
|
269
271
|
this.message.info.softwareVersion = resource.product_data.software_version;
|
|
270
272
|
this.message.info.battery = Object.values(resource.services.device_power)[0].power_state.battery_level;
|
|
271
|
-
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
273
|
+
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
272
274
|
|
|
273
275
|
this.message.info.model = {};
|
|
274
276
|
this.message.info.model.id = resource.product_data.model_id;
|
|
275
277
|
this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
|
|
276
278
|
this.message.info.model.name = resource.product_data.product_name;
|
|
277
279
|
this.message.info.model.type = resource.product_data.product_archetype;
|
|
278
|
-
this.message.info.model.certified = resource.product_data.certified;
|
|
280
|
+
this.message.info.model.certified = resource.product_data.certified;
|
|
279
281
|
}
|
|
280
282
|
|
|
281
283
|
get msg()
|
|
@@ -293,7 +295,7 @@ class HueRulesMessage
|
|
|
293
295
|
{
|
|
294
296
|
this.message = {};
|
|
295
297
|
this.message.payload = {};
|
|
296
|
-
this.message.payload.enabled = (resource["status"] == "enabled");
|
|
298
|
+
this.message.payload.enabled = (resource["status"] == "enabled");
|
|
297
299
|
this.message.payload.triggered = (resource["lasttriggered"] != null) ? dayjs(resource["lasttriggered"]).format() : false;
|
|
298
300
|
|
|
299
301
|
this.message.info = {};
|
|
@@ -338,30 +340,30 @@ class HueButtonsMessage
|
|
|
338
340
|
|
|
339
341
|
this.message = {};
|
|
340
342
|
this.message.payload = {
|
|
341
|
-
reachable: connectivity ? (connectivity.status === "connected") : "unknown",
|
|
342
|
-
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
343
|
-
button: pressedButton ? pressedButton.metadata.control_id : false,
|
|
344
|
-
action: pressedButton ? pressedButton.button.last_event : false,
|
|
343
|
+
reachable: connectivity ? (connectivity.status === "connected") : "unknown",
|
|
344
|
+
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
345
|
+
button: pressedButton ? pressedButton.metadata.control_id : false,
|
|
346
|
+
action: pressedButton ? pressedButton.button.last_event : false,
|
|
345
347
|
updated: resource.updated
|
|
346
348
|
};
|
|
347
349
|
|
|
348
350
|
this.message.info = {};
|
|
349
351
|
this.message.info.id = pressedButton ? pressedButton.id : resource.id;
|
|
350
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
352
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
351
353
|
this.message.info.uniqueId = resource.id + "-" + (pressedButton ? pressedButton.id : "");
|
|
352
|
-
this.message.info.deviceId = resource.id;
|
|
354
|
+
this.message.info.deviceId = resource.id;
|
|
353
355
|
this.message.info.name = resource.metadata.name;
|
|
354
356
|
this.message.info.type = "button";
|
|
355
357
|
this.message.info.softwareVersion = resource.product_data.software_version;
|
|
356
358
|
this.message.info.battery = resource.services.device_power ? Object.values(resource.services.device_power)[0].power_state.battery_level : false;
|
|
357
|
-
this.message.info.batteryState = resource.services.device_power ? Object.values(resource.services.device_power)[0].power_state.battery_state : false;
|
|
359
|
+
this.message.info.batteryState = resource.services.device_power ? Object.values(resource.services.device_power)[0].power_state.battery_state : false;
|
|
358
360
|
|
|
359
361
|
this.message.info.model = {};
|
|
360
362
|
this.message.info.model.id = resource.product_data.model_id;
|
|
361
363
|
this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
|
|
362
364
|
this.message.info.model.name = resource.product_data.product_name;
|
|
363
365
|
this.message.info.model.type = resource.product_data.product_archetype;
|
|
364
|
-
this.message.info.model.certified = resource.product_data.certified;
|
|
366
|
+
this.message.info.model.certified = resource.product_data.certified;
|
|
365
367
|
}
|
|
366
368
|
|
|
367
369
|
get msg()
|
|
@@ -414,9 +416,9 @@ class HueTemperatureMessage
|
|
|
414
416
|
|
|
415
417
|
this.message = {};
|
|
416
418
|
this.message.payload = {
|
|
417
|
-
active: service.enabled,
|
|
418
|
-
reachable: connectivity ? (connectivity.status === "connected") : "unknown",
|
|
419
|
-
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
419
|
+
active: service.enabled,
|
|
420
|
+
reachable: connectivity ? (connectivity.status === "connected") : "unknown",
|
|
421
|
+
connectionStatus: connectivity ? connectivity.status : "unknown",
|
|
420
422
|
celsius: celsius,
|
|
421
423
|
fahrenheit: fahrenheit,
|
|
422
424
|
temperatureIs: temperatureMessage,
|
|
@@ -426,21 +428,21 @@ class HueTemperatureMessage
|
|
|
426
428
|
|
|
427
429
|
this.message.info = {};
|
|
428
430
|
this.message.info.id = service.id;
|
|
429
|
-
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
431
|
+
this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false;
|
|
430
432
|
this.message.info.uniqueId = resource.id + "-" + service.id;
|
|
431
|
-
this.message.info.deviceId = resource.id;
|
|
433
|
+
this.message.info.deviceId = resource.id;
|
|
432
434
|
this.message.info.name = resource.metadata.name;
|
|
433
435
|
this.message.info.type = "temperature";
|
|
434
436
|
this.message.info.softwareVersion = resource.product_data.software_version;
|
|
435
437
|
this.message.info.battery = Object.values(resource.services.device_power)[0].power_state.battery_level;
|
|
436
|
-
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
438
|
+
this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state;
|
|
437
439
|
|
|
438
440
|
this.message.info.model = {};
|
|
439
441
|
this.message.info.model.id = resource.product_data.model_id;
|
|
440
442
|
this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
|
|
441
443
|
this.message.info.model.name = resource.product_data.product_name;
|
|
442
444
|
this.message.info.model.type = resource.product_data.product_archetype;
|
|
443
|
-
this.message.info.model.certified = resource.product_data.certified;
|
|
445
|
+
this.message.info.model.certified = resource.product_data.certified;
|
|
444
446
|
}
|
|
445
447
|
|
|
446
448
|
get msg()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-huemagic",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"description": "Philips Hue node to control bridges, lights, groups, scenes, rules, taps, switches, buttons, motion sensors, temperature sensors and Lux sensors using Node-RED.",
|
|
5
5
|
"author": "foddy",
|
|
6
6
|
"homepage": "https://github.com/Foddy/node-red-contrib-huemagic",
|
|
@@ -41,17 +41,20 @@
|
|
|
41
41
|
"hue-rules": "huemagic/hue-rules.js"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=12.0.0"
|
|
46
|
+
},
|
|
44
47
|
"publishConfig": {
|
|
45
48
|
"access": "public"
|
|
46
49
|
},
|
|
47
50
|
"dependencies": {
|
|
48
51
|
"async": "^3.2.2",
|
|
49
|
-
"axios": "^0.
|
|
52
|
+
"axios": "^0.26.1",
|
|
50
53
|
"color-namer": "^1.4.0",
|
|
51
54
|
"colornames": "^1.1.1",
|
|
52
55
|
"dayjs": "^1.10.7",
|
|
53
56
|
"deep-object-diff": "^1.1.0",
|
|
54
|
-
"eventsource": "^
|
|
57
|
+
"eventsource": "^2.0.0",
|
|
55
58
|
"fastq": "^1.13.0",
|
|
56
59
|
"get-image-colors": "^4.0.0"
|
|
57
60
|
}
|