node-red-contrib-huemagic 3.0.0 → 4.0.3

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.
Files changed (138) hide show
  1. package/README.md +764 -603
  2. package/examples/Hue Bridge.json +189 -35
  3. package/examples/Hue Brightness.json +124 -14
  4. package/examples/Hue Buttons.json +88 -0
  5. package/examples/Hue Group.json +575 -63
  6. package/examples/Hue Light.json +805 -58
  7. package/examples/Hue Magic.json +69 -24
  8. package/examples/Hue Motion.json +110 -42
  9. package/examples/Hue Rules.json +105 -37
  10. package/examples/Hue Scene.json +145 -28
  11. package/examples/Hue Temperature.json +124 -14
  12. package/huemagic/animations/019-christmas.json +30 -0
  13. package/huemagic/animations/020-superhero.json +56 -0
  14. package/huemagic/animations/021-neoncity.json +52 -0
  15. package/huemagic/animations/previews/006-fireplace.gif +0 -0
  16. package/huemagic/animations/previews/013-strobo.gif +0 -0
  17. package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
  18. package/huemagic/animations/previews/016-milkyway.gif +0 -0
  19. package/huemagic/animations/previews/018-forest.gif +0 -0
  20. package/huemagic/animations/previews/019-christmas.gif +0 -0
  21. package/huemagic/animations/previews/020-superhero.gif +0 -0
  22. package/huemagic/animations/previews/021-neoncity.gif +0 -0
  23. package/huemagic/hue-bridge-config.html +105 -61
  24. package/huemagic/hue-bridge-config.js +631 -319
  25. package/huemagic/hue-bridge.html +41 -21
  26. package/huemagic/hue-bridge.js +190 -396
  27. package/huemagic/hue-brightness.html +127 -59
  28. package/huemagic/hue-brightness.js +111 -55
  29. package/huemagic/hue-buttons.html +197 -0
  30. package/huemagic/hue-buttons.js +158 -0
  31. package/huemagic/hue-group.html +137 -66
  32. package/huemagic/hue-group.js +387 -403
  33. package/huemagic/hue-light.html +132 -64
  34. package/huemagic/hue-light.js +544 -378
  35. package/huemagic/hue-magic.html +36 -20
  36. package/huemagic/hue-magic.js +49 -27
  37. package/huemagic/hue-motion.html +127 -59
  38. package/huemagic/hue-motion.js +105 -101
  39. package/huemagic/hue-rules.html +121 -50
  40. package/huemagic/hue-rules.js +89 -63
  41. package/huemagic/hue-scene.html +95 -114
  42. package/huemagic/hue-scene.js +64 -95
  43. package/huemagic/hue-temperature.html +127 -59
  44. package/huemagic/hue-temperature.js +120 -56
  45. package/huemagic/icons/hue-bridge.png +0 -0
  46. package/huemagic/icons/hue-bridge.svg +3 -0
  47. package/huemagic/icons/hue-brightness.png +0 -0
  48. package/huemagic/icons/hue-brightness.svg +11 -0
  49. package/huemagic/icons/hue-buttons.png +0 -0
  50. package/huemagic/icons/hue-buttons.svg +4 -0
  51. package/huemagic/icons/hue-group.png +0 -0
  52. package/huemagic/icons/hue-group.svg +12 -0
  53. package/huemagic/icons/hue-light.png +0 -0
  54. package/huemagic/icons/hue-light.svg +3 -0
  55. package/huemagic/icons/hue-magic.png +0 -0
  56. package/huemagic/icons/hue-magic.svg +3 -0
  57. package/huemagic/icons/hue-motion.png +0 -0
  58. package/huemagic/icons/hue-motion.svg +9 -0
  59. package/huemagic/icons/hue-rules.png +0 -0
  60. package/huemagic/icons/hue-rules.svg +4 -0
  61. package/huemagic/icons/hue-scene.png +0 -0
  62. package/huemagic/icons/hue-scene.svg +5 -0
  63. package/huemagic/icons/hue-temperature.png +0 -0
  64. package/huemagic/icons/hue-temperature.svg +7 -0
  65. package/huemagic/locales/de/hue-bridge-config.html +17 -12
  66. package/huemagic/locales/de/hue-bridge-config.json +7 -5
  67. package/huemagic/locales/de/hue-bridge.html +64 -145
  68. package/huemagic/locales/de/hue-bridge.json +6 -17
  69. package/huemagic/locales/de/hue-brightness.html +50 -50
  70. package/huemagic/locales/de/hue-brightness.json +6 -5
  71. package/huemagic/locales/de/hue-buttons.html +58 -0
  72. package/huemagic/locales/de/{hue-button.json → hue-buttons.json} +7 -11
  73. package/huemagic/locales/de/hue-group.html +46 -122
  74. package/huemagic/locales/de/hue-group.json +5 -5
  75. package/huemagic/locales/de/hue-light.html +68 -116
  76. package/huemagic/locales/de/hue-light.json +5 -5
  77. package/huemagic/locales/de/hue-magic.html +65 -57
  78. package/huemagic/locales/de/hue-magic.json +2 -1
  79. package/huemagic/locales/de/hue-motion.html +47 -50
  80. package/huemagic/locales/de/hue-motion.json +5 -5
  81. package/huemagic/locales/de/hue-rules.html +68 -73
  82. package/huemagic/locales/de/hue-rules.json +5 -2
  83. package/huemagic/locales/de/hue-scene.html +23 -32
  84. package/huemagic/locales/de/hue-scene.json +5 -2
  85. package/huemagic/locales/de/hue-temperature.html +51 -48
  86. package/huemagic/locales/de/hue-temperature.json +6 -5
  87. package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
  88. package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
  89. package/huemagic/locales/en-US/hue-bridge.html +64 -145
  90. package/huemagic/locales/en-US/hue-bridge.json +5 -16
  91. package/huemagic/locales/en-US/hue-brightness.html +50 -50
  92. package/huemagic/locales/en-US/hue-brightness.json +5 -2
  93. package/huemagic/locales/en-US/hue-buttons.html +58 -0
  94. package/huemagic/locales/en-US/{hue-button.json → hue-buttons.json} +6 -4
  95. package/huemagic/locales/en-US/hue-group.html +46 -122
  96. package/huemagic/locales/en-US/hue-group.json +4 -2
  97. package/huemagic/locales/en-US/hue-light.html +68 -116
  98. package/huemagic/locales/en-US/hue-light.json +4 -2
  99. package/huemagic/locales/en-US/hue-magic.html +65 -57
  100. package/huemagic/locales/en-US/hue-magic.json +3 -1
  101. package/huemagic/locales/en-US/hue-motion.html +47 -50
  102. package/huemagic/locales/en-US/hue-motion.json +4 -2
  103. package/huemagic/locales/en-US/hue-rules.html +68 -73
  104. package/huemagic/locales/en-US/hue-rules.json +5 -2
  105. package/huemagic/locales/en-US/hue-scene.html +23 -32
  106. package/huemagic/locales/en-US/hue-scene.json +5 -2
  107. package/huemagic/locales/en-US/hue-temperature.html +51 -48
  108. package/huemagic/locales/en-US/hue-temperature.json +5 -2
  109. package/huemagic/utils/api.js +290 -0
  110. package/huemagic/utils/color.js +382 -0
  111. package/{utils → huemagic/utils}/merge.js +4 -6
  112. package/huemagic/utils/messages.js +447 -0
  113. package/package.json +9 -15
  114. package/examples/Hue Button.json +0 -40
  115. package/examples/Hue Switch.json +0 -40
  116. package/examples/Hue Tap.json +0 -40
  117. package/huemagic/hue-button.html +0 -132
  118. package/huemagic/hue-button.js +0 -143
  119. package/huemagic/hue-switch.html +0 -132
  120. package/huemagic/hue-switch.js +0 -163
  121. package/huemagic/hue-tap.html +0 -132
  122. package/huemagic/hue-tap.js +0 -123
  123. package/huemagic/icons/hue-button.png +0 -0
  124. package/huemagic/icons/hue-switch.png +0 -0
  125. package/huemagic/icons/hue-tap.png +0 -0
  126. package/huemagic/locales/de/hue-button.html +0 -64
  127. package/huemagic/locales/de/hue-switch.html +0 -64
  128. package/huemagic/locales/de/hue-switch.json +0 -35
  129. package/huemagic/locales/de/hue-tap.html +0 -55
  130. package/huemagic/locales/de/hue-tap.json +0 -27
  131. package/huemagic/locales/en-US/hue-button.html +0 -64
  132. package/huemagic/locales/en-US/hue-switch.html +0 -64
  133. package/huemagic/locales/en-US/hue-switch.json +0 -35
  134. package/huemagic/locales/en-US/hue-tap.html +0 -55
  135. package/huemagic/locales/en-US/hue-tap.json +0 -27
  136. package/utils/color.js +0 -9
  137. package/utils/messages.js +0 -658
  138. package/utils/rgb.js +0 -188
@@ -0,0 +1,447 @@
1
+ const dayjs = require('dayjs');
2
+ const colorUtils = require("./color");
3
+
4
+ //
5
+ // HUE BRIDGE
6
+ class HueBridgeMessage
7
+ {
8
+ constructor(resource, options = {})
9
+ {
10
+ this.message = {};
11
+ this.message.payload = {};
12
+ this.message.payload.id = resource.bridgeid;
13
+ this.message.payload.name = resource.name;
14
+ this.message.payload.factoryNew = resource.factorynew;
15
+ this.message.payload.replacesBridgeId = resource.replacesbridgeid ? resource.replacesbridgeid : false;
16
+ this.message.payload.dataStoreVersion = resource.datastoreversion;
17
+ this.message.payload.starterKitId = resource.starterkitid.length > 0 ? resource.starterkitid : false;
18
+ this.message.payload.softwareVersion = resource.swversion;
19
+ this.message.payload.apiVersion = resource.apiversion;
20
+ this.message.payload.zigbeeChannel = resource.zigbeechannel;
21
+ this.message.payload.macAddress = resource.mac;
22
+ this.message.payload.ipAddress = resource.ipaddress;
23
+ this.message.payload.dhcpEnabled = resource.dhcp;
24
+ this.message.payload.netmask = resource.netmask;
25
+ this.message.payload.gateway = resource.gateway;
26
+ this.message.payload.proxyAddress = resource.proxyaddress == "none" ? false : resource.proxyaddress;
27
+ this.message.payload.proxyPort = resource.proxyport;
28
+ this.message.payload.utcTime = resource.UTC;
29
+ this.message.payload.timeZone = resource.timezone;
30
+ this.message.payload.localTime = resource.localtime;
31
+ this.message.payload.portalServicesEnabled = resource.portalservices;
32
+ this.message.payload.portalConnected = resource.portalconnection;
33
+ this.message.payload.linkButtonEnabled = resource.linkbutton;
34
+ this.message.payload.touchlinkEnabled = (resource["touchlink"] && resource["touchlink"] == true) ? true : false;
35
+ this.message.payload.autoUpdatesEnabled = options["autoupdate"] ? options["autoupdate"] : false;
36
+ this.message.payload.users = []; // NEW!
37
+ this.message.payload.updated = resource.updated; // NEW!
38
+
39
+ this.message.payload.model = {};
40
+ this.message.payload.model.id = resource.modelid;
41
+ this.message.payload.model.manufacturer = "Philips";
42
+ this.message.payload.model.name = "Hue v2";
43
+
44
+ // GET USERS
45
+ for (const [userID, user] of Object.entries(resource["whitelist"]))
46
+ {
47
+ this.message.payload.users.push({
48
+ user: userID,
49
+ name: user["name"],
50
+ created: user["create date"],
51
+ lastAccess: user["last use date"]
52
+ });
53
+ }
54
+ }
55
+
56
+ get msg()
57
+ {
58
+ return this.message;
59
+ }
60
+ }
61
+
62
+
63
+ //
64
+ // HUE BRIGHTNESS
65
+ class HueBrightnessMessage
66
+ {
67
+ constructor(resource, options = {})
68
+ {
69
+ const service = Object.values(resource["services"]["light_level"])[0];
70
+ const connectivity = resource.services.zigbee_connectivity ? Object.values(resource.services.zigbee_connectivity)[0] : ((resource.services.zgp_connectivity) ? Object.values(resource.services.zgp_connectivity)[0] : false);
71
+
72
+ var realLUX = service.light.light_level - 1;
73
+ realLUX = realLUX / 10000;
74
+ realLUX = Math.round(Math.pow(10, realLUX));
75
+
76
+ this.message = {};
77
+ this.message.payload = {};
78
+ this.message.payload.active = service.enabled; // NEW!
79
+ this.message.payload.reachable = connectivity ? (connectivity.status === "connected") : "unknown"; // NEW!
80
+ this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown"; // NEW!
81
+ this.message.payload.lux = realLUX;
82
+ this.message.payload.lightLevel = service.light.light_level;
83
+ this.message.payload.dark = (realLUX < 200);
84
+ this.message.payload.daylight = (realLUX > 200);
85
+ this.message.payload.updated = resource.updated;
86
+
87
+ this.message.info = {};
88
+ this.message.info.id = service.id;
89
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
90
+ this.message.info.uniqueId = resource.id + "-" + service.id;
91
+ this.message.info.deviceId = resource.id; // NEW!
92
+ this.message.info.name = resource.metadata.name;
93
+ this.message.info.type = "light_level";
94
+ this.message.info.softwareVersion = resource.product_data.software_version;
95
+ 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; // NEW!
97
+
98
+ this.message.info.model = {};
99
+ this.message.info.model.id = resource.product_data.model_id;
100
+ this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
101
+ this.message.info.model.name = resource.product_data.product_name;
102
+ this.message.info.model.type = resource.product_data.product_archetype;
103
+ this.message.info.model.certified = resource.product_data.certified; // NEW
104
+ }
105
+
106
+ get msg()
107
+ {
108
+ return this.message;
109
+ }
110
+ }
111
+
112
+
113
+ //
114
+ // HUE GROUP
115
+ class HueGroupMessage
116
+ {
117
+ constructor(resource, options = {})
118
+ {
119
+ let service = Object.values(resource["services"]["grouped_light"])[0];
120
+ service = options.resources[service.id];
121
+
122
+ this.message = {};
123
+ this.message.payload = {};
124
+ this.message.payload.on = service.on.on;
125
+ this.message.payload.updated = resource.updated;
126
+
127
+ this.message.info = {};
128
+ this.message.info.id = resource.id;
129
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
130
+ this.message.info.name = resource.metadata ? resource.metadata.name : "all";
131
+ this.message.info.type = "group";
132
+ }
133
+
134
+ get msg()
135
+ {
136
+ return this.message;
137
+ }
138
+ }
139
+
140
+
141
+ //
142
+ // HUE LIGHT
143
+ class HueLightMessage
144
+ {
145
+ constructor(resource, options = {})
146
+ {
147
+ const service = Object.values(resource["services"]["light"])[0];
148
+ const connectivity = resource.services.zigbee_connectivity ? Object.values(resource.services.zigbee_connectivity)[0] : ((resource.services.zgp_connectivity) ? Object.values(resource.services.zgp_connectivity)[0] : false);
149
+
150
+ this.message = {};
151
+ this.message.payload = {};
152
+ this.message.payload.on = service.on.on;
153
+ this.message.payload.brightness = service.dimming ? service.dimming.brightness : false;
154
+ this.message.payload.brightnessLevel = service.dimming ? Math.round((254/100)*this.message.payload.brightness) : false;
155
+ this.message.payload.reachable = connectivity ? (connectivity.status === "connected") : "unknown";
156
+ this.message.payload.connectionStatus = connectivity ? connectivity.status : "unknown"; // NEW!
157
+ this.message.payload.updated = resource.updated;
158
+
159
+ this.message.info = {};
160
+ this.message.info.id = service.id;
161
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
162
+ this.message.info.uniqueId = resource.id + "-" + service.id;
163
+ this.message.info.deviceId = resource.id; // NEW!
164
+ this.message.info.name = service.metadata.name;
165
+ this.message.info.type = "light";
166
+ this.message.info.softwareVersion = resource.product_data.software_version;
167
+
168
+ this.message.info.model = {};
169
+ this.message.info.model.id = resource.product_data.model_id;
170
+ this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
171
+ this.message.info.model.name = resource.product_data.product_name;
172
+ this.message.info.model.type = resource.product_data.product_archetype;
173
+ this.message.info.model.certified = resource.product_data.certified; // NEW
174
+ this.message.info.model.friendsOfHue = true;
175
+
176
+ // HAS COLOR CAPABILITIES?
177
+ if(service["color"])
178
+ {
179
+ let RGB = colorUtils.xyBriToRgb(service.color.xy.x, service.color.xy.y, (service.dimming ? service.dimming.brightness : 100));
180
+ this.message.payload.rgb = [RGB.r, RGB.g, RGB.b];
181
+ this.message.payload.hex = colorUtils.rgbHex(RGB.r, RGB.g, RGB.b);
182
+ this.message.payload.xyColor = service.color.xy; // NEW!
183
+
184
+ if(options.colornames == true)
185
+ {
186
+ var cNamesArray = colorUtils.colornamer(colorUtils.rgbHex(RGB.r, RGB.g, RGB.b));
187
+ this.message.payload.color = cNamesArray.basic[0]["name"];
188
+ }
189
+
190
+ this.message.info.model.colorGamut = service.color.gamut; // NEW
191
+ this.message.info.model.colorGamutType = service.color.gamut_type; // NEW
192
+ }
193
+
194
+ // HAS COLOR TEMPERATURE CAPABILITIES?
195
+ if(service["color_temperature"])
196
+ {
197
+ this.message.payload.colorTemp = service.color_temperature.mirek ? service.color_temperature.mirek : false;
198
+
199
+ if(!this.message.payload.colorTemp) { this.message.payload.colorTempName = "unknown"; }
200
+ else if(this.message.payload.colorTemp < 200) { this.message.payload.colorTempName = "cold"; } // NEW!
201
+ else if(this.message.payload.colorTemp < 350) { this.message.payload.colorTempName = "normal"; }
202
+ else if(this.message.payload.colorTemp < 410) { this.message.payload.colorTempName = "warm"; }
203
+ else { this.message.payload.colorTempName = "hot"; }
204
+ }
205
+
206
+ // HAS GRADIENT COLOR CAPABILITIES?
207
+ if(service["gradient"]) // NEW!
208
+ {
209
+ this.message.payload.gradient = {};
210
+ this.message.payload.gradient.colors = [];
211
+
212
+ for(let gradientColor in service["gradient"]["points"])
213
+ {
214
+ let gradientColorRGB = colorUtils.xyBriToRgb(gradientColor.color.xy.x, gradientColor.color.xy.y, (gradientColor.dimming ? service.dimming.brightness : 100));
215
+
216
+ let oneColorPack = {};
217
+ oneColorPack.rgb = [gradientColorRGB.r, gradientColorRGB.g, gradientColorRGB.b];
218
+ oneColorPack.hex = colorUtils.rgbHex(gradientColorRGB.r, gradientColorRGB.g, gradientColorRGB.b);
219
+ oneColorPack.xyColor = gradientColor.color.xy.x;
220
+
221
+ this.message.payload.gradient.colors.push(oneColorPack);
222
+ }
223
+
224
+ this.message.payload.gradient.numColors = service["gradient"]["points"] ? service["gradient"]["points"].length : 0;
225
+ this.message.payload.gradient.totalColors = service["gradient"]["points_capable"];
226
+ }
227
+ }
228
+
229
+ get msg()
230
+ {
231
+ return this.message;
232
+ }
233
+ }
234
+
235
+
236
+ //
237
+ // HUE MOTION
238
+ class HueMotionMessage
239
+ {
240
+ constructor(resource, options = {})
241
+ {
242
+ const service = Object.values(resource["services"]["motion"])[0];
243
+ const connectivity = resource.services.zigbee_connectivity ? Object.values(resource.services.zigbee_connectivity)[0] : ((resource.services.zgp_connectivity) ? Object.values(resource.services.zgp_connectivity)[0] : false);
244
+
245
+ this.message = {};
246
+ this.message.payload = {
247
+ active: service.enabled,
248
+ reachable: connectivity ? (connectivity.status === "connected") : "unknown",
249
+ connectionStatus: connectivity ? connectivity.status : "unknown", // NEW!
250
+ motion: (service.motion.motion && service.motion.motion_valid),
251
+ updated: resource.updated
252
+ };
253
+
254
+ this.message.info = {};
255
+ this.message.info.id = service.id;
256
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
257
+ this.message.info.uniqueId = resource.id + "-" + service.id;
258
+ this.message.info.deviceId = resource.id; // NEW!
259
+ this.message.info.name = resource.metadata.name;
260
+ this.message.info.type = "motion";
261
+ this.message.info.softwareVersion = resource.product_data.software_version;
262
+ this.message.info.battery = Object.values(resource.services.device_power)[0].power_state.battery_level;
263
+ this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state; // NEW!
264
+
265
+ this.message.info.model = {};
266
+ this.message.info.model.id = resource.product_data.model_id;
267
+ this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
268
+ this.message.info.model.name = resource.product_data.product_name;
269
+ this.message.info.model.type = resource.product_data.product_archetype;
270
+ this.message.info.model.certified = resource.product_data.certified; // NEW
271
+ }
272
+
273
+ get msg()
274
+ {
275
+ return this.message;
276
+ }
277
+ }
278
+
279
+
280
+ //
281
+ // HUE RULES
282
+ class HueRulesMessage
283
+ {
284
+ constructor(resource, options = {})
285
+ {
286
+ this.message = {};
287
+ this.message.payload = {};
288
+ this.message.payload.enabled = (resource["status"] == "enabled"); // NEW!
289
+ this.message.payload.triggered = (resource["lasttriggered"] != null) ? dayjs(resource["lasttriggered"]).format() : false;
290
+
291
+ this.message.info = {};
292
+ this.message.info.id = resource["id"];
293
+ this.message.info.created = dayjs(resource["created"]).format();
294
+ this.message.info.name = resource["name"];
295
+ this.message.info.timesTriggered = resource["timestriggered"];
296
+ this.message.info.owner = resource["_owner"];
297
+ this.message.info.status = resource["status"];
298
+
299
+ this.message.conditions = resource["conditions"];
300
+ this.message.actions = resource["actions"];
301
+ }
302
+
303
+ get msg()
304
+ {
305
+ return this.message;
306
+ }
307
+ }
308
+
309
+
310
+ //
311
+ // HUE BUTTONS
312
+ class HueButtonsMessage
313
+ {
314
+ constructor(resource, options = {})
315
+ {
316
+ const connectivity = resource.services.zigbee_connectivity ? Object.values(resource.services.zigbee_connectivity)[0] : ((resource.services.zgp_connectivity) ? Object.values(resource.services.zgp_connectivity)[0] : false);
317
+
318
+ // FIND PRESSED BUTTON
319
+ var pressedButton = false;
320
+ const allButtons = Object.values(resource.services.button);
321
+
322
+ for (var i = allButtons.length - 1; i >= 0; i--)
323
+ {
324
+ if(allButtons[i]["button"])
325
+ {
326
+ pressedButton = allButtons[i];
327
+ break;
328
+ }
329
+ }
330
+
331
+ this.message = {};
332
+ this.message.payload = {
333
+ reachable: connectivity ? (connectivity.status === "connected") : "unknown", // NEW!
334
+ connectionStatus: connectivity ? connectivity.status : "unknown", // NEW!
335
+ button: pressedButton ? pressedButton.metadata.control_id : false, // NEW
336
+ action: pressedButton ? pressedButton.button.last_event : false, // NEW
337
+ updated: resource.updated
338
+ };
339
+
340
+ this.message.info = {};
341
+ this.message.info.id = pressedButton ? pressedButton.id : resource.id;
342
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
343
+ this.message.info.uniqueId = resource.id + "-" + (pressedButton ? pressedButton.id : "");
344
+ this.message.info.deviceId = resource.id; // NEW!
345
+ this.message.info.name = resource.metadata.name;
346
+ this.message.info.type = "button";
347
+ this.message.info.softwareVersion = resource.product_data.software_version;
348
+ this.message.info.battery = resource.services.device_power ? Object.values(resource.services.device_power)[0].power_state.battery_level : false;
349
+ this.message.info.batteryState = resource.services.device_power ? Object.values(resource.services.device_power)[0].power_state.battery_state : false; // NEW!
350
+
351
+ this.message.info.model = {};
352
+ this.message.info.model.id = resource.product_data.model_id;
353
+ this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
354
+ this.message.info.model.name = resource.product_data.product_name;
355
+ this.message.info.model.type = resource.product_data.product_archetype;
356
+ this.message.info.model.certified = resource.product_data.certified; // NEW
357
+ }
358
+
359
+ get msg()
360
+ {
361
+ return this.message;
362
+ }
363
+ }
364
+
365
+
366
+ //
367
+ // HUE TEMPERATURE
368
+ class HueTemperatureMessage
369
+ {
370
+ constructor(resource, options = {})
371
+ {
372
+ const service = Object.values(resource["services"]["temperature"])[0];
373
+ const connectivity = resource.services.zigbee_connectivity ? Object.values(resource.services.zigbee_connectivity)[0] : ((resource.services.zgp_connectivity) ? Object.values(resource.services.zgp_connectivity)[0] : false);
374
+
375
+ var deviceValue = service.temperature.temperature;
376
+ var celsius = Math.round(deviceValue * 100) / 100;
377
+ var fahrenheit = Math.round(((celsius * 1.8)+32) * 100) / 100;
378
+
379
+ // TEMPERATURE MESSAGE
380
+ let temperatureMessage = "comfortable";
381
+
382
+ if(celsius < 0) {
383
+ temperatureMessage = "very cold";
384
+ }
385
+ else if(celsius < 11) {
386
+ temperatureMessage = "cold";
387
+ }
388
+ else if(celsius < 16) {
389
+ temperatureMessage = "slightly cold";
390
+ }
391
+ else if(celsius < 22) {
392
+ temperatureMessage = "comfortable";
393
+ }
394
+ else if(celsius < 27) {
395
+ temperatureMessage = "slightly warm";
396
+ }
397
+ else if(celsius < 33) {
398
+ temperatureMessage = "warm";
399
+ }
400
+ else if(celsius < 39) {
401
+ temperatureMessage = "hot";
402
+ }
403
+ else {
404
+ temperatureMessage = "very hot";
405
+ }
406
+
407
+ this.message = {};
408
+ this.message.payload = {
409
+ active: service.enabled, // NEW!
410
+ reachable: connectivity ? (connectivity.status === "connected") : "unknown", // NEW!
411
+ connectionStatus: connectivity ? connectivity.status : "unknown", // NEW!
412
+ celsius: celsius,
413
+ fahrenheit: fahrenheit,
414
+ temperatureIs: temperatureMessage,
415
+ deviceValue: deviceValue,
416
+ updated: resource.updated
417
+ };
418
+
419
+ this.message.info = {};
420
+ this.message.info.id = service.id;
421
+ this.message.info.idV1 = resource.id_v1 ? resource.id_v1 : false; // NEW
422
+ this.message.info.uniqueId = resource.id + "-" + service.id;
423
+ this.message.info.deviceId = resource.id; // NEW!
424
+ this.message.info.name = resource.metadata.name;
425
+ this.message.info.type = "temperature";
426
+ this.message.info.softwareVersion = resource.product_data.software_version;
427
+ this.message.info.battery = Object.values(resource.services.device_power)[0].power_state.battery_level;
428
+ this.message.info.batteryState = Object.values(resource.services.device_power)[0].power_state.battery_state; // NEW!
429
+
430
+ this.message.info.model = {};
431
+ this.message.info.model.id = resource.product_data.model_id;
432
+ this.message.info.model.manufacturer = resource.product_data.manufacturer_name;
433
+ this.message.info.model.name = resource.product_data.product_name;
434
+ this.message.info.model.type = resource.product_data.product_archetype;
435
+ this.message.info.model.certified = resource.product_data.certified; // NEW
436
+ }
437
+
438
+ get msg()
439
+ {
440
+ return this.message;
441
+ }
442
+ }
443
+
444
+ //
445
+ // EXPORT
446
+ module.exports = { HueBridgeMessage, HueBrightnessMessage, HueGroupMessage, HueLightMessage, HueMotionMessage, HueRulesMessage, HueButtonsMessage, HueTemperatureMessage }
447
+
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "node-red-contrib-huemagic",
3
- "version": "3.0.0",
3
+ "version": "4.0.3",
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",
7
7
  "license": "Apache-2.0",
8
- "scripts": {
9
- "generate:previews": "node ./helper/huemagic-gifmaker/index.js && node ./helper/huemagic-gifmaker/optimize.js"
10
- },
11
8
  "maintainers": [
12
9
  "Foddy Botosakis <github@foddys.com>"
13
10
  ],
@@ -37,9 +34,7 @@
37
34
  "hue-light": "huemagic/hue-light.js",
38
35
  "hue-group": "huemagic/hue-group.js",
39
36
  "hue-scene": "huemagic/hue-scene.js",
40
- "hue-tap": "huemagic/hue-tap.js",
41
- "hue-switch": "huemagic/hue-switch.js",
42
- "hue-button": "huemagic/hue-button.js",
37
+ "hue-buttons": "huemagic/hue-buttons.js",
43
38
  "hue-motion": "huemagic/hue-motion.js",
44
39
  "hue-temperature": "huemagic/hue-temperature.js",
45
40
  "hue-brightness": "huemagic/hue-brightness.js",
@@ -50,14 +45,13 @@
50
45
  "access": "public"
51
46
  },
52
47
  "dependencies": {
53
- "async": "^3.2.0",
54
- "hex-rgb": "^4.2.0",
55
- "huejay": "^1.9.0",
56
- "moment": "^2.29.1",
57
- "rgb-hex": "^3.0.0",
58
- "request": "^2.88.2",
59
- "colornames": "^1.1.1",
48
+ "async": "^3.2.2",
49
+ "axios": "^0.24.0",
60
50
  "color-namer": "^1.4.0",
51
+ "colornames": "^1.1.1",
52
+ "dayjs": "^1.10.7",
53
+ "deep-object-diff": "^1.1.0",
54
+ "eventsource": "^1.1.0",
61
55
  "get-image-colors": "^4.0.0"
62
56
  }
63
- }
57
+ }
@@ -1,40 +0,0 @@
1
- [
2
- {
3
- "id": "d5d4a606.0f05",
4
- "type": "tab",
5
- "label": "Hue Button (example)",
6
- "disabled": false,
7
- "info": "Example use of the Hue Button node"
8
- },
9
- {
10
- "id": "897758f5.e19ee8",
11
- "type": "debug",
12
- "z": "d5d4a606.0f05",
13
- "name": "Information",
14
- "active": true,
15
- "tosidebar": true,
16
- "console": false,
17
- "tostatus": false,
18
- "complete": "payload",
19
- "targetType": "msg",
20
- "x": 330,
21
- "y": 60,
22
- "wires": [],
23
- "icon": "font-awesome/fa-info-circle"
24
- },
25
- {
26
- "id": "b190f9f5.2d8f",
27
- "type": "hue-button",
28
- "z": "d5d4a606.0f05",
29
- "name": "",
30
- "sensorid": "",
31
- "skipevents": false,
32
- "x": 130,
33
- "y": 60,
34
- "wires": [
35
- [
36
- "897758f5.e19ee8"
37
- ]
38
- ]
39
- }
40
- ]
@@ -1,40 +0,0 @@
1
- [
2
- {
3
- "id": "e3a959fd.39da6",
4
- "type": "tab",
5
- "label": "Hue Switch (example)",
6
- "disabled": false,
7
- "info": "Example use of the Hue Switch node"
8
- },
9
- {
10
- "id": "d481c97b.56f63",
11
- "type": "debug",
12
- "z": "e3a959fd.39da6",
13
- "name": "Information",
14
- "active": true,
15
- "tosidebar": true,
16
- "console": false,
17
- "tostatus": false,
18
- "complete": "payload",
19
- "targetType": "msg",
20
- "x": 330,
21
- "y": 60,
22
- "wires": [],
23
- "icon": "font-awesome/fa-info-circle"
24
- },
25
- {
26
- "id": "de4dca53.31075",
27
- "type": "hue-switch",
28
- "z": "e3a959fd.39da6",
29
- "name": "",
30
- "sensorid": "",
31
- "skipevents": false,
32
- "x": 130,
33
- "y": 60,
34
- "wires": [
35
- [
36
- "d481c97b.56f63"
37
- ]
38
- ]
39
- }
40
- ]
@@ -1,40 +0,0 @@
1
- [
2
- {
3
- "id": "e3a959fd.39da6",
4
- "type": "tab",
5
- "label": "Hue Tap (example)",
6
- "disabled": false,
7
- "info": "Example use of the Hue Tap node"
8
- },
9
- {
10
- "id": "d481c97b.56f63",
11
- "type": "debug",
12
- "z": "e3a959fd.39da6",
13
- "name": "Information",
14
- "active": true,
15
- "tosidebar": true,
16
- "console": false,
17
- "tostatus": false,
18
- "complete": "payload",
19
- "targetType": "msg",
20
- "x": 310,
21
- "y": 60,
22
- "wires": [],
23
- "icon": "font-awesome/fa-info-circle"
24
- },
25
- {
26
- "id": "7553e1a.fc48c2",
27
- "type": "hue-tap",
28
- "z": "e3a959fd.39da6",
29
- "name": "",
30
- "sensorid": "",
31
- "skipevents": false,
32
- "x": 120,
33
- "y": 60,
34
- "wires": [
35
- [
36
- "d481c97b.56f63"
37
- ]
38
- ]
39
- }
40
- ]