node-red-contrib-huemagic 4.2.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/CHANGELOG.md +89 -5
  2. package/README.md +506 -123
  3. package/examples/Deutsch/Hue Automation.json +176 -0
  4. package/examples/Deutsch/Hue Bridge.json +256 -0
  5. package/examples/Deutsch/Hue Brightness.json +150 -0
  6. package/examples/Deutsch/Hue Buttons.json +88 -0
  7. package/examples/Deutsch/Hue Contact.json +150 -0
  8. package/examples/Deutsch/Hue Group.json +658 -0
  9. package/examples/Deutsch/Hue Light.json +893 -0
  10. package/examples/Deutsch/Hue Magic.json +148 -0
  11. package/examples/Deutsch/Hue Motion.json +150 -0
  12. package/examples/Deutsch/Hue Rules.json +150 -0
  13. package/examples/Deutsch/Hue Scene.json +178 -0
  14. package/examples/Deutsch/Hue Speaker.json +274 -0
  15. package/examples/Deutsch/Hue Sync Box.json +378 -0
  16. package/examples/Deutsch/Hue Temperature.json +150 -0
  17. package/examples/English/Hue Automation.json +176 -0
  18. package/examples/{Hue Bridge.json → English/Hue Bridge.json } +1 -1
  19. package/examples/{Hue Brightness.json → English/Hue Brightness.json } +1 -1
  20. package/examples/{Hue Buttons.json → English/Hue Buttons.json } +1 -1
  21. package/examples/English/Hue Contact.json +150 -0
  22. package/examples/{Hue Group.json → English/Hue Group.json } +1 -1
  23. package/examples/{Hue Light.json → English/Hue Light.json } +1 -1
  24. package/examples/{Hue Magic.json → English/Hue Magic.json } +1 -1
  25. package/examples/{Hue Motion.json → English/Hue Motion.json } +1 -1
  26. package/examples/{Hue Rules.json → English/Hue Rules.json } +1 -1
  27. package/examples/{Hue Scene.json → English/Hue Scene.json } +1 -1
  28. package/examples/English/Hue Speaker.json +274 -0
  29. package/examples/English/Hue Sync Box.json +378 -0
  30. package/examples/{Hue Temperature.json → English/Hue Temperature.json } +1 -1
  31. package/examples/Espa/303/261ol/Hue Automation.json" +176 -0
  32. package/examples/Espa/303/261ol/Hue Bridge.json" +256 -0
  33. package/examples/Espa/303/261ol/Hue Brightness.json" +150 -0
  34. package/examples/Espa/303/261ol/Hue Buttons.json" +88 -0
  35. package/examples/Espa/303/261ol/Hue Contact.json" +150 -0
  36. package/examples/Espa/303/261ol/Hue Group.json" +658 -0
  37. package/examples/Espa/303/261ol/Hue Light.json" +893 -0
  38. package/examples/Espa/303/261ol/Hue Magic.json" +148 -0
  39. package/examples/Espa/303/261ol/Hue Motion.json" +150 -0
  40. package/examples/Espa/303/261ol/Hue Rules.json" +150 -0
  41. package/examples/Espa/303/261ol/Hue Scene.json" +178 -0
  42. package/examples/Espa/303/261ol/Hue Speaker.json" +274 -0
  43. package/examples/Espa/303/261ol/Hue Sync Box.json" +378 -0
  44. package/examples/Espa/303/261ol/Hue Temperature.json" +150 -0
  45. package/examples/Fran/303/247ais/Hue Automation.json" +176 -0
  46. package/examples/Fran/303/247ais/Hue Bridge.json" +256 -0
  47. package/examples/Fran/303/247ais/Hue Brightness.json" +150 -0
  48. package/examples/Fran/303/247ais/Hue Buttons.json" +88 -0
  49. package/examples/Fran/303/247ais/Hue Contact.json" +150 -0
  50. package/examples/Fran/303/247ais/Hue Group.json" +658 -0
  51. package/examples/Fran/303/247ais/Hue Light.json" +893 -0
  52. package/examples/Fran/303/247ais/Hue Magic.json" +148 -0
  53. package/examples/Fran/303/247ais/Hue Motion.json" +150 -0
  54. package/examples/Fran/303/247ais/Hue Rules.json" +150 -0
  55. package/examples/Fran/303/247ais/Hue Scene.json" +178 -0
  56. package/examples/Fran/303/247ais/Hue Speaker.json" +274 -0
  57. package/examples/Fran/303/247ais/Hue Sync Box.json" +378 -0
  58. package/examples/Fran/303/247ais/Hue Temperature.json" +150 -0
  59. package/examples/Italiano/Hue Automation.json +176 -0
  60. package/examples/Italiano/Hue Bridge.json +256 -0
  61. package/examples/Italiano/Hue Brightness.json +150 -0
  62. package/examples/Italiano/Hue Buttons.json +88 -0
  63. package/examples/Italiano/Hue Contact.json +150 -0
  64. package/examples/Italiano/Hue Group.json +658 -0
  65. package/examples/Italiano/Hue Light.json +893 -0
  66. package/examples/Italiano/Hue Magic.json +148 -0
  67. package/examples/Italiano/Hue Motion.json +150 -0
  68. package/examples/Italiano/Hue Rules.json +150 -0
  69. package/examples/Italiano/Hue Scene.json +178 -0
  70. package/examples/Italiano/Hue Speaker.json +274 -0
  71. package/examples/Italiano/Hue Sync Box.json +378 -0
  72. package/examples/Italiano/Hue Temperature.json +150 -0
  73. package/examples/Nederlands/Hue Automation.json +176 -0
  74. package/examples/Nederlands/Hue Bridge.json +256 -0
  75. package/examples/Nederlands/Hue Brightness.json +150 -0
  76. package/examples/Nederlands/Hue Buttons.json +88 -0
  77. package/examples/Nederlands/Hue Contact.json +150 -0
  78. package/examples/Nederlands/Hue Group.json +658 -0
  79. package/examples/Nederlands/Hue Light.json +893 -0
  80. package/examples/Nederlands/Hue Magic.json +148 -0
  81. package/examples/Nederlands/Hue Motion.json +150 -0
  82. package/examples/Nederlands/Hue Rules.json +150 -0
  83. package/examples/Nederlands/Hue Scene.json +178 -0
  84. package/examples/Nederlands/Hue Speaker.json +274 -0
  85. package/examples/Nederlands/Hue Sync Box.json +378 -0
  86. package/examples/Nederlands/Hue Temperature.json +150 -0
  87. package/examples/Polski/Hue Automation.json +176 -0
  88. package/examples/Polski/Hue Bridge.json +256 -0
  89. package/examples/Polski/Hue Brightness.json +150 -0
  90. package/examples/Polski/Hue Buttons.json +88 -0
  91. package/examples/Polski/Hue Contact.json +150 -0
  92. package/examples/Polski/Hue Group.json +658 -0
  93. package/examples/Polski/Hue Light.json +893 -0
  94. package/examples/Polski/Hue Magic.json +148 -0
  95. package/examples/Polski/Hue Motion.json +150 -0
  96. package/examples/Polski/Hue Rules.json +150 -0
  97. package/examples/Polski/Hue Scene.json +178 -0
  98. package/examples/Polski/Hue Speaker.json +274 -0
  99. package/examples/Polski/Hue Sync Box.json +378 -0
  100. package/examples/Polski/Hue Temperature.json +150 -0
  101. package/examples/Portugu/303/252s/Hue Automation.json" +176 -0
  102. package/examples/Portugu/303/252s/Hue Bridge.json" +256 -0
  103. package/examples/Portugu/303/252s/Hue Brightness.json" +150 -0
  104. package/examples/Portugu/303/252s/Hue Buttons.json" +88 -0
  105. package/examples/Portugu/303/252s/Hue Contact.json" +150 -0
  106. package/examples/Portugu/303/252s/Hue Group.json" +658 -0
  107. package/examples/Portugu/303/252s/Hue Light.json" +893 -0
  108. package/examples/Portugu/303/252s/Hue Magic.json" +148 -0
  109. package/examples/Portugu/303/252s/Hue Motion.json" +150 -0
  110. package/examples/Portugu/303/252s/Hue Rules.json" +150 -0
  111. package/examples/Portugu/303/252s/Hue Scene.json" +178 -0
  112. package/examples/Portugu/303/252s/Hue Speaker.json" +274 -0
  113. package/examples/Portugu/303/252s/Hue Sync Box.json" +378 -0
  114. package/examples/Portugu/303/252s/Hue Temperature.json" +150 -0
  115. package/examples/T/303/274rk/303/247e/Hue Automation.json" +176 -0
  116. package/examples/T/303/274rk/303/247e/Hue Bridge.json" +256 -0
  117. package/examples/T/303/274rk/303/247e/Hue Brightness.json" +150 -0
  118. package/examples/T/303/274rk/303/247e/Hue Buttons.json" +88 -0
  119. package/examples/T/303/274rk/303/247e/Hue Contact.json" +150 -0
  120. package/examples/T/303/274rk/303/247e/Hue Group.json" +658 -0
  121. package/examples/T/303/274rk/303/247e/Hue Light.json" +893 -0
  122. package/examples/T/303/274rk/303/247e/Hue Magic.json" +148 -0
  123. package/examples/T/303/274rk/303/247e/Hue Motion.json" +150 -0
  124. package/examples/T/303/274rk/303/247e/Hue Rules.json" +150 -0
  125. package/examples/T/303/274rk/303/247e/Hue Scene.json" +178 -0
  126. package/examples/T/303/274rk/303/247e/Hue Speaker.json" +274 -0
  127. package/examples/T/303/274rk/303/247e/Hue Sync Box.json" +378 -0
  128. package/examples/T/303/274rk/303/247e/Hue Temperature.json" +150 -0
  129. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Automation.json" +176 -0
  130. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Bridge.json" +256 -0
  131. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Brightness.json" +150 -0
  132. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Buttons.json" +88 -0
  133. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Contact.json" +150 -0
  134. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Group.json" +658 -0
  135. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Light.json" +893 -0
  136. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Magic.json" +148 -0
  137. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Motion.json" +150 -0
  138. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Rules.json" +150 -0
  139. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Scene.json" +178 -0
  140. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Speaker.json" +274 -0
  141. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Sync Box.json" +378 -0
  142. package/examples//316/225/316/273/316/273/316/267/316/275/316/271/316/272/316/254/Hue Temperature.json" +150 -0
  143. package/huemagic/assets/huemagic-examples.gif +0 -0
  144. package/huemagic/hue-automation.html +218 -0
  145. package/huemagic/hue-automation.js +173 -0
  146. package/huemagic/hue-bridge-config.html +39 -32
  147. package/huemagic/hue-bridge-config.js +290 -99
  148. package/huemagic/hue-bridge.html +8 -8
  149. package/huemagic/hue-bridge.js +29 -4
  150. package/huemagic/hue-brightness.html +21 -9
  151. package/huemagic/hue-brightness.js +20 -10
  152. package/huemagic/hue-buttons.html +16 -9
  153. package/huemagic/hue-buttons.js +90 -27
  154. package/huemagic/hue-contact.html +218 -0
  155. package/huemagic/hue-contact.js +209 -0
  156. package/huemagic/hue-group.html +16 -9
  157. package/huemagic/hue-group.js +141 -179
  158. package/huemagic/hue-light.html +19 -12
  159. package/huemagic/hue-light.js +222 -167
  160. package/huemagic/hue-magic.html +3 -5
  161. package/huemagic/hue-motion.html +16 -9
  162. package/huemagic/hue-motion.js +37 -8
  163. package/huemagic/hue-rules.html +16 -9
  164. package/huemagic/hue-rules.js +16 -8
  165. package/huemagic/hue-scene.html +9 -5
  166. package/huemagic/hue-scene.js +52 -16
  167. package/huemagic/hue-speaker.html +218 -0
  168. package/huemagic/hue-speaker.js +257 -0
  169. package/huemagic/hue-syncbox-config.html +123 -0
  170. package/huemagic/hue-syncbox-config.js +179 -0
  171. package/huemagic/hue-syncbox.html +82 -0
  172. package/huemagic/hue-syncbox.js +274 -0
  173. package/huemagic/hue-temperature.html +21 -9
  174. package/huemagic/hue-temperature.js +18 -10
  175. package/huemagic/icons/hue-automation.png +0 -0
  176. package/huemagic/icons/hue-automation.svg +3 -0
  177. package/huemagic/icons/hue-contact.png +0 -0
  178. package/huemagic/icons/hue-contact.svg +4 -0
  179. package/huemagic/icons/hue-speaker.png +0 -0
  180. package/huemagic/icons/hue-speaker.svg +6 -0
  181. package/huemagic/icons/hue-syncbox.png +0 -0
  182. package/huemagic/icons/hue-syncbox.svg +7 -0
  183. package/huemagic/locales/de/hue-automation.html +59 -0
  184. package/huemagic/locales/de/hue-automation.json +33 -0
  185. package/huemagic/locales/de/hue-bridge-config.json +23 -12
  186. package/huemagic/locales/de/hue-bridge.html +7 -4
  187. package/huemagic/locales/de/hue-bridge.json +9 -10
  188. package/huemagic/locales/de/hue-brightness.html +9 -6
  189. package/huemagic/locales/de/hue-brightness.json +13 -9
  190. package/huemagic/locales/de/hue-buttons.html +5 -4
  191. package/huemagic/locales/de/hue-buttons.json +22 -8
  192. package/huemagic/locales/de/hue-contact.html +67 -0
  193. package/huemagic/locales/de/hue-contact.json +35 -0
  194. package/huemagic/locales/de/hue-group.html +17 -6
  195. package/huemagic/locales/de/hue-group.json +16 -9
  196. package/huemagic/locales/de/hue-light.html +6 -6
  197. package/huemagic/locales/de/hue-light.json +17 -9
  198. package/huemagic/locales/de/hue-magic.html +1 -1
  199. package/huemagic/locales/de/hue-magic.json +6 -8
  200. package/huemagic/locales/de/hue-motion.html +4 -4
  201. package/huemagic/locales/de/hue-motion.json +14 -9
  202. package/huemagic/locales/de/hue-rules.html +2 -2
  203. package/huemagic/locales/de/hue-rules.json +10 -9
  204. package/huemagic/locales/de/hue-scene.html +11 -3
  205. package/huemagic/locales/de/hue-scene.json +9 -9
  206. package/huemagic/locales/de/hue-speaker.html +80 -0
  207. package/huemagic/locales/de/hue-speaker.json +38 -0
  208. package/huemagic/locales/de/hue-syncbox-config.html +19 -0
  209. package/huemagic/locales/de/hue-syncbox-config.json +25 -0
  210. package/huemagic/locales/de/hue-syncbox.html +86 -0
  211. package/huemagic/locales/de/hue-syncbox.json +30 -0
  212. package/huemagic/locales/de/hue-temperature.html +7 -5
  213. package/huemagic/locales/de/hue-temperature.json +13 -9
  214. package/huemagic/locales/el/hue-automation.html +59 -0
  215. package/huemagic/locales/el/hue-automation.json +33 -0
  216. package/huemagic/locales/el/hue-bridge-config.html +31 -0
  217. package/huemagic/locales/el/hue-bridge-config.json +40 -0
  218. package/huemagic/locales/el/hue-bridge.html +96 -0
  219. package/huemagic/locales/el/hue-bridge.json +26 -0
  220. package/huemagic/locales/el/hue-brightness.html +70 -0
  221. package/huemagic/locales/el/hue-brightness.json +37 -0
  222. package/huemagic/locales/el/hue-buttons.html +59 -0
  223. package/huemagic/locales/el/hue-buttons.json +42 -0
  224. package/huemagic/locales/el/hue-contact.html +67 -0
  225. package/huemagic/locales/el/hue-contact.json +35 -0
  226. package/huemagic/locales/el/hue-group.html +87 -0
  227. package/huemagic/locales/el/hue-group.json +46 -0
  228. package/huemagic/locales/el/hue-light.html +97 -0
  229. package/huemagic/locales/el/hue-light.json +44 -0
  230. package/huemagic/locales/el/hue-magic.html +68 -0
  231. package/huemagic/locales/el/hue-magic.json +26 -0
  232. package/huemagic/locales/el/hue-motion.html +64 -0
  233. package/huemagic/locales/el/hue-motion.json +36 -0
  234. package/huemagic/locales/el/hue-rules.html +69 -0
  235. package/huemagic/locales/el/hue-rules.json +30 -0
  236. package/huemagic/locales/el/hue-scene.html +43 -0
  237. package/huemagic/locales/el/hue-scene.json +32 -0
  238. package/huemagic/locales/el/hue-speaker.html +80 -0
  239. package/huemagic/locales/el/hue-speaker.json +38 -0
  240. package/huemagic/locales/el/hue-syncbox-config.html +19 -0
  241. package/huemagic/locales/el/hue-syncbox-config.json +25 -0
  242. package/huemagic/locales/el/hue-syncbox.html +86 -0
  243. package/huemagic/locales/el/hue-syncbox.json +30 -0
  244. package/huemagic/locales/el/hue-temperature.html +69 -0
  245. package/huemagic/locales/el/hue-temperature.json +33 -0
  246. package/huemagic/locales/en/hue-automation.html +59 -0
  247. package/huemagic/locales/en/hue-automation.json +33 -0
  248. package/huemagic/locales/en/hue-bridge-config.json +40 -0
  249. package/huemagic/locales/{en-US → en}/hue-bridge.html +5 -2
  250. package/huemagic/locales/{en-US → en}/hue-bridge.json +8 -9
  251. package/huemagic/locales/{en-US → en}/hue-brightness.html +6 -3
  252. package/huemagic/locales/{en-US → en}/hue-brightness.json +11 -9
  253. package/huemagic/locales/{en-US → en}/hue-buttons.html +4 -3
  254. package/huemagic/locales/en/hue-buttons.json +42 -0
  255. package/huemagic/locales/en/hue-contact.html +67 -0
  256. package/huemagic/locales/en/hue-contact.json +35 -0
  257. package/huemagic/locales/{en-US → en}/hue-group.html +16 -5
  258. package/huemagic/locales/{en-US → en}/hue-group.json +15 -10
  259. package/huemagic/locales/{en-US → en}/hue-light.html +3 -3
  260. package/huemagic/locales/en/hue-light.json +44 -0
  261. package/huemagic/locales/{en-US → en}/hue-magic.html +1 -1
  262. package/huemagic/locales/{en-US → en}/hue-motion.html +2 -2
  263. package/huemagic/locales/{en-US → en}/hue-motion.json +12 -9
  264. package/huemagic/locales/{en-US → en}/hue-rules.html +2 -2
  265. package/huemagic/locales/{en-US → en}/hue-rules.json +10 -9
  266. package/huemagic/locales/{en-US → en}/hue-scene.html +11 -3
  267. package/huemagic/locales/{en-US → en}/hue-scene.json +9 -9
  268. package/huemagic/locales/en/hue-speaker.html +80 -0
  269. package/huemagic/locales/en/hue-speaker.json +38 -0
  270. package/huemagic/locales/en/hue-syncbox-config.html +19 -0
  271. package/huemagic/locales/en/hue-syncbox-config.json +25 -0
  272. package/huemagic/locales/en/hue-syncbox.html +86 -0
  273. package/huemagic/locales/en/hue-syncbox.json +30 -0
  274. package/huemagic/locales/{en-US → en}/hue-temperature.html +4 -2
  275. package/huemagic/locales/{en-US → en}/hue-temperature.json +11 -9
  276. package/huemagic/locales/es/hue-automation.html +59 -0
  277. package/huemagic/locales/es/hue-automation.json +33 -0
  278. package/huemagic/locales/es/hue-bridge-config.html +31 -0
  279. package/huemagic/locales/es/hue-bridge-config.json +40 -0
  280. package/huemagic/locales/es/hue-bridge.html +96 -0
  281. package/huemagic/locales/es/hue-bridge.json +26 -0
  282. package/huemagic/locales/es/hue-brightness.html +70 -0
  283. package/huemagic/locales/es/hue-brightness.json +37 -0
  284. package/huemagic/locales/es/hue-buttons.html +59 -0
  285. package/huemagic/locales/es/hue-buttons.json +42 -0
  286. package/huemagic/locales/es/hue-contact.html +67 -0
  287. package/huemagic/locales/es/hue-contact.json +35 -0
  288. package/huemagic/locales/es/hue-group.html +87 -0
  289. package/huemagic/locales/es/hue-group.json +46 -0
  290. package/huemagic/locales/es/hue-light.html +97 -0
  291. package/huemagic/locales/es/hue-light.json +44 -0
  292. package/huemagic/locales/es/hue-magic.html +68 -0
  293. package/huemagic/locales/es/hue-magic.json +26 -0
  294. package/huemagic/locales/es/hue-motion.html +64 -0
  295. package/huemagic/locales/es/hue-motion.json +36 -0
  296. package/huemagic/locales/es/hue-rules.html +69 -0
  297. package/huemagic/locales/es/hue-rules.json +30 -0
  298. package/huemagic/locales/es/hue-scene.html +43 -0
  299. package/huemagic/locales/es/hue-scene.json +32 -0
  300. package/huemagic/locales/es/hue-speaker.html +80 -0
  301. package/huemagic/locales/es/hue-speaker.json +38 -0
  302. package/huemagic/locales/es/hue-syncbox-config.html +19 -0
  303. package/huemagic/locales/es/hue-syncbox-config.json +25 -0
  304. package/huemagic/locales/es/hue-syncbox.html +86 -0
  305. package/huemagic/locales/es/hue-syncbox.json +30 -0
  306. package/huemagic/locales/es/hue-temperature.html +69 -0
  307. package/huemagic/locales/es/hue-temperature.json +33 -0
  308. package/huemagic/locales/fr/hue-automation.html +59 -0
  309. package/huemagic/locales/fr/hue-automation.json +33 -0
  310. package/huemagic/locales/fr/hue-bridge-config.html +31 -0
  311. package/huemagic/locales/fr/hue-bridge-config.json +40 -0
  312. package/huemagic/locales/fr/hue-bridge.html +96 -0
  313. package/huemagic/locales/fr/hue-bridge.json +26 -0
  314. package/huemagic/locales/fr/hue-brightness.html +70 -0
  315. package/huemagic/locales/fr/hue-brightness.json +37 -0
  316. package/huemagic/locales/fr/hue-buttons.html +59 -0
  317. package/huemagic/locales/fr/hue-buttons.json +42 -0
  318. package/huemagic/locales/fr/hue-contact.html +67 -0
  319. package/huemagic/locales/fr/hue-contact.json +35 -0
  320. package/huemagic/locales/fr/hue-group.html +87 -0
  321. package/huemagic/locales/fr/hue-group.json +46 -0
  322. package/huemagic/locales/fr/hue-light.html +97 -0
  323. package/huemagic/locales/fr/hue-light.json +44 -0
  324. package/huemagic/locales/fr/hue-magic.html +68 -0
  325. package/huemagic/locales/fr/hue-magic.json +26 -0
  326. package/huemagic/locales/fr/hue-motion.html +64 -0
  327. package/huemagic/locales/fr/hue-motion.json +36 -0
  328. package/huemagic/locales/fr/hue-rules.html +69 -0
  329. package/huemagic/locales/fr/hue-rules.json +30 -0
  330. package/huemagic/locales/fr/hue-scene.html +43 -0
  331. package/huemagic/locales/fr/hue-scene.json +32 -0
  332. package/huemagic/locales/fr/hue-speaker.html +80 -0
  333. package/huemagic/locales/fr/hue-speaker.json +38 -0
  334. package/huemagic/locales/fr/hue-syncbox-config.html +19 -0
  335. package/huemagic/locales/fr/hue-syncbox-config.json +25 -0
  336. package/huemagic/locales/fr/hue-syncbox.html +86 -0
  337. package/huemagic/locales/fr/hue-syncbox.json +30 -0
  338. package/huemagic/locales/fr/hue-temperature.html +69 -0
  339. package/huemagic/locales/fr/hue-temperature.json +33 -0
  340. package/huemagic/locales/it/hue-automation.html +59 -0
  341. package/huemagic/locales/it/hue-automation.json +33 -0
  342. package/huemagic/locales/it/hue-bridge-config.html +31 -0
  343. package/huemagic/locales/it/hue-bridge-config.json +40 -0
  344. package/huemagic/locales/it/hue-bridge.html +96 -0
  345. package/huemagic/locales/it/hue-bridge.json +26 -0
  346. package/huemagic/locales/it/hue-brightness.html +70 -0
  347. package/huemagic/locales/it/hue-brightness.json +37 -0
  348. package/huemagic/locales/it/hue-buttons.html +59 -0
  349. package/huemagic/locales/it/hue-buttons.json +42 -0
  350. package/huemagic/locales/it/hue-contact.html +67 -0
  351. package/huemagic/locales/it/hue-contact.json +35 -0
  352. package/huemagic/locales/it/hue-group.html +87 -0
  353. package/huemagic/locales/it/hue-group.json +46 -0
  354. package/huemagic/locales/it/hue-light.html +97 -0
  355. package/huemagic/locales/it/hue-light.json +44 -0
  356. package/huemagic/locales/it/hue-magic.html +68 -0
  357. package/huemagic/locales/it/hue-magic.json +26 -0
  358. package/huemagic/locales/it/hue-motion.html +64 -0
  359. package/huemagic/locales/it/hue-motion.json +36 -0
  360. package/huemagic/locales/it/hue-rules.html +69 -0
  361. package/huemagic/locales/it/hue-rules.json +30 -0
  362. package/huemagic/locales/it/hue-scene.html +43 -0
  363. package/huemagic/locales/it/hue-scene.json +32 -0
  364. package/huemagic/locales/it/hue-speaker.html +80 -0
  365. package/huemagic/locales/it/hue-speaker.json +38 -0
  366. package/huemagic/locales/it/hue-syncbox-config.html +19 -0
  367. package/huemagic/locales/it/hue-syncbox-config.json +25 -0
  368. package/huemagic/locales/it/hue-syncbox.html +86 -0
  369. package/huemagic/locales/it/hue-syncbox.json +30 -0
  370. package/huemagic/locales/it/hue-temperature.html +69 -0
  371. package/huemagic/locales/it/hue-temperature.json +33 -0
  372. package/huemagic/locales/nl/hue-automation.html +59 -0
  373. package/huemagic/locales/nl/hue-automation.json +33 -0
  374. package/huemagic/locales/nl/hue-bridge-config.html +31 -0
  375. package/huemagic/locales/nl/hue-bridge-config.json +40 -0
  376. package/huemagic/locales/nl/hue-bridge.html +96 -0
  377. package/huemagic/locales/nl/hue-bridge.json +26 -0
  378. package/huemagic/locales/nl/hue-brightness.html +70 -0
  379. package/huemagic/locales/nl/hue-brightness.json +37 -0
  380. package/huemagic/locales/nl/hue-buttons.html +59 -0
  381. package/huemagic/locales/nl/hue-buttons.json +42 -0
  382. package/huemagic/locales/nl/hue-contact.html +67 -0
  383. package/huemagic/locales/nl/hue-contact.json +35 -0
  384. package/huemagic/locales/nl/hue-group.html +87 -0
  385. package/huemagic/locales/nl/hue-group.json +46 -0
  386. package/huemagic/locales/nl/hue-light.html +97 -0
  387. package/huemagic/locales/nl/hue-light.json +44 -0
  388. package/huemagic/locales/nl/hue-magic.html +68 -0
  389. package/huemagic/locales/nl/hue-magic.json +26 -0
  390. package/huemagic/locales/nl/hue-motion.html +64 -0
  391. package/huemagic/locales/nl/hue-motion.json +36 -0
  392. package/huemagic/locales/nl/hue-rules.html +69 -0
  393. package/huemagic/locales/nl/hue-rules.json +30 -0
  394. package/huemagic/locales/nl/hue-scene.html +43 -0
  395. package/huemagic/locales/nl/hue-scene.json +32 -0
  396. package/huemagic/locales/nl/hue-speaker.html +80 -0
  397. package/huemagic/locales/nl/hue-speaker.json +38 -0
  398. package/huemagic/locales/nl/hue-syncbox-config.html +19 -0
  399. package/huemagic/locales/nl/hue-syncbox-config.json +25 -0
  400. package/huemagic/locales/nl/hue-syncbox.html +86 -0
  401. package/huemagic/locales/nl/hue-syncbox.json +30 -0
  402. package/huemagic/locales/nl/hue-temperature.html +69 -0
  403. package/huemagic/locales/nl/hue-temperature.json +33 -0
  404. package/huemagic/locales/pl/hue-automation.html +59 -0
  405. package/huemagic/locales/pl/hue-automation.json +33 -0
  406. package/huemagic/locales/pl/hue-bridge-config.html +31 -0
  407. package/huemagic/locales/pl/hue-bridge-config.json +40 -0
  408. package/huemagic/locales/pl/hue-bridge.html +96 -0
  409. package/huemagic/locales/pl/hue-bridge.json +26 -0
  410. package/huemagic/locales/pl/hue-brightness.html +70 -0
  411. package/huemagic/locales/pl/hue-brightness.json +37 -0
  412. package/huemagic/locales/pl/hue-buttons.html +59 -0
  413. package/huemagic/locales/pl/hue-buttons.json +42 -0
  414. package/huemagic/locales/pl/hue-contact.html +67 -0
  415. package/huemagic/locales/pl/hue-contact.json +35 -0
  416. package/huemagic/locales/pl/hue-group.html +87 -0
  417. package/huemagic/locales/pl/hue-group.json +46 -0
  418. package/huemagic/locales/pl/hue-light.html +97 -0
  419. package/huemagic/locales/pl/hue-light.json +44 -0
  420. package/huemagic/locales/pl/hue-magic.html +68 -0
  421. package/huemagic/locales/pl/hue-magic.json +26 -0
  422. package/huemagic/locales/pl/hue-motion.html +64 -0
  423. package/huemagic/locales/pl/hue-motion.json +36 -0
  424. package/huemagic/locales/pl/hue-rules.html +69 -0
  425. package/huemagic/locales/pl/hue-rules.json +30 -0
  426. package/huemagic/locales/pl/hue-scene.html +43 -0
  427. package/huemagic/locales/pl/hue-scene.json +32 -0
  428. package/huemagic/locales/pl/hue-speaker.html +80 -0
  429. package/huemagic/locales/pl/hue-speaker.json +38 -0
  430. package/huemagic/locales/pl/hue-syncbox-config.html +19 -0
  431. package/huemagic/locales/pl/hue-syncbox-config.json +25 -0
  432. package/huemagic/locales/pl/hue-syncbox.html +86 -0
  433. package/huemagic/locales/pl/hue-syncbox.json +30 -0
  434. package/huemagic/locales/pl/hue-temperature.html +69 -0
  435. package/huemagic/locales/pl/hue-temperature.json +33 -0
  436. package/huemagic/locales/pt/hue-automation.html +59 -0
  437. package/huemagic/locales/pt/hue-automation.json +33 -0
  438. package/huemagic/locales/pt/hue-bridge-config.html +31 -0
  439. package/huemagic/locales/pt/hue-bridge-config.json +40 -0
  440. package/huemagic/locales/pt/hue-bridge.html +96 -0
  441. package/huemagic/locales/pt/hue-bridge.json +26 -0
  442. package/huemagic/locales/pt/hue-brightness.html +70 -0
  443. package/huemagic/locales/pt/hue-brightness.json +37 -0
  444. package/huemagic/locales/pt/hue-buttons.html +59 -0
  445. package/huemagic/locales/pt/hue-buttons.json +42 -0
  446. package/huemagic/locales/pt/hue-contact.html +67 -0
  447. package/huemagic/locales/pt/hue-contact.json +35 -0
  448. package/huemagic/locales/pt/hue-group.html +87 -0
  449. package/huemagic/locales/pt/hue-group.json +46 -0
  450. package/huemagic/locales/pt/hue-light.html +97 -0
  451. package/huemagic/locales/pt/hue-light.json +44 -0
  452. package/huemagic/locales/pt/hue-magic.html +68 -0
  453. package/huemagic/locales/pt/hue-magic.json +26 -0
  454. package/huemagic/locales/pt/hue-motion.html +64 -0
  455. package/huemagic/locales/pt/hue-motion.json +36 -0
  456. package/huemagic/locales/pt/hue-rules.html +69 -0
  457. package/huemagic/locales/pt/hue-rules.json +30 -0
  458. package/huemagic/locales/pt/hue-scene.html +43 -0
  459. package/huemagic/locales/pt/hue-scene.json +32 -0
  460. package/huemagic/locales/pt/hue-speaker.html +80 -0
  461. package/huemagic/locales/pt/hue-speaker.json +38 -0
  462. package/huemagic/locales/pt/hue-syncbox-config.html +19 -0
  463. package/huemagic/locales/pt/hue-syncbox-config.json +25 -0
  464. package/huemagic/locales/pt/hue-syncbox.html +86 -0
  465. package/huemagic/locales/pt/hue-syncbox.json +30 -0
  466. package/huemagic/locales/pt/hue-temperature.html +69 -0
  467. package/huemagic/locales/pt/hue-temperature.json +33 -0
  468. package/huemagic/locales/tr/hue-automation.html +59 -0
  469. package/huemagic/locales/tr/hue-automation.json +33 -0
  470. package/huemagic/locales/tr/hue-bridge-config.html +31 -0
  471. package/huemagic/locales/tr/hue-bridge-config.json +40 -0
  472. package/huemagic/locales/tr/hue-bridge.html +96 -0
  473. package/huemagic/locales/tr/hue-bridge.json +26 -0
  474. package/huemagic/locales/tr/hue-brightness.html +70 -0
  475. package/huemagic/locales/tr/hue-brightness.json +37 -0
  476. package/huemagic/locales/tr/hue-buttons.html +59 -0
  477. package/huemagic/locales/tr/hue-buttons.json +42 -0
  478. package/huemagic/locales/tr/hue-contact.html +67 -0
  479. package/huemagic/locales/tr/hue-contact.json +35 -0
  480. package/huemagic/locales/tr/hue-group.html +87 -0
  481. package/huemagic/locales/tr/hue-group.json +46 -0
  482. package/huemagic/locales/tr/hue-light.html +97 -0
  483. package/huemagic/locales/tr/hue-light.json +44 -0
  484. package/huemagic/locales/tr/hue-magic.html +68 -0
  485. package/huemagic/locales/tr/hue-magic.json +26 -0
  486. package/huemagic/locales/tr/hue-motion.html +64 -0
  487. package/huemagic/locales/tr/hue-motion.json +36 -0
  488. package/huemagic/locales/tr/hue-rules.html +69 -0
  489. package/huemagic/locales/tr/hue-rules.json +30 -0
  490. package/huemagic/locales/tr/hue-scene.html +43 -0
  491. package/huemagic/locales/tr/hue-scene.json +32 -0
  492. package/huemagic/locales/tr/hue-speaker.html +80 -0
  493. package/huemagic/locales/tr/hue-speaker.json +38 -0
  494. package/huemagic/locales/tr/hue-syncbox-config.html +19 -0
  495. package/huemagic/locales/tr/hue-syncbox-config.json +25 -0
  496. package/huemagic/locales/tr/hue-syncbox.html +86 -0
  497. package/huemagic/locales/tr/hue-syncbox.json +30 -0
  498. package/huemagic/locales/tr/hue-temperature.html +69 -0
  499. package/huemagic/locales/tr/hue-temperature.json +33 -0
  500. package/huemagic/utils/api.js +158 -54
  501. package/huemagic/utils/color.js +20 -2
  502. package/huemagic/utils/merge.js +3 -2
  503. package/huemagic/utils/messages.js +506 -120
  504. package/huemagic/utils/sse.js +51 -0
  505. package/huemagic/utils/syncbox.js +84 -0
  506. package/package.json +19 -11
  507. package/.github/FUNDING.yml +0 -2
  508. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
  509. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  510. package/.github/workflows/npm.yml +0 -18
  511. package/huemagic/locales/en-US/hue-bridge-config.json +0 -29
  512. package/huemagic/locales/en-US/hue-buttons.json +0 -34
  513. package/huemagic/locales/en-US/hue-light.json +0 -38
  514. /package/huemagic/locales/{en-US → en}/hue-bridge-config.html +0 -0
  515. /package/huemagic/locales/{en-US → en}/hue-magic.json +0 -0
@@ -47,7 +47,7 @@ module.exports = function(RED)
47
47
 
48
48
  //
49
49
  // SUBSCRIBE TO UPDATES FROM THE BRIDGE
50
- bridge.subscribe("group", config.groupid, function(info)
50
+ this.unsubscribe = bridge.subscribe("group", config.groupid, function(info)
51
51
  {
52
52
  let currentState = bridge.get("group", info.id, { colornames: config.colornamer ? true : false });
53
53
 
@@ -63,18 +63,22 @@ module.exports = function(RED)
63
63
  scope.applyCommands({}, null, null);
64
64
  }
65
65
 
66
- if(currentState.payload.on === true)
66
+ if(currentState.payload.on !== true)
67
67
  {
68
- scope.status({fill: "yellow", shape: "dot", text: "hue-group.node.turned-on"});
68
+ scope.status({fill: "grey", shape: "dot", text: "hue-group.node.all-off"});
69
+ }
70
+ else if(currentState.payload.brightness !== false)
71
+ {
72
+ scope.status({fill: "yellow", shape: "dot", text: RED._("hue-group.node.turned-on") + RED._("hue-group.node.brightness", { percent: Math.round(currentState.payload.brightness) })});
69
73
  }
70
74
  else
71
75
  {
72
- scope.status({fill: "grey", shape: "dot", text: "hue-group.node.all-off"});
76
+ scope.status({fill: "yellow", shape: "dot", text: "hue-group.node.turned-on"});
73
77
  }
74
78
  }
75
79
 
76
80
  // SEND MESSAGE
77
- if(!config.skipevents && (config.initevents || info.suppressMessage == false))
81
+ if(!config.skipevents && (config.initevents || info.suppressMessage == false) && (!config.onlycommands || scope.lastCommand !== null))
78
82
  {
79
83
  // SET LAST COMMAND
80
84
  if(scope.lastCommand !== null)
@@ -96,7 +100,7 @@ module.exports = function(RED)
96
100
  this.on('input', function(msg, send, done) { scope.applyCommands(msg, send, done); });
97
101
 
98
102
  //
99
- // APPLY COMMANDS (API v1 because CLIP/v2 does not yet support all features)
103
+ // APPLY COMMANDS (CLIP/v2, only the colorloop effect still needs the legacy API)
100
104
  this.applyCommands = async function(msg, send = null, done = null)
101
105
  {
102
106
  // SET SEND
@@ -108,19 +112,19 @@ module.exports = function(RED)
108
112
  // CREATE PATCH
109
113
  let patchObject = {};
110
114
 
111
- // DEFINE SENSOR ID & CURRENT STATE
115
+ // DEFINE GROUP ID
112
116
  const tempGroupID = (!config.groupid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.groupid;
113
- let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
114
- if(!currentState)
117
+ if(!tempGroupID)
115
118
  {
116
- scope.error("The group in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid.");
119
+ scope.error(RED._("hue-group.node.error-no-id"), msg);
117
120
  return false;
118
121
  }
119
122
 
120
- // CHECK IF LIGHT ID IS SET
121
- if(!tempGroupID)
123
+ // GET CURRENT STATE
124
+ let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
125
+ if(!currentState)
122
126
  {
123
- scope.error(RED._("hue-group.node.error-no-id"));
127
+ scope.error(RED._("hue-group.node.error-not-available"), msg);
124
128
  return false;
125
129
  }
126
130
 
@@ -150,9 +154,15 @@ module.exports = function(RED)
150
154
  return true;
151
155
  }
152
156
 
153
- // COLORLOOP EFFECT
157
+ // COLORLOOP EFFECT (CLIP/v2 HAS NO EQUIVALENT, SO THIS STAYS ON THE LEGACY API)
154
158
  if(typeof msg.payload != 'undefined' && typeof msg.payload.colorloop != 'undefined' && msg.payload.colorloop > 0)
155
159
  {
160
+ if(!currentState.info.idV1)
161
+ {
162
+ scope.error(RED._("hue-group.node.error-no-colorloop"), msg);
163
+ return false;
164
+ }
165
+
156
166
  patchObject = {
157
167
  "on": true,
158
168
  "effect": "colorloop",
@@ -161,11 +171,11 @@ module.exports = function(RED)
161
171
 
162
172
  // PATCH!
163
173
  async.retry({
164
- times: 3,
174
+ times: 5,
165
175
  errorFilter: function(err) {
166
- return (err.status == 503);
176
+ return (err.status == 503 || err.status == 429);
167
177
  },
168
- interval: function(retryCount) { return retryCount*2000; }
178
+ interval: function(retryCount) { return 750*retryCount; }
169
179
  },
170
180
  function(callback, results)
171
181
  {
@@ -202,31 +212,14 @@ module.exports = function(RED)
202
212
  // ALERT EFFECT
203
213
  if(typeof msg.payload != 'undefined' && typeof msg.payload.alert != 'undefined' && msg.payload.alert > 0)
204
214
  {
205
- // SAVE PREVIOUS STATE
206
- scope.context().set('groupPreviousState', currentState);
215
+ // THE BRIDGE BLINKS AND RESTORES THE PREVIOUS STATE ON ITS OWN
216
+ let duration = Math.round(parseFloat(msg.payload.alert)) * 1000;
217
+ duration = (duration > 65534000) ? 65534000 : duration;
207
218
 
208
- // TURN ON LIGHT
209
- if(currentState.payload.on === false)
210
- {
211
- patchObject["on"] = true;
212
- }
213
-
214
- // SET BRIGHTNESS
215
- if(!msg.payload.brightness && currentState.payload.brightness != 100)
216
- {
217
- patchObject["bri"] = 254;
218
- }
219
- else if(msg.payload.brightness)
220
- {
221
- patchObject["bri"] = Math.round((254/100)*msg.payload.brightness);
222
- }
223
-
224
- // SET TRANSITION
225
- patchObject["transitiontime"] = 0;
226
-
227
- // CAN CHANGE COLOR?
228
- let XYAlertColor = {};
219
+ let signaling = { signal: "on_off", duration: duration };
220
+ let XYAlertColor = false;
229
221
 
222
+ // BLINK IN A SPECIFIC COLOR?
230
223
  if(typeof msg.payload.rgb != 'undefined')
231
224
  {
232
225
  XYAlertColor = colorUtils.rgbToXy(msg.payload.rgb[0], msg.payload.rgb[1], msg.payload.rgb[2] );
@@ -238,79 +231,38 @@ module.exports = function(RED)
238
231
  }
239
232
  else if(typeof msg.payload.color != 'undefined')
240
233
  {
241
- if(new RegExp("random|any|whatever").test(msg.payload.color))
234
+ const colorHex = new RegExp("random|any|whatever").test(msg.payload.color) ? colorUtils.randomHexColor() : colorUtils.colornames(msg.payload.color);
235
+ if(colorHex)
242
236
  {
243
- const randomColor = colorUtils.randomHexColor();
244
- let rgbFromHex = colorUtils.hexRgb(rgbFromHex);
237
+ let rgbFromHex = colorUtils.hexRgb(colorHex);
245
238
  XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
246
239
  }
247
- else
248
- {
249
- var colorHex = colorUtils.colornames(msg.payload.color);
250
- if(colorHex)
251
- {
252
- let rgbFromHex = colorUtils.hexRgb(colorHex);
253
- XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
254
- }
255
- }
256
240
  }
257
- else
241
+
242
+ if(XYAlertColor)
258
243
  {
259
- XYAlertColor = colorUtils.rgbToXy(255, 0, 0 );
244
+ signaling = { signal: "on_off_color", duration: duration, colors: [{ xy: XYAlertColor }] };
260
245
  }
261
246
 
262
- patchObject["xy"] = [XYAlertColor.x, XYAlertColor.y];
263
-
264
- // SET ALERT EFFECT
265
- patchObject["alert"] = "lselect";
266
-
267
247
  // PATCH!
268
248
  async.retry({
269
- times: 3,
249
+ times: 5,
270
250
  errorFilter: function(err) {
271
- return (err.status == 503);
251
+ return (err.status == 503 || err.status == 429);
272
252
  },
273
- interval: function(retryCount) { return retryCount*2000; }
253
+ interval: function(retryCount) { return 750*retryCount; }
274
254
  },
275
255
  function(callback, results)
276
256
  {
277
- // 1. TURN ON THE LIGHT BULB
278
- bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
279
- .then(function(status)
257
+ bridge.patch("grouped_light", tempGroupID, { signaling: signaling })
258
+ .catch(function(errors)
280
259
  {
281
- setTimeout(function()
282
- {
283
- const tempPreviousState = scope.context().get('groupPreviousState');
284
- var tempPreviousStatePatch = {};
285
-
286
- tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
287
- if(tempPreviousState.payload.xyColor)
288
- {
289
- tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
290
- }
291
- else if(tempPreviousState.payload.colorTemp)
292
- {
293
- tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
294
- }
295
-
296
- bridge.patch("group", currentState.info.idV1 + "/action", tempPreviousStatePatch, 1)
297
- .then(function(status)
298
- {
299
- return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
300
- })
301
- .then(function(status) {
302
- if(tempPreviousState.payload.on === true)
303
- {
304
- bridge.patch("group", currentState.info.idV1, { on: true }, 1);
305
- }
306
- });
307
- }, parseInt(msg.payload.alert) * 1000);
308
-
309
- callback(null, true);
260
+ // OLDER BRIDGES ONLY KNOW THE (15 SECONDS LONG) BREATHE EFFECT
261
+ if(errors.status !== 400) { throw errors; }
262
+ return bridge.patch("grouped_light", tempGroupID, { alert: { action: "breathe" } });
310
263
  })
311
- .catch(function(errors) {
312
- callback(errors, null);
313
- });
264
+ .then(function() { callback(null, true); })
265
+ .catch(function(errors) { callback(errors, null); });
314
266
  },
315
267
  function(errors, success)
316
268
  {
@@ -335,52 +287,48 @@ module.exports = function(RED)
335
287
  else if(typeof msg.animation != 'undefined' && msg.animation.status == false && msg.animation.restore == true)
336
288
  {
337
289
  const tempPreviousState = scope.context().get('groupPreviousState');
338
- var tempPreviousStatePatch = {};
290
+ if(!tempPreviousState)
291
+ {
292
+ if(done) { done(); }
293
+ return false;
294
+ }
295
+
296
+ // RESTORE IN ONE SINGLE PATCH ON THE GROUP, OTHERWISE THE LIGHTS FLICKER
297
+ var tempPreviousStatePatch = { on: { on: tempPreviousState.payload.on } };
298
+
299
+ if(typeof tempPreviousState.payload.brightness != 'undefined' && tempPreviousState.payload.brightness !== false)
300
+ {
301
+ tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
302
+ }
339
303
 
340
- tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
341
304
  if(tempPreviousState.payload.xyColor)
342
305
  {
343
- tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
306
+ tempPreviousStatePatch.color = { xy: tempPreviousState.payload.xyColor };
344
307
  }
345
308
  else if(tempPreviousState.payload.colorTemp)
346
309
  {
347
- tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
310
+ tempPreviousStatePatch.color_temperature = { mirek: tempPreviousState.payload.colorTemp };
348
311
  }
349
312
 
350
313
  // PATCH!
351
314
  async.retry({
352
- times: 3,
315
+ times: 5,
353
316
  errorFilter: function(err) {
354
- return (err.status == 503);
317
+ return (err.status == 503 || err.status == 429);
355
318
  },
356
- interval: function(retryCount) { return retryCount*2000; }
319
+ interval: function(retryCount) { return 750*retryCount; }
357
320
  },
358
321
  function(callback, results)
359
322
  {
360
- bridge.patch("light", currentState.info.lightIds[l], tempPreviousStatePatch).
361
- then(function(status)
362
- {
363
- if(tempPreviousState.payload.on === false)
364
- {
365
- bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
366
- .then(function() { callback(null, true); });
367
- }
368
- else
369
- {
370
- bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
371
- .then(function(status) {
372
- callback(null, true);
373
- return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } });
374
- });
375
- }
376
- })
323
+ bridge.patch("grouped_light", tempGroupID, tempPreviousStatePatch)
324
+ .then(function() { callback(null, true); })
377
325
  .catch(function(errors) { callback(errors, null); });
378
326
  },
379
327
  function(errors, success)
380
328
  {
381
329
  if(errors)
382
330
  {
383
- scope.error(errors);
331
+ scope.error(errors, msg);
384
332
  }
385
333
  else if(done)
386
334
  {
@@ -391,28 +339,22 @@ module.exports = function(RED)
391
339
  // EXTENDED COMMANDS
392
340
  else
393
341
  {
394
- // SET LIGHT STATE SIMPLE MODE
342
+ // SET LIGHT STATE SIMPLE MODE (ALWAYS SENT, THE CACHED STATE MAY BE OUTDATED)
395
343
  if(msg.payload === true||msg.payload === false)
396
344
  {
397
- if(msg.payload !== currentState.payload.on)
398
- {
399
- patchObject["on"] = msg.payload;
400
- }
345
+ patchObject["on"] = { on: msg.payload };
401
346
  }
402
347
 
403
348
  // SET LIGHT STATE
404
349
  if(typeof msg.payload != 'undefined' && typeof msg.payload.on != 'undefined' && (msg.payload.on === true || msg.payload.on === false))
405
350
  {
406
- if(msg.payload.on !== currentState.payload.on)
407
- {
408
- patchObject["on"] = msg.payload.on;
409
- }
351
+ patchObject["on"] = { on: msg.payload.on };
410
352
  }
411
353
 
412
354
  // TOGGLE ON / OFF
413
355
  if(typeof msg.payload != 'undefined' && typeof msg.payload.toggle != 'undefined')
414
356
  {
415
- patchObject["on"] = !currentState.payload.on;
357
+ patchObject["on"] = { on: !currentState.payload.on };
416
358
  }
417
359
 
418
360
  // SET BRIGHTNESS
@@ -427,22 +369,22 @@ module.exports = function(RED)
427
369
  autoBrightness = (autoBrightness < 20) ? 20 : autoBrightness;
428
370
 
429
371
  // SET CALCULATED BRIGHTNESS
430
- patchObject["bri"] = Math.round((254/100)*autoBrightness);
372
+ patchObject["dimming"] = { brightness: autoBrightness };
431
373
  }
432
374
  else
433
375
  {
434
376
  if(msg.payload.brightness > 100 || msg.payload.brightness < 0)
435
377
  {
436
- scope.error("Invalid brightness setting. Only 0 - 100 percent allowed");
378
+ scope.error(RED._("hue-group.node.error-invalid-brightness"), msg);
437
379
  return false;
438
380
  }
439
381
  else if(msg.payload.brightness == 0)
440
382
  {
441
- patchObject["on"] = false;
383
+ patchObject["on"] = { on: false };
442
384
  }
443
385
  else
444
386
  {
445
- patchObject["bri"] = Math.round((254/100)*msg.payload.brightness);
387
+ patchObject["dimming"] = { brightness: msg.payload.brightness };
446
388
  }
447
389
  }
448
390
  }
@@ -450,63 +392,72 @@ module.exports = function(RED)
450
392
  {
451
393
  if(msg.payload.brightnessLevel > 254 || msg.payload.brightnessLevel < 0)
452
394
  {
453
- scope.error("Invalid brightness setting. Only 0 - 254 allowed");
395
+ scope.error(RED._("hue-group.node.error-invalid-brightness-level"), msg);
454
396
  return false;
455
397
  }
456
- else if(msg.payload.brightness == 0)
398
+ else if(msg.payload.brightnessLevel == 0)
457
399
  {
458
- patchObject["on"] = false;
400
+ patchObject["on"] = { on: false };
459
401
  }
460
402
  else
461
403
  {
462
- patchObject["bri"] = msg.payload.brightnessLevel;
404
+ patchObject["dimming"] = { brightness: Math.round((100/254)*msg.payload.brightnessLevel) };
463
405
  }
464
406
  }
465
-
466
- // SET HUMAN READABLE COLOR OR RANDOM
467
- if(typeof msg.payload != 'undefined' && typeof msg.payload.color != 'undefined')
407
+ else if(typeof msg.payload != 'undefined' && typeof msg.payload.incrementBrightness != 'undefined')
468
408
  {
469
- let XYAlertColor = {};
409
+ let incrementBy = (isNaN(msg.payload.incrementBrightness)) ? 10 : parseFloat(msg.payload.incrementBrightness);
470
410
 
471
- if(new RegExp("random|any|whatever").test(msg.payload.color))
411
+ if ((incrementBy > 100) || (incrementBy < -100))
472
412
  {
473
- const randomColor = colorUtils.randomHexColor();
474
- let rgbFromHex = colorUtils.hexRgb(randomColor);
475
- XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
413
+ scope.error(RED._("hue-group.node.error-invalid-increment"), msg);
414
+ return false;
476
415
  }
477
- else
416
+
417
+ patchObject["dimming_delta"] = { action: (incrementBy < 0) ? "down" : "up", brightness_delta: Math.abs(incrementBy) };
418
+ }
419
+ else if(typeof msg.payload != 'undefined' && typeof msg.payload.decrementBrightness != 'undefined')
420
+ {
421
+ let decrementBy = (isNaN(msg.payload.decrementBrightness)) ? 10 : parseFloat(msg.payload.decrementBrightness);
422
+
423
+ if ((decrementBy > 100) || (decrementBy < -100))
478
424
  {
479
- var colorHex = colorUtils.colornames(msg.payload.color);
480
- if(colorHex)
481
- {
482
- let rgbFromHex = colorUtils.hexRgb(colorHex);
483
- XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
484
- }
425
+ scope.error(RED._("hue-group.node.error-invalid-decrement"), msg);
426
+ return false;
485
427
  }
486
428
 
487
- patchObject["xy"] = [XYAlertColor.x, XYAlertColor.y];
429
+ patchObject["dimming_delta"] = { action: (decrementBy < 0) ? "up" : "down", brightness_delta: Math.abs(decrementBy) };
430
+ }
431
+
432
+ // SET HUMAN READABLE COLOR OR RANDOM
433
+ if(typeof msg.payload != 'undefined' && typeof msg.payload.color != 'undefined')
434
+ {
435
+ const colorHex = new RegExp("random|any|whatever").test(msg.payload.color) ? colorUtils.randomHexColor() : colorUtils.colornames(msg.payload.color);
436
+
437
+ if(colorHex)
438
+ {
439
+ let rgbFromHex = colorUtils.hexRgb(colorHex);
440
+ patchObject["color"] = { xy: colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2]) };
441
+ }
488
442
  }
489
443
 
490
444
  // SET HEX COLOR
491
445
  if(typeof msg.payload != 'undefined' && typeof msg.payload.hex != 'undefined')
492
446
  {
493
447
  let rgbFromHex = colorUtils.hexRgb((msg.payload.hex).toString());
494
- let xyColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2])
495
-
496
- patchObject["xy"] = [xyColor.x, xyColor.y];
448
+ patchObject["color"] = { xy: colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2]) };
497
449
  }
498
450
 
499
451
  // SET RGB COLOR
500
452
  if(typeof msg.payload != 'undefined' && typeof msg.payload.rgb != 'undefined' && msg.payload.rgb.length === 3)
501
453
  {
502
- let xyColor = colorUtils.rgbToXy(msg.payload.rgb[0], msg.payload.rgb[1], msg.payload.rgb[2] )
503
- patchObject["xy"] = [xyColor.x, xyColor.y];
454
+ patchObject["color"] = { xy: colorUtils.rgbToXy(msg.payload.rgb[0], msg.payload.rgb[1], msg.payload.rgb[2]) };
504
455
  }
505
456
 
506
457
  // SET XY COLOR
507
458
  if(typeof msg.payload != 'undefined' && typeof msg.payload.xyColor != 'undefined')
508
459
  {
509
- patchObject["xy"] = [msg.payload.xyColor.x, msg.payload.xyColor.y];
460
+ patchObject["color"] = { xy: { x: msg.payload.xyColor.x, y: msg.payload.xyColor.y } };
510
461
  }
511
462
 
512
463
  // SET COLOR TEMPERATURE
@@ -518,34 +469,34 @@ module.exports = function(RED)
518
469
  let colorTemp = parseInt(msg.payload.colorTemp);
519
470
  if(colorTemp >= 153 && colorTemp <= 500)
520
471
  {
521
- patchObject["ct"] = colorTemp;
472
+ patchObject["color_temperature"] = { mirek: colorTemp };
522
473
  }
523
474
  else
524
475
  {
525
- scope.error("Invalid color temprature. Only 153 - 500 allowed");
476
+ scope.error(RED._("hue-group.node.error-invalid-temp"), msg);
526
477
  return false;
527
478
  }
528
479
  }
529
480
  else if(msg.payload.colorTemp == "cold")
530
481
  {
531
- patchObject["ct"] = 153;
482
+ patchObject["color_temperature"] = { mirek: 153 };
532
483
  }
533
484
  else if(msg.payload.colorTemp == "normal")
534
485
  {
535
- patchObject["ct"] = 240;
486
+ patchObject["color_temperature"] = { mirek: 240 };
536
487
  }
537
488
  else if(msg.payload.colorTemp == "warm")
538
489
  {
539
- patchObject["ct"] = 400;
490
+ patchObject["color_temperature"] = { mirek: 400 };
540
491
  }
541
492
  else if(msg.payload.colorTemp == "hot")
542
493
  {
543
- patchObject["ct"] = 500;
494
+ patchObject["color_temperature"] = { mirek: 500 };
544
495
  }
545
496
  else
546
497
  {
547
498
  // SET TEMPERATURE
548
- patchObject["ct"] = colorUtils.colorTemperature();
499
+ patchObject["color_temperature"] = { mirek: colorUtils.colorTemperature() };
549
500
  }
550
501
  }
551
502
 
@@ -556,7 +507,7 @@ module.exports = function(RED)
556
507
  targetTransitionTime = (targetTransitionTime > 6000000) ? 6000000 : targetTransitionTime;
557
508
  targetTransitionTime = (targetTransitionTime < 0) ? 0 : targetTransitionTime;
558
509
 
559
- patchObject["transitiontime"] = targetTransitionTime/100;
510
+ patchObject["dynamics"] = { duration: targetTransitionTime };
560
511
  }
561
512
 
562
513
  // SET DOMINANT COLORS FROM IMAGE
@@ -567,37 +518,40 @@ module.exports = function(RED)
567
518
  {
568
519
  var colorsHEX = colors.map(color => color.hex());
569
520
  let rgbFromHex = colorUtils.hexRgb(colorsHEX[0]);
570
- let xyColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2]);
571
521
 
572
- patchObject["xy"] = [xyColor.x, xyColor.y];
522
+ patchObject["color"] = { xy: colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2]) };
573
523
  }
574
524
  }
575
525
 
526
+ // THE BRIDGE ONLY ACCEPTS ONE OF BOTH
527
+ if(patchObject["color"] && patchObject["color_temperature"]) { delete patchObject["color_temperature"]; }
528
+
576
529
  //
577
530
  // SHOULD PATCH?
578
531
  if(Object.values(patchObject).length > 0)
579
532
  {
580
- // IS FOR LATER?
533
+ // IS FOR LATER? (ONLY IF THE COMMAND ITSELF DOES NOT SWITCH THE GROUP)
581
534
  if(currentState.payload.on === false)
582
535
  {
583
- if(!patchObject["on"])
536
+ if(typeof patchObject["on"] == 'undefined')
584
537
  {
585
538
  scope.futurePatchState = merge.deep(scope.futurePatchState, patchObject);
539
+ if(done) { done(); }
586
540
  return false;
587
541
  }
588
542
  }
589
543
 
590
544
  // PATCH!
591
545
  async.retry({
592
- times: 3,
546
+ times: 5,
593
547
  errorFilter: function(err) {
594
- return (err.status == 503);
548
+ return (err.status == 503 || err.status == 429);
595
549
  },
596
- interval: function(retryCount) { return retryCount*2000; }
550
+ interval: function(retryCount) { return 750*retryCount; }
597
551
  },
598
552
  function(callback, results)
599
553
  {
600
- bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
554
+ bridge.patch("grouped_light", tempGroupID, patchObject)
601
555
  .then(function() { callback(null, true); })
602
556
  .catch(function(errors) { callback(errors, null); });
603
557
  },
@@ -630,7 +584,15 @@ module.exports = function(RED)
630
584
  }
631
585
  }
632
586
  }
587
+
588
+ //
589
+ // CLOSE NODE / DETACH FROM THE BRIDGE
590
+ this.on('close', function()
591
+ {
592
+ if(scope.unsubscribe) { scope.unsubscribe(); }
593
+ });
594
+
633
595
  }
634
596
 
635
597
  RED.nodes.registerType("hue-group", HueGroup);
636
- }
598
+ }
@@ -4,7 +4,7 @@
4
4
  <input type="text" id="node-input-name" data-i18n="[placeholder]hue-light.config.input-name" style="width: calc(100% - 105px)">
5
5
  </div>
6
6
  <div class="form-row">
7
- <label for="node-input-bridge"><i class="fa fa-server"></i> Bridge</label>
7
+ <label for="node-input-bridge"><i class="fa fa-server"></i> <span data-i18n="hue-light.config.bridge"></span></label>
8
8
  <input type="text" id="node-input-bridge" style="width: calc(100% - 105px)">
9
9
  </div>
10
10
  <div class="form-row">
@@ -19,21 +19,27 @@
19
19
  </div>
20
20
  </div>
21
21
  <div class="form-row" style="margin-top: 30px">
22
- <div style="display: inline-flex; width: calc(100% - 105px)">
23
- <input type="checkbox" id="node-input-colornamer" style="flex: 15px;">
24
- <span data-i18n="hue-light.config.colornamer-info" style="width: 100%; margin-left: 10px;"></span>
22
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
23
+ <input type="checkbox" id="node-input-colornamer" style="flex: 0 0 auto; width: auto; margin: 0;">
24
+ <span data-i18n="hue-light.config.colornamer-info" style="flex: 1; margin-left: 8px;"></span>
25
25
  </div>
26
26
  </div>
27
27
  <div class="form-row">
28
- <div style="display: inline-flex; width: calc(100% - 105px)">
29
- <input type="checkbox" id="node-input-skipevents" style="flex: 15px;">
30
- <span data-i18n="hue-light.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
28
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
29
+ <input type="checkbox" id="node-input-skipevents" style="flex: 0 0 auto; width: auto; margin: 0;">
30
+ <span data-i18n="hue-light.config.skipevents-node" style="flex: 1; margin-left: 8px;"></span>
31
31
  </div>
32
32
  </div>
33
33
  <div class="form-row">
34
- <div style="display: inline-flex; width: calc(100% - 105px)">
35
- <input type="checkbox" id="node-input-initevents" style="flex: 15px;">
36
- <span data-i18n="hue-light.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
34
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
35
+ <input type="checkbox" id="node-input-initevents" style="flex: 0 0 auto; width: auto; margin: 0;">
36
+ <span data-i18n="hue-light.config.sendinitevents-node" style="flex: 1; margin-left: 8px;"></span>
37
+ </div>
38
+ </div>
39
+ <div class="form-row">
40
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
41
+ <input type="checkbox" id="node-input-onlycommands" style="flex: 0 0 auto; width: auto; margin: 0;">
42
+ <span data-i18n="hue-light.config.onlycommands-node" style="flex: 1; margin-left: 8px;"></span>
37
43
  </div>
38
44
  </div>
39
45
  </script>
@@ -48,10 +54,11 @@
48
54
  lightid: { value:"", required: false },
49
55
  colornamer: { value: true },
50
56
  skipevents: { value: false },
51
- initevents: { value: false }
57
+ initevents: { value: false },
58
+ onlycommands: { value: false }
52
59
  },
53
60
  align: 'left',
54
- icon: "hue-light.png",
61
+ icon: "hue-light.svg",
55
62
  inputs: 1,
56
63
  outputs: 1,
57
64
  label: function() {