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
@@ -2,12 +2,35 @@ module.exports = function(RED)
2
2
  {
3
3
  "use strict";
4
4
 
5
+ //
6
+ // DOES A BUTTON EVENT MATCH THE RULE OF AN ADDITIONAL OUTPUT?
7
+ function matchesRule(buttonState, rule)
8
+ {
9
+ // BUTTON OUTSIDE THE RANGE THE RULE WATCHES?
10
+ if(buttonState.button < parseInt(rule.buttonFrom) || buttonState.button > parseInt(rule.buttonTo)) { return false; }
11
+
12
+ switch (buttonState.actionType)
13
+ {
14
+ case "PRESS_START":
15
+ return !!rule.onStartPress;
16
+ case "SHORT":
17
+ return !!rule.onEndShortPress;
18
+ case "LONG_ONGOING":
19
+ return !!rule.onDuringLongPress;
20
+ case "LONG":
21
+ return (!!rule.onEndLongPress && buttonState.actionDuration >= (parseInt(rule.minLongPressDuration) || 0));
22
+ default:
23
+ return false;
24
+ }
25
+ }
26
+
5
27
  function HueButtons(config)
6
28
  {
7
29
  RED.nodes.createNode(this, config);
8
30
 
9
31
  const scope = this;
10
32
  const bridge = RED.nodes.getNode(config.bridge);
33
+ const async = require('async');
11
34
 
12
35
  // NODE UI STATUS TIMEOUT
13
36
  this.timeout = null;
@@ -15,6 +38,17 @@ module.exports = function(RED)
15
38
  // SAVE LAST COMMAND
16
39
  this.lastCommand = null;
17
40
 
41
+ // SAVE THE LAST STATE OF EVERY DEVICE AND BUTTON
42
+ scope.buttonLastStates = {};
43
+
44
+ //
45
+ // CLOSE NODE
46
+ this.on('close', function()
47
+ {
48
+ if(scope.timeout !== null) { clearTimeout(scope.timeout); }
49
+ if(scope.unsubscribe) { scope.unsubscribe(); }
50
+ });
51
+
18
52
  //
19
53
  // CHECK CONFIG
20
54
  if(bridge == null)
@@ -39,15 +73,65 @@ module.exports = function(RED)
39
73
 
40
74
  //
41
75
  // SUBSCRIBE TO UPDATES FROM THE BRIDGE
42
- bridge.subscribe("button", config.sensorid, function(info)
76
+ this.unsubscribe = bridge.subscribe("button", config.sensorid, function(info)
43
77
  {
44
78
  let currentState = bridge.get("button", info.id);
45
79
 
46
80
  // RESOURCE FOUND?
47
81
  if(currentState !== false)
48
82
  {
83
+ const hasEvent = (currentState.payload.button !== false || currentState.payload.rotation !== false);
84
+
85
+ // TRACK THE STATE OF THE PRESSED BUTTON, WHICH GIVES THE ADDITIONAL OUTPUTS THEIR PRESS DURATION
86
+ let buttonState = {};
87
+
88
+ if(currentState.payload.button !== false)
89
+ {
90
+ // EVERY DEVICE NUMBERS ITS BUTTONS FROM 1, SO THE STATE HAS TO BE KEPT PER DEVICE AND BUTTON
91
+ const buttonKey = info.id + ":" + currentState.payload.button;
92
+ buttonState = scope.buttonLastStates[buttonKey] || {};
93
+
94
+ switch (currentState.payload.action)
95
+ {
96
+ case "initial_press":
97
+ // START OF A SHORT OR A LONG PRESS
98
+ buttonState = { actionType: "PRESS_START", actionStart: Date.now() };
99
+ break;
100
+
101
+ case "long_press":
102
+ case "repeat":
103
+ // THE BRIDGE SENDS THIS EVENT EVERY 0.5 SECONDS WHILE THE BUTTON IS STILL HELD DOWN
104
+ buttonState.actionType = "LONG_ONGOING";
105
+ buttonState.actionEnd = Date.now();
106
+ break;
107
+
108
+ case "short_release":
109
+ case "double_short_release":
110
+ // PRESS SHORTER THAN 0.5 SECONDS
111
+ buttonState.actionType = "SHORT";
112
+ buttonState.actionStart = Date.now();
113
+ buttonState.actionEnd = Date.now();
114
+ break;
115
+
116
+ case "long_release":
117
+ // RELEASE AFTER A LONG PRESS
118
+ buttonState.actionType = "LONG";
119
+ buttonState.actionEnd = Date.now();
120
+ break;
121
+
122
+ default:
123
+ // UNKNOWN ACTION, MUST NOT INHERIT THE TYPE OF THE PREVIOUS ONE
124
+ buttonState.actionType = false;
125
+ }
126
+
127
+ buttonState.button = currentState.payload.button;
128
+ buttonState.actionDuration = (buttonState.actionEnd - buttonState.actionStart) || 0;
129
+
130
+ scope.buttonLastStates[buttonKey] = buttonState;
131
+ }
132
+
49
133
  // SEND MESSAGE
50
- if(!config.skipevents && currentState.payload.button !== false && (config.initevents || info.suppressMessage == false))
134
+ if(!config.skipevents && hasEvent && (config.initevents || info.suppressMessage == false) && (!config.onlycommands || scope.lastCommand !== null))
51
135
  {
52
136
  // SET LAST COMMAND
53
137
  if(scope.lastCommand !== null)
@@ -55,8 +139,21 @@ module.exports = function(RED)
55
139
  currentState.command = scope.lastCommand;
56
140
  }
57
141
 
142
+ // COPY THE EVENT TO EVERY ADDITIONAL OUTPUT THAT ASKED FOR IT
143
+ let outputs = [currentState];
144
+
145
+ if(currentState.payload.button !== false)
146
+ {
147
+ const rules = Array.isArray(config.rules) ? config.rules : [];
148
+
149
+ for (let i = 0; i < rules.length; i++)
150
+ {
151
+ outputs[i+1] = matchesRule(buttonState, rules[i]) ? RED.util.cloneMessage(currentState) : null;
152
+ }
153
+ }
154
+
58
155
  // SEND STATE
59
- scope.send(currentState);
156
+ scope.send(outputs);
60
157
 
61
158
  // RESET LAST COMMAND
62
159
  scope.lastCommand = null;
@@ -65,35 +162,53 @@ module.exports = function(RED)
65
162
  // NOT IN UNIVERAL MODE? -> CHANGE UI STATES
66
163
  if(config.sensorid)
67
164
  {
68
- if(currentState.payload.button === false)
165
+ if(!hasEvent)
69
166
  {
70
167
  scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
71
168
  }
72
169
  else
73
170
  {
74
- var action = "";
75
- switch (currentState.payload.action)
171
+ var statusText = "";
172
+
173
+ if(currentState.payload.button === false)
174
+ {
175
+ const rotation = currentState.payload.rotation;
176
+ statusText = RED._(rotation.clockwise ? "hue-buttons.node.dial-clockwise" : "hue-buttons.node.dial-counterclockwise", { degrees: rotation.degrees });
177
+ }
178
+ else
76
179
  {
77
- case "initial_press":
78
- action = "(pressed)";
79
- break;
80
- case "repeat":
81
- action = "(repeated)";
82
- break;
83
- case "short_release":
84
- action = "(short press)";
85
- break;
86
- case "long_release":
87
- action = "(long press)";
88
- break;
89
- case "double_short_release":
90
- action = "(double pressed)";
91
- break;
92
- default:
93
- action = "(pressed)";
180
+ var action = "";
181
+ switch (currentState.payload.action)
182
+ {
183
+ case "initial_press":
184
+ action = "action-started";
185
+ break;
186
+ case "repeat":
187
+ action = "action-repeated";
188
+ break;
189
+ case "short_release":
190
+ action = "action-shortreleased";
191
+ break;
192
+ case "long_press":
193
+ action = "action-holded";
194
+ break;
195
+ case "long_release":
196
+ action = "action-longreleased";
197
+ break;
198
+ case "double_short_release":
199
+ action = "action-doublepressed";
200
+ break;
201
+ default:
202
+ action = "action-pressed";
203
+ }
204
+
205
+ // THE DURATION IS ONLY KNOWN WHILE AND AFTER A BUTTON WAS HELD DOWN
206
+ statusText = (buttonState.actionDuration > 0)
207
+ ? RED._("hue-buttons.node.button-status-duration", { button: currentState.payload.button, action: RED._("hue-buttons.node." + action), duration: (buttonState.actionDuration / 1000).toFixed(1) })
208
+ : RED._("hue-buttons.node.button-status", { button: currentState.payload.button, action: RED._("hue-buttons.node." + action) });
94
209
  }
95
210
 
96
- scope.status({fill: "blue", shape: "dot", text: "Button #"+ currentState.payload.button + " " + action });
211
+ scope.status({fill: "blue", shape: "dot", text: statusText });
97
212
 
98
213
  // RESET TO WAITING AFTER 3 SECONDS
99
214
  if(scope.timeout !== null) { clearTimeout(scope.timeout); };
@@ -102,9 +217,12 @@ module.exports = function(RED)
102
217
  scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
103
218
 
104
219
  // REMOVE OLD BUTTON STATES
105
- for (const [oneButtonID, oneButton] of Object.entries(bridge.resources[config.sensorid]["services"]["button"]))
220
+ const buttons = (bridge.resources[config.sensorid] && bridge.resources[config.sensorid]["services"]) ? bridge.resources[config.sensorid]["services"]["button"] : false;
221
+ if(!buttons) { return false; }
222
+
223
+ for (const [oneButtonID, oneButton] of Object.entries(buttons))
106
224
  {
107
- delete bridge.resources[config.sensorid]["services"]["button"][oneButtonID]["button"];
225
+ delete buttons[oneButtonID]["button"];
108
226
  }
109
227
  }, 3000);
110
228
  }
@@ -127,14 +245,14 @@ module.exports = function(RED)
127
245
  const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
128
246
  if(!tempSensorID)
129
247
  {
130
- scope.error("Please submit a valid button ID.");
248
+ scope.error(RED._("hue-buttons.node.error-no-id"), msg);
131
249
  return false;
132
250
  }
133
251
 
134
252
  let currentState = bridge.get("button", tempSensorID);
135
253
  if(!currentState)
136
254
  {
137
- scope.error("The button/switch in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid.");
255
+ scope.error(RED._("hue-buttons.node.error-not-available"), msg);
138
256
  return false;
139
257
  }
140
258
 
@@ -156,6 +274,43 @@ module.exports = function(RED)
156
274
  if(done) { done(); }
157
275
  return true;
158
276
  }
277
+
278
+ // SWITCH BETWEEN ROCKER AND PUSHBUTTON MODE (WALL SWITCH MODULE)
279
+ if(typeof msg.payload != 'undefined' && typeof msg.payload.switchMode != 'undefined')
280
+ {
281
+ if(!currentState.info.switchModes)
282
+ {
283
+ scope.error(RED._("hue-buttons.node.error-no-switchmode"), msg);
284
+ return false;
285
+ }
286
+
287
+ if(currentState.info.switchModes.indexOf(msg.payload.switchMode) === -1)
288
+ {
289
+ scope.error(RED._("hue-buttons.node.error-invalid-switchmode", { modes: currentState.info.switchModes.join(", ") }), msg);
290
+ return false;
291
+ }
292
+
293
+ async.retry({
294
+ times: 5,
295
+ errorFilter: function(err) {
296
+ return (err.status == 503 || err.status == 429);
297
+ },
298
+ interval: function(retryCount) { return 750*retryCount; }
299
+ },
300
+ function(callback, results)
301
+ {
302
+ bridge.patch("switch_input_configuration", tempSensorID, { switch_mode: { mode: msg.payload.switchMode } })
303
+ .then(function() { callback(null, true); })
304
+ .catch(function(errors) { callback(errors, null); });
305
+ },
306
+ function(errors, success)
307
+ {
308
+ if(errors) { scope.error(errors, msg); }
309
+ else if(done) { done(); }
310
+ });
311
+
312
+ return true;
313
+ }
159
314
  });
160
315
  }
161
316
 
@@ -0,0 +1,218 @@
1
+ <script type="text/x-red" data-template-name="hue-contact">
2
+ <div class="form-row">
3
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-contact.config.name"></span></label>
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-contact.config.input-name" style="width: calc(100% - 105px)">
5
+ </div>
6
+ <div class="form-row">
7
+ <label for="node-input-bridge"><i class="fa fa-server"></i> <span data-i18n="hue-contact.config.bridge"></span></label>
8
+ <input type="text" id="node-input-bridge" style="width: calc(100% - 105px)">
9
+ </div>
10
+ <div class="form-row">
11
+ <label for="node-input-sensorid"><i class="fa fa-eye"></i> <span data-i18n="hue-contact.config.sensor"></span></label>
12
+ <div style="display: inline-flex; width: calc(100% - 105px)">
13
+ <div id="input-select-toggle" style="flex-grow: 1;">
14
+ <input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%"/>
15
+ </div>
16
+ <button id="node-config-input-scan-sensors" type="button" class="red-ui-button" style="margin-left: 10px;">
17
+ <i class="fa fa-search"></i>
18
+ </button>
19
+ </div>
20
+ </div>
21
+ <div class="form-row" style="margin-top: 30px">
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-contact.config.skipevents-node" style="flex: 1; margin-left: 8px;"></span>
25
+ </div>
26
+ </div>
27
+ <div class="form-row">
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-contact.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-contact.config.onlycommands-node" style="flex: 1; margin-left: 8px;"></span>
37
+ </div>
38
+ </div>
39
+ </script>
40
+
41
+ <script type="text/javascript">
42
+ RED.nodes.registerType('hue-contact',{
43
+ category: 'HueMagic',
44
+ color: '#ce5cd6',
45
+ defaults: {
46
+ name: { value:"" },
47
+ bridge: { type: "hue-bridge", required: true },
48
+ sensorid: { value:"", required: false },
49
+ skipevents: { value: false },
50
+ initevents: { value: false },
51
+ onlycommands: { value: false }
52
+ },
53
+ align: 'left',
54
+ icon: "hue-contact.svg",
55
+ inputs: 1,
56
+ outputs: 1,
57
+ label: function() {
58
+ return this.name || this._("hue-contact.node.title");
59
+ },
60
+ paletteLabel: function() {
61
+ return this._("hue-contact.node.title");
62
+ },
63
+ inputLabels: function() {
64
+ return this._("hue-contact.node.input");
65
+ },
66
+ outputLabels: function() {
67
+ return this._("hue-contact.node.output");
68
+ },
69
+ oneditprepare: function()
70
+ {
71
+ const scope = this;
72
+ let options = [];
73
+
74
+ function manualInput()
75
+ {
76
+ // GET CURRENT SELECTED VALUE
77
+ var current = $('#node-input-sensorid').val();
78
+
79
+ // REMOVE SELECT FIELD
80
+ $('#input-select-toggle').empty();
81
+
82
+ // CREATE NEW INPUT FIELD
83
+ $('#input-select-toggle').append('<input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%" value="'+current+'" />');
84
+
85
+ // CHANGE BUTTON ICON
86
+ var button = $("#node-config-input-scan-sensors");
87
+ var buttonIcon = button.find("i");
88
+ buttonIcon.removeClass("fa-pencil");
89
+ buttonIcon.addClass("fa-search");
90
+ }
91
+
92
+ function sortResourcesBy(prop, resources)
93
+ {
94
+ return resources.sort((a, b) => {
95
+ if ( a[prop] < b[prop] ){
96
+ return -1;
97
+ }
98
+ if ( a[prop] > b[prop] ){
99
+ return 1;
100
+ }
101
+ return 0;
102
+ });
103
+ }
104
+
105
+ function searchAndSelect()
106
+ {
107
+ // GET CURRENT BRIDGE CONFIGURATION
108
+ var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
109
+ if(!bridgeConfig) { return false; }
110
+
111
+ // GET CURRENT SELECTED VALUE
112
+ var current = $('#node-input-sensorid').val();
113
+
114
+ // TRIGGER SEARCHING NOTIFICATION
115
+ var notification = RED.notify(scope._("hue-contact.config.searching"), { type: "compact", modal: true, fixed: true });
116
+
117
+ // GET THE SENSORS
118
+ $.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "contact" })
119
+ .done( function(data) {
120
+ var allResources = JSON.parse(data);
121
+ allResources = sortResourcesBy('name', allResources);
122
+ if(allResources.length <= 0)
123
+ {
124
+ notification.close();
125
+ RED.notify(scope._("hue-contact.config.none-found"), { type: "error" });
126
+ return false;
127
+ }
128
+
129
+ // SET OPTIONS
130
+ allResources.forEach(function(resource)
131
+ {
132
+ if(resource.model)
133
+ {
134
+ options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
135
+ }
136
+ else
137
+ {
138
+ options[resource.id] = { value: resource.id, label: resource.name };
139
+ }
140
+ });
141
+
142
+ // SELECT CURRENT VALUE
143
+ $("#node-input-sensorid").typedInput({
144
+ types: [
145
+ {
146
+ value: current,
147
+ options: Object.values(options)
148
+ }
149
+ ]
150
+ });
151
+
152
+ // CHANGE BUTTON ICON
153
+ var button = $("#node-config-input-scan-sensors");
154
+ var buttonIcon = button.find("i");
155
+ buttonIcon.removeClass("fa-search");
156
+ buttonIcon.addClass("fa-pencil");
157
+
158
+ // CLOSE SEARCH NOTIFICATION
159
+ notification.close();
160
+ })
161
+ .fail(function()
162
+ {
163
+ notification.close();
164
+ RED.notify(scope._("hue-contact.config.unknown-error"), "error");
165
+ });
166
+ }
167
+
168
+ // CHANGED SENSOR ID? -> REPLACE NAME (IF POSSIBLE)
169
+ $(document).on('change', '#node-input-sensorid', function(e)
170
+ {
171
+ let currentSelectedOptionID = $(e.currentTarget).val();
172
+ let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
173
+
174
+ if(currentSelectedOptionValue !== false)
175
+ {
176
+ $('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
177
+ }
178
+ });
179
+
180
+ // TOGGLE SELECT/INPUT FIELD
181
+ $('#node-config-input-scan-sensors').click(function()
182
+ {
183
+ if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
184
+ {
185
+ manualInput();
186
+ }
187
+ else
188
+ {
189
+ searchAndSelect();
190
+ }
191
+ });
192
+ },
193
+ button: {
194
+ enabled: function() {
195
+ return (this.sensorid && this.sensorid.length > 1)
196
+ },
197
+ visible: function() {
198
+ return (this.sensorid && this.sensorid.length > 1)
199
+ },
200
+ onclick: function()
201
+ {
202
+ const node = this;
203
+ if(node.bridge)
204
+ {
205
+ $.ajax({
206
+ url: "inject/" + node.id,
207
+ type: "POST",
208
+ data: JSON.stringify({ __user_inject_props__: "status"}),
209
+ contentType: "application/json; charset=utf-8",
210
+ success: function (resp) {
211
+ RED.notify(node.name + ": " + node._("hue-contact.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
212
+ }
213
+ });
214
+ }
215
+ }
216
+ }
217
+ });
218
+ </script>