node-red-contrib-huemagic 4.2.2 → 5.0.1

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 +94 -5
  2. package/README.md +525 -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 +227 -11
  153. package/huemagic/hue-buttons.js +183 -28
  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 +7 -4
  191. package/huemagic/locales/de/hue-buttons.json +42 -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 +61 -0
  223. package/huemagic/locales/el/hue-buttons.json +62 -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 +6 -3
  254. package/huemagic/locales/en/hue-buttons.json +62 -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 +61 -0
  285. package/huemagic/locales/es/hue-buttons.json +62 -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 +61 -0
  317. package/huemagic/locales/fr/hue-buttons.json +62 -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 +61 -0
  349. package/huemagic/locales/it/hue-buttons.json +62 -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 +61 -0
  381. package/huemagic/locales/nl/hue-buttons.json +62 -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 +61 -0
  413. package/huemagic/locales/pl/hue-buttons.json +62 -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 +61 -0
  445. package/huemagic/locales/pt/hue-buttons.json +62 -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 +61 -0
  477. package/huemagic/locales/tr/hue-buttons.json +62 -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
@@ -4,19 +4,19 @@
4
4
  <input type="text" id="node-input-name" data-i18n="[placeholder]hue-bridge.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-bridge.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" style="margin-top: 30px">
11
- <div style="display: inline-flex; width: calc(100% - 105px)">
12
- <input type="checkbox" id="node-input-skipglobalevents" style="flex: 15px;">
13
- <span data-i18n="hue-bridge.config.skipglobalevents-info" style="width: 100%; margin-left: 10px;"></span>
11
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
12
+ <input type="checkbox" id="node-input-skipglobalevents" style="flex: 0 0 auto; width: auto; margin: 0;">
13
+ <span data-i18n="hue-bridge.config.skipglobalevents-info" style="flex: 1; margin-left: 8px;"></span>
14
14
  </div>
15
15
  </div>
16
16
  <div class="form-row">
17
- <div style="display: inline-flex; width: calc(100% - 105px)">
18
- <input type="checkbox" id="node-input-initevents" style="flex: 15px;">
19
- <span data-i18n="hue-bridge.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
17
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
18
+ <input type="checkbox" id="node-input-initevents" style="flex: 0 0 auto; width: auto; margin: 0;">
19
+ <span data-i18n="hue-bridge.config.sendinitevents-node" style="flex: 1; margin-left: 8px;"></span>
20
20
  </div>
21
21
  </div>
22
22
  </script>
@@ -33,7 +33,7 @@
33
33
  initevents: { value: false }
34
34
  },
35
35
  align: 'left',
36
- icon: "hue-bridge.png",
36
+ icon: "hue-bridge.svg",
37
37
  inputs: 1,
38
38
  outputs: 1,
39
39
  label: function() {
@@ -52,6 +52,8 @@ module.exports = function(RED)
52
52
  if(forceReload === true)
53
53
  {
54
54
  // REFRESH INFORMATION
55
+ scope.lastBridgeInformation = null;
56
+
55
57
  bridge.getBridgeInformation(true)
56
58
  .then(function(updated)
57
59
  {
@@ -60,7 +62,8 @@ module.exports = function(RED)
60
62
  .then(function(bridgeInformation)
61
63
  {
62
64
  resolve(bridgeInformation);
63
- });
65
+ })
66
+ .catch(function(error) { reject(error); });
64
67
  }
65
68
  else if(scope.lastBridgeInformation !== null)
66
69
  {
@@ -70,8 +73,15 @@ module.exports = function(RED)
70
73
  else
71
74
  {
72
75
  let bridgeInformation = bridge.get("bridge", "bridge", { autoupdate: ((bridge.config.autoupdates && bridge.config.autoupdates == true) || typeof bridge.config.autoupdates == 'undefined') });
73
- scope.lastBridgeInformation = Object.assign({}, bridgeInformation);
74
76
 
77
+ // NOT CONNECTED YET? -> NOTHING TO CACHE AND NOTHING TO SEND
78
+ if(!bridgeInformation)
79
+ {
80
+ reject(RED._("hue-bridge.node.error-not-available"));
81
+ return false;
82
+ }
83
+
84
+ scope.lastBridgeInformation = Object.assign({}, bridgeInformation);
75
85
  resolve(bridgeInformation);
76
86
  }
77
87
  });
@@ -79,7 +89,7 @@ module.exports = function(RED)
79
89
 
80
90
  //
81
91
  // SUBSCRIBE TO UPDATES FROM THE BRIDGE
82
- bridge.subscribe("bridge", "globalResourceUpdates", async function(info)
92
+ this.unsubscribe = bridge.subscribe("bridge", "globalResourceUpdates", async function(info)
83
93
  {
84
94
  let currentState = bridge.get(info.updatedType, info.id);
85
95
 
@@ -117,7 +127,8 @@ module.exports = function(RED)
117
127
 
118
128
  // RESET LAST COMMAND
119
129
  scope.lastCommand = null;
120
- });
130
+ })
131
+ .catch(function(error) { scope.debug(error); });
121
132
  }
122
133
  }
123
134
 
@@ -296,8 +307,22 @@ module.exports = function(RED)
296
307
  // RESET LAST COMMAND
297
308
  scope.lastCommand = null;
298
309
  }
310
+ })
311
+ .catch(function(error)
312
+ {
313
+ scope.error(error, msg);
314
+ scope.status({fill: "red", shape: "ring", text: "hue-bridge.node.connecting"});
315
+ if(done) { done(); }
299
316
  });
300
317
  });
318
+
319
+ //
320
+ // CLOSE NODE / DETACH FROM THE BRIDGE
321
+ this.on('close', function()
322
+ {
323
+ if(scope.unsubscribe) { scope.unsubscribe(); }
324
+ });
325
+
301
326
  }
302
327
 
303
328
  RED.nodes.registerType("hue-bridge-node", HueBridgeNode);
@@ -4,7 +4,7 @@
4
4
  <input type="text" id="node-input-name" data-i18n="[placeholder]hue-brightness.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-brightness.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">
@@ -18,16 +18,26 @@
18
18
  </button>
19
19
  </div>
20
20
  </div>
21
+ <div class="form-row">
22
+ <label for="node-input-darkthreshold"><i class="fa fa-adjust"></i> <span data-i18n="hue-brightness.config.darkthreshold"></span></label>
23
+ <input type="number" id="node-input-darkthreshold" placeholder="90" min="0" style="width: calc(100% - 105px)">
24
+ </div>
21
25
  <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-skipevents" style="flex: 15px;">
24
- <span data-i18n="hue-brightness.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
26
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
27
+ <input type="checkbox" id="node-input-skipevents" style="flex: 0 0 auto; width: auto; margin: 0;">
28
+ <span data-i18n="hue-brightness.config.skipevents-node" style="flex: 1; margin-left: 8px;"></span>
25
29
  </div>
26
30
  </div>
27
31
  <div class="form-row">
28
- <div style="display: inline-flex; width: calc(100% - 105px)">
29
- <input type="checkbox" id="node-input-initevents" style="flex: 15px;">
30
- <span data-i18n="hue-brightness.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
32
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
33
+ <input type="checkbox" id="node-input-initevents" style="flex: 0 0 auto; width: auto; margin: 0;">
34
+ <span data-i18n="hue-brightness.config.sendinitevents-node" style="flex: 1; margin-left: 8px;"></span>
35
+ </div>
36
+ </div>
37
+ <div class="form-row">
38
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
39
+ <input type="checkbox" id="node-input-onlycommands" style="flex: 0 0 auto; width: auto; margin: 0;">
40
+ <span data-i18n="hue-brightness.config.onlycommands-node" style="flex: 1; margin-left: 8px;"></span>
31
41
  </div>
32
42
  </div>
33
43
  </script>
@@ -40,11 +50,13 @@
40
50
  name: { value:"" },
41
51
  bridge: { type: "hue-bridge", required: true },
42
52
  sensorid: { value:"", required: false },
53
+ darkthreshold: { value: 90, validate: function(v) { return (v === "" || (!isNaN(v) && v >= 0)); } },
43
54
  skipevents: { value: false },
44
- initevents: { value: false }
55
+ initevents: { value: false },
56
+ onlycommands: { value: false }
45
57
  },
46
58
  align: 'left',
47
- icon: "hue-brightness.png",
59
+ icon: "hue-brightness.svg",
48
60
  inputs: 1,
49
61
  outputs: 1,
50
62
  label: function() {
@@ -37,15 +37,15 @@ module.exports = function(RED)
37
37
 
38
38
  //
39
39
  // SUBSCRIBE TO UPDATES FROM THE BRIDGE
40
- bridge.subscribe("light_level", config.sensorid, function(info)
40
+ this.unsubscribe = bridge.subscribe("light_level", config.sensorid, function(info)
41
41
  {
42
- let currentState = bridge.get("light_level", info.id);
42
+ let currentState = bridge.get("light_level", info.id, { darkThreshold: config.darkthreshold });
43
43
 
44
44
  // RESOURCE FOUND?
45
45
  if(currentState !== false)
46
46
  {
47
47
  // SEND MESSAGE
48
- if(!config.skipevents && (config.initevents || info.suppressMessage == false))
48
+ if(!config.skipevents && (config.initevents || info.suppressMessage == false) && (!config.onlycommands || scope.lastCommand !== null))
49
49
  {
50
50
  // SET LAST COMMAND
51
51
  if(scope.lastCommand !== null)
@@ -110,14 +110,14 @@ module.exports = function(RED)
110
110
  const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
111
111
  if(!tempSensorID)
112
112
  {
113
- scope.error("Please submit a valid sensor ID.");
113
+ scope.error(RED._("hue-brightness.node.error-no-id"), msg);
114
114
  return false;
115
115
  }
116
116
 
117
- let currentState = bridge.get("light_level", tempSensorID);
117
+ let currentState = bridge.get("light_level", tempSensorID, { darkThreshold: config.darkthreshold });
118
118
  if(!currentState)
119
119
  {
120
- 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.");
120
+ scope.error(RED._("hue-brightness.node.error-not-available"), msg);
121
121
  return false;
122
122
  }
123
123
 
@@ -159,11 +159,11 @@ module.exports = function(RED)
159
159
 
160
160
  // PATCH!
161
161
  async.retry({
162
- times: 3,
162
+ times: 5,
163
163
  errorFilter: function(err) {
164
- return (err.status == 503);
164
+ return (err.status == 503 || err.status == 429);
165
165
  },
166
- interval: function(retryCount) { return retryCount*2000; }
166
+ interval: function(retryCount) { return 750*retryCount; }
167
167
  },
168
168
  function(callback, results)
169
169
  {
@@ -196,9 +196,19 @@ module.exports = function(RED)
196
196
 
197
197
  // RESET LAST COMMAND
198
198
  scope.lastCommand = null;
199
+
200
+ if(done) { done(); }
199
201
  }
200
202
  });
203
+
204
+ //
205
+ // CLOSE NODE / DETACH FROM THE BRIDGE
206
+ this.on('close', function()
207
+ {
208
+ if(scope.unsubscribe) { scope.unsubscribe(); }
209
+ });
210
+
201
211
  }
202
212
 
203
213
  RED.nodes.registerType("hue-brightness", HueBrightness);
204
- }
214
+ }
@@ -4,7 +4,7 @@
4
4
  <input type="text" id="node-input-name" data-i18n="[placeholder]hue-buttons.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-buttons.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,17 +19,30 @@
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-skipevents" style="flex: 15px;">
24
- <span data-i18n="hue-buttons.config.skipevents-node" 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-skipevents" style="flex: 0 0 auto; width: auto; margin: 0;">
24
+ <span data-i18n="hue-buttons.config.skipevents-node" 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-initevents" style="flex: 15px;">
30
- <span data-i18n="hue-buttons.config.sendinitevents-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-initevents" style="flex: 0 0 auto; width: auto; margin: 0;">
30
+ <span data-i18n="hue-buttons.config.sendinitevents-node" style="flex: 1; margin-left: 8px;"></span>
31
+ </div>
32
+ </div>
33
+ <div class="form-row">
34
+ <div style="display: inline-flex; align-items: center; width: calc(100% - 105px)">
35
+ <input type="checkbox" id="node-input-onlycommands" style="flex: 0 0 auto; width: auto; margin: 0;">
36
+ <span data-i18n="hue-buttons.config.onlycommands-node" style="flex: 1; margin-left: 8px;"></span>
31
37
  </div>
32
38
  </div>
39
+ <div class="form-row">
40
+ <i class="fa fa-sign-out"></i> <b><span data-i18n="hue-buttons.config.add-outputs"></span></b>
41
+ </div>
42
+ <div class="form-row node-input-rule-container-row" style="width:100%">
43
+ <input type="hidden" id="node-input-outputs"/>
44
+ <ol id="node-input-rule-container"></ol>
45
+ </div>
33
46
  </script>
34
47
 
35
48
  <script type="text/javascript">
@@ -41,10 +54,13 @@
41
54
  bridge: { type: "hue-bridge", required: true },
42
55
  sensorid: { value:"", required: false },
43
56
  skipevents: { value: false },
44
- initevents: { value: false }
57
+ initevents: { value: false },
58
+ onlycommands: { value: false },
59
+ rules: { value: [] },
60
+ outputs: { value: 1 }
45
61
  },
46
62
  align: 'left',
47
- icon: "hue-buttons.png",
63
+ icon: "hue-buttons.svg",
48
64
  inputs: 1,
49
65
  outputs: 1,
50
66
  label: function() {
@@ -56,8 +72,35 @@
56
72
  inputLabels: function() {
57
73
  return this._("hue-buttons.node.input");
58
74
  },
59
- outputLabels: function() {
60
- return this._("hue-buttons.node.output");
75
+ outputLabels: function(index) {
76
+ let rule = (this.rules || [])[index-1];
77
+ let label = '';
78
+ if (rule) {
79
+ if (rule.buttonFrom == rule.buttonTo) {
80
+ label = this._('hue-buttons.config.outputlabel-btn-from' , {'from' : rule.buttonFrom});
81
+ } else {
82
+ label = this._('hue-buttons.config.outputlabel-btn-from-to' , {'from' : rule.buttonFrom, 'to' : rule.buttonTo});
83
+ }
84
+ let onEvents = [];
85
+ if (rule.onStartPress) {
86
+ onEvents.push (' - ' + this._('hue-buttons.config.outputlabel-btn-startpress'));
87
+ }
88
+ if (rule.onEndShortPress) {
89
+ onEvents.push (' - ' + this._('hue-buttons.config.outputlabel-btn-shortpress'));
90
+ }
91
+ if (rule.onEndLongPress) {
92
+ onEvents.push (' - ' + this._('hue-buttons.config.outputlabel-btn-longpress' , {'duration' : (rule.minLongPressDuration/1000).toFixed(1).toString()}) );
93
+ }
94
+ if (rule.onDuringLongPress) {
95
+ onEvents.push (' - ' + this._('hue-buttons.config.outputlabel-btn-longpresswhile') );
96
+ }
97
+ if (onEvents.length) {
98
+ label += ' ' + this._('hue-buttons.config.outputlabel-btn-on') + '\n' + onEvents.join ('\n');
99
+ }
100
+ } else {
101
+ label = this._('hue-buttons.node.output');
102
+ }
103
+ return label;
61
104
  },
62
105
  oneditprepare: function()
63
106
  {
@@ -182,7 +225,180 @@
182
225
  searchAndSelect();
183
226
  }
184
227
  });
228
+
229
+ // ADVANCED ADDITIONAL OUTPUTS
230
+ // Styles used in button range container
231
+ $("style").append("#node-input-rule-container .buttonrule-fromtolabel {display:inline-block; width:100px; margin-left: 20px;}");
232
+ $("style").append("#node-input-rule-container .buttonrule-checkbox {display:inline-block; width:22px; margin-left:0px; vertical-align:baseline;}");
233
+ $("style").append("#node-input-rule-container .buttonrule-select {width:60px; height: 23px; padding: 2px 2px; margin-left: 25px; margin-right: 35px; text-align: center;}");
234
+ $("style").append("#node-input-rule-container .buttonrule-checkbox-label {width: auto; margin-bottom: 2px;}");
235
+ // Output order can be updated to keep linked junctions correctly connected. To do so, a reserved item must contains
236
+ // outputs re-directions (if outputs are a,b,c,d, after configuring, new outputs are z,a,c, then 'node-input-outputs'
237
+ // must now be {"0":"1", "1":"-1", "2":"2", "3":"-1", "someRandomNo":"0"}.
238
+ var outputOrderIndexOnOpen = {};
239
+ function rebuildOutputIndexes (rulesUI) {
240
+ // Build new outputs : assume all which were defined before are 'deleted' (if not, they will be re-assigned right after)
241
+ let orderedRulesIndex = {'0':'0'}; // first output is always static, afterwards always index using i+1 therefore
242
+ Object.entries(outputOrderIndexOnOpen).forEach ((ruleIndex) => {orderedRulesIndex[ruleIndex[1]+1] = -1;});
243
+ // Parse each rule : if it existed before, build index transfer (Initial -> To), if new just indicate new index 'usage'
244
+ rulesUI.each(function(i) {
245
+ let ruleUI = $(this);
246
+ let curRowID = ruleUI.find("[id^=node-input-buttonFrom_]").attr('id').split("_").pop(); // row id is appended to each item, so gather it after the '_'
247
+ if (outputOrderIndexOnOpen.hasOwnProperty(curRowID)) {
248
+ // This rule existed on open, build index .initial -> .toCurrent
249
+ orderedRulesIndex[outputOrderIndexOnOpen[curRowID]+1] = i+1;
250
+ } else {
251
+ // This is a new rule : just add its final index using its rowID
252
+ orderedRulesIndex[curRowID] = i+1;
253
+ }
254
+ // Re-number them in UI (output number)
255
+ ruleUI.find(".node-input-rule-index").html(i+2);
256
+ });
257
+ $("#node-input-outputs").val(JSON.stringify(orderedRulesIndex));
258
+ }
259
+
260
+ $("#node-input-rule-container").css('min-height','350px').css('min-width','450px').editableList({
261
+ addButton: scope._('hue-buttons.config.add-outputs-btn-addnew'),
262
+ header: $("<div style='background:#EFEFEF; display:grid; grid-template-columns:135px 1fr 90px 30px'>"
263
+ +"<div style='margin-left: 30px; display: inline-grid; margin-top: 5px; font-weight:bold'>" + scope._('hue-buttons.config.add-outputs-range') + "</div>"
264
+ +"<div style='display: inline-grid; margin-top: 5px; font-weight:bold'>" + scope._('hue-buttons.config.add-outputs-newflow') + "</div>"
265
+ +"<div style='display: inline-grid; justify-self: end; margin-top: 5px; font-weight:bold'>" + scope._('hue-buttons.config.add-outputs-nr') + "</div>"
266
+ +"</div>"),
267
+
268
+ addItem: function (container, i, rules) {
269
+ let uniqueRowID = Math.floor((0x99999-0x10000)*Math.random()).toString()
270
+ if (!rules.hasOwnProperty('rule')) {
271
+ rules.rule = {};
272
+ } else {
273
+ // Rule existed before (=on load, keep its initial index)
274
+ outputOrderIndexOnOpen[uniqueRowID] = i;
275
+ }
276
+ var rule = rules.rule;
277
+
278
+ // When object is new, apply default values
279
+ if (!rule.hasOwnProperty('buttonFrom')) {
280
+ rule.buttonFrom = '1';
281
+ }
282
+ if (!rule.hasOwnProperty('buttonTo')) {
283
+ rule.buttonTo = '4';
284
+ }
285
+ if (!rule.hasOwnProperty('onEndShortPress')) {
286
+ rule.onEndShortPress = true;
287
+ }
288
+ if (!rule.hasOwnProperty('onEndLongPress')) {
289
+ rule.onEndLongPress = true;
290
+ }
291
+ if (!rule.hasOwnProperty('minLongPressDuration')) {
292
+ rule.minLongPressDuration = 1000;
293
+ }
294
+ // ROW 1 : 'From label' & checkbox 'Start press'
295
+ let row1 = $('<div/>').appendTo(container);
296
+ row1.append('<span class="buttonrule-fromtolabel">' + scope._('hue-buttons.config.add-outputs-btn-from') + '</span>');
297
+ let field_onStartPress = $('<input/>',{id:"node-input-onStartPress_" + uniqueRowID,type:"checkbox", class:"buttonrule-checkbox"}).appendTo(row1);
298
+ row1.append('<label class="buttonrule-checkbox-label" for="node-input-onStartPress_' + uniqueRowID + '">' + scope._('hue-buttons.config.add-outputs-startpress') + '</label>');
299
+ // ROW1 : output info (rightest part)
300
+ let finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row1);
301
+ finalspan.append('<i class="fa fa-sign-out"></i><span class="node-input-rule-index">'+(i+2)+'</span>');
302
+ // ROW 2 : 'From list' & checkbox 'End short press'
303
+ let row2 = $('<div/>').appendTo(container);
304
+ let field_buttonFrom = $('<select/>',{id:"node-input-buttonFrom_" + uniqueRowID, class:"buttonrule-select"}).appendTo(row2);
305
+ let field_onEndShortPress = $('<input/>',{id:"node-input-onEndShortPress_" + uniqueRowID, type:"checkbox", class:"buttonrule-checkbox"}).appendTo(row2);
306
+ row2.append('<label class="buttonrule-checkbox-label" for="node-input-onEndShortPress_' + uniqueRowID + '">' + scope._('hue-buttons.config.add-outputs-shortpress') + '</label>');
307
+ // ROW 3 : 'To label' & checkbox 'End long press after [xx] seconds'
308
+ let row3 = $('<div/>').appendTo(container);
309
+ row3.append('<span class="buttonrule-fromtolabel">' + scope._('hue-buttons.config.add-outputs-btn-to') + '</span>');
310
+ let field_onEndLongPress = $('<input/>',{id:"node-input-onEndLongPress_" + uniqueRowID, type:"checkbox", class:"buttonrule-checkbox"}).appendTo(row3);
311
+ row3.append('<label class="buttonrule-checkbox-label" for="node-input-onEndLongPress_' + uniqueRowID + '" style="width:unset";>' + scope._('hue-buttons.config.add-outputs-longpress') + '&nbsp</label>');
312
+ let field_minLongPressDuration = $('<input/>',{id:"node-input-minLongPressDuration_" + uniqueRowID, type:"text",style:"height:23px; width:55px; padding: 2px 2px;"}).appendTo(row3);
313
+ row3.append('<label class="buttonrule-checkbox-label" for="node-input-minLongPressDuration_' + uniqueRowID + '">&nbsp ms</label>');
314
+ // ROW 4 : 'To list' & checkbox 'During long press'
315
+ let row4 = $('<div/>').appendTo(container);
316
+ let field_buttonTo = $('<select/>',{id:"node-input-buttonTo_" + uniqueRowID, class:"buttonrule-select"}).appendTo(row4);
317
+ let field_onDuringLongPress = $('<input/>',{id:"node-input-onDuringLongPress_" + uniqueRowID, type:"checkbox", class:"buttonrule-checkbox"}).appendTo(row4);
318
+ row4.append('<label class="buttonrule-checkbox-label" for="node-input-onDuringLongPress_' + uniqueRowID + '">' + scope._('hue-buttons.config.add-outputs-longpresswhile') + '</label>');
319
+
320
+ // Build all 0-10 choices to both fields inputs
321
+ for (let i = 1; i <= 10; i++) {
322
+ field_buttonFrom.append($("<option></option>").val(i.toString()).text(i.toString()));
323
+ field_buttonTo.append($("<option></option>").val(i.toString()).text(i.toString()));
324
+ }
325
+
326
+ // Events : When From & To selector is changed, ensure range remains OK
327
+ field_buttonFrom.on ("change", function() {
328
+ if (parseInt(field_buttonFrom.val()) > parseInt(field_buttonTo.val())) {
329
+ field_buttonTo.val(field_buttonFrom.val());
330
+ }
331
+ });
332
+ field_buttonTo.on ("change", function() {
333
+ if (parseInt(field_buttonFrom.val()) > parseInt(field_buttonTo.val())) {
334
+ field_buttonFrom.val(field_buttonTo.val());
335
+ }
336
+ });
337
+
338
+ // Copy memory info back on fields
339
+ field_buttonFrom.val (rule.buttonFrom.toString());
340
+ field_buttonTo.val (rule.buttonTo.toString());
341
+ field_minLongPressDuration.val (rule.minLongPressDuration.toString());
342
+ // Checkboxes
343
+ field_onStartPress.prop ('checked', rule.onStartPress);
344
+ field_onEndShortPress.prop ('checked', rule.onEndShortPress);
345
+ field_onEndLongPress.prop ('checked', rule.onEndLongPress);
346
+ field_onDuringLongPress.prop ('checked', rule.onDuringLongPress);
347
+ // Update outputs (number of outputs and how the changed since onLoad)
348
+ rebuildOutputIndexes ($("#node-input-rule-container").editableList('items'));
349
+ },
350
+ removeItem: function (rule) {
351
+ // Update outputs (number of outputs and how the changed since onLoad)
352
+ rebuildOutputIndexes ($("#node-input-rule-container").editableList('items'));
353
+ },
354
+ sortItems: function (rules) {
355
+ // Update outputs (number of outputs and how the changed since onLoad)
356
+ rebuildOutputIndexes (rules);
357
+ },
358
+ sortable: true,
359
+ removable: true
360
+ });
361
+
362
+ // Add all previously saved rules back to UI List
363
+ let savedRules = this.rules || [];
364
+ for (let i = 0 ; i < savedRules.length ; i++) {
365
+ $("#node-input-rule-container").editableList('addItem',{rule:savedRules[i], i:i});
366
+ }
367
+
368
+ // An empty list never runs through addItem, so the output map has to be written once here
369
+ rebuildOutputIndexes ($("#node-input-rule-container").editableList('items'));
370
+ },
371
+
372
+ oneditresize: function(size) {
373
+ let rows = $("#dialog-form>div:not(.node-input-rule-container-row)");
374
+ let height = size.height;
375
+ for (let i = 0 ; i<rows.length ; i++) {
376
+ height -= $(rows[i]).outerHeight(true);
377
+ }
378
+ let editorRow = $("#dialog-form>div.node-input-rule-container-row");
379
+ height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
380
+ height += 40;
381
+ $("#node-input-rule-container").editableList('height',height);
185
382
  },
383
+
384
+ oneditsave: function() {
385
+ let rules = $("#node-input-rule-container").editableList('items');
386
+ let node = this;
387
+ node.rules = [];
388
+ rules.each (function (i) {
389
+ let rule = $(this);
390
+ let savedRule = {};
391
+ savedRule.buttonFrom = parseInt(rule.find("[id^=node-input-buttonFrom_]").val());
392
+ savedRule.buttonTo = parseInt(rule.find("[id^=node-input-buttonTo_]").val());
393
+ savedRule.onStartPress = rule.find("[id^=node-input-onStartPress_]").prop("checked");
394
+ savedRule.onEndShortPress = rule.find("[id^=node-input-onEndShortPress_]").prop("checked");
395
+ savedRule.onEndLongPress = rule.find("[id^=node-input-onEndLongPress_]").prop("checked");
396
+ savedRule.onDuringLongPress = rule.find("[id^=node-input-onDuringLongPress_]").prop("checked");
397
+ savedRule.minLongPressDuration = parseInt(rule.find("[id^=node-input-minLongPressDuration_]").val()) || 0;
398
+ node.rules.push (savedRule);
399
+ });
400
+ },
401
+
186
402
  button: {
187
403
  enabled: function() {
188
404
  return (this.sensorid && this.sensorid.length > 1)