node-red-contrib-knx-ultimate 4.0.10 → 4.0.12

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 (399) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/nodes/commonFunctions.js +7 -1
  3. package/nodes/hue-config.html +2 -2
  4. package/nodes/hue-config.js +56 -0
  5. package/nodes/knxUltimate-config.html +11 -7
  6. package/nodes/knxUltimate-config.js +33 -8
  7. package/nodes/knxUltimate.html +87 -2
  8. package/nodes/knxUltimate.js +12 -8
  9. package/nodes/knxUltimateAlerter.html +6 -5
  10. package/nodes/knxUltimateAlerter.js +13 -15
  11. package/nodes/knxUltimateAutoResponder.html +1 -2
  12. package/nodes/knxUltimateAutoResponder.js +7 -7
  13. package/nodes/knxUltimateGlobalContext.html +1 -2
  14. package/nodes/knxUltimateGlobalContext.js +7 -7
  15. package/nodes/knxUltimateHueBattery.html +549 -222
  16. package/nodes/knxUltimateHueBattery.js +36 -20
  17. package/nodes/knxUltimateHueButton.html +688 -452
  18. package/nodes/knxUltimateHueButton.js +37 -23
  19. package/nodes/knxUltimateHueCameraMotion.html +631 -0
  20. package/nodes/knxUltimateHueCameraMotion.js +211 -0
  21. package/nodes/knxUltimateHueContactSensor.html +512 -212
  22. package/nodes/knxUltimateHueContactSensor.js +23 -15
  23. package/nodes/knxUltimateHueHumiditySensor.html +601 -0
  24. package/nodes/knxUltimateHueHumiditySensor.js +194 -0
  25. package/nodes/knxUltimateHueLight.html +788 -199
  26. package/nodes/knxUltimateHueLight.js +354 -79
  27. package/nodes/knxUltimateHueLightSensor.html +538 -224
  28. package/nodes/knxUltimateHueLightSensor.js +34 -20
  29. package/nodes/knxUltimateHueMotion.html +536 -215
  30. package/nodes/knxUltimateHueMotion.js +30 -15
  31. package/nodes/knxUltimateHuePlug.html +539 -0
  32. package/nodes/knxUltimateHuePlug.js +251 -0
  33. package/nodes/knxUltimateHueScene.html +863 -577
  34. package/nodes/knxUltimateHueScene.js +22 -10
  35. package/nodes/knxUltimateHueTapDial.html +543 -217
  36. package/nodes/knxUltimateHueTapDial.js +71 -34
  37. package/nodes/knxUltimateHueTemperatureSensor.html +541 -222
  38. package/nodes/knxUltimateHueTemperatureSensor.js +38 -22
  39. package/nodes/knxUltimateHueZigbeeConnectivity.html +549 -222
  40. package/nodes/knxUltimateHueZigbeeConnectivity.js +35 -19
  41. package/nodes/knxUltimateHuedevice_software_update.html +554 -222
  42. package/nodes/knxUltimateHuedevice_software_update.js +40 -19
  43. package/nodes/knxUltimateLoadControl.html +17 -6
  44. package/nodes/knxUltimateLoadControl.js +7 -7
  45. package/nodes/knxUltimateLogger.html +1 -2
  46. package/nodes/knxUltimateLogger.js +7 -7
  47. package/nodes/knxUltimateSceneController.html +7 -4
  48. package/nodes/knxUltimateSceneController.js +7 -7
  49. package/nodes/knxUltimateViewer.html +1 -2
  50. package/nodes/knxUltimateViewer.js +15 -15
  51. package/nodes/knxUltimateWatchDog.html +1 -1
  52. package/nodes/knxUltimateWatchDog.js +7 -7
  53. package/nodes/locales/{de-DE → de}/hue-config.html +2 -2
  54. package/nodes/locales/{de-DE → de}/knxUltimate-config.html +10 -19
  55. package/nodes/locales/{de-DE → de}/knxUltimate.html +24 -30
  56. package/nodes/locales/{de-DE → de}/knxUltimateAlerter.html +6 -10
  57. package/nodes/locales/{de-DE → de}/knxUltimateAutoResponder.html +22 -25
  58. package/nodes/locales/de/knxUltimateGarageDoorBarrierOpener.html +27 -0
  59. package/nodes/locales/{de-DE → de}/knxUltimateGlobalContext.html +10 -12
  60. package/nodes/locales/{de-DE → de}/knxUltimateHATranslator.html +1 -2
  61. package/nodes/locales/de/knxUltimateHueBattery.html +25 -0
  62. package/nodes/locales/de/knxUltimateHueBattery.json +18 -6
  63. package/nodes/locales/de/knxUltimateHueButton.html +53 -0
  64. package/nodes/locales/de/knxUltimateHueButton.json +21 -2
  65. package/nodes/locales/de/knxUltimateHueCameraMotion.html +41 -0
  66. package/nodes/locales/de/knxUltimateHueCameraMotion.json +30 -0
  67. package/nodes/locales/{de-DE → de}/knxUltimateHueContactSensor.html +1 -1
  68. package/nodes/locales/de/knxUltimateHueContactSensor.json +13 -2
  69. package/nodes/locales/de/knxUltimateHueHumiditySensor.html +27 -0
  70. package/nodes/locales/de/knxUltimateHueHumiditySensor.json +30 -0
  71. package/nodes/locales/{de-DE → de}/knxUltimateHueLight.html +17 -16
  72. package/nodes/locales/de/knxUltimateHueLight.json +13 -3
  73. package/nodes/locales/{de-DE → de}/knxUltimateHueLightSensor.html +1 -1
  74. package/nodes/locales/de/knxUltimateHueMotion.html +29 -0
  75. package/nodes/locales/de/knxUltimateHueMotion.json +16 -5
  76. package/nodes/locales/de/knxUltimateHuePlug.html +41 -0
  77. package/nodes/locales/de/knxUltimateHuePlug.json +33 -0
  78. package/nodes/locales/de/knxUltimateHueScene.html +50 -0
  79. package/nodes/locales/de/knxUltimateHueScene.json +16 -3
  80. package/nodes/locales/de/knxUltimateHueTapDial.html +45 -0
  81. package/nodes/locales/de/knxUltimateHueTapDial.json +14 -2
  82. package/nodes/locales/{de-DE → de}/knxUltimateHueTemperatureSensor.html +1 -1
  83. package/nodes/locales/de/knxUltimateHueTemperatureSensor.json +18 -5
  84. package/nodes/locales/{de-DE → de}/knxUltimateHueZigbeeConnectivity.html +4 -4
  85. package/nodes/locales/de/knxUltimateHueZigbeeConnectivity.json +18 -6
  86. package/nodes/locales/{de-DE → de}/knxUltimateHuedevice_software_update.html +4 -4
  87. package/nodes/locales/de/knxUltimateHuedevice_software_update.json +12 -0
  88. package/nodes/locales/{de-DE → de}/knxUltimateLoadControl.html +2 -2
  89. package/nodes/locales/{de-DE → de}/knxUltimateLogger.html +8 -3
  90. package/nodes/locales/{de-DE → de}/knxUltimateSceneController.html +8 -6
  91. package/nodes/locales/{de-DE → de}/knxUltimateViewer.html +7 -10
  92. package/nodes/locales/de/knxUltimateWatchDog.html +158 -0
  93. package/nodes/locales/{en-US → en}/hue-config.html +2 -3
  94. package/nodes/locales/{en-US → en}/knxUltimate-config.html +21 -33
  95. package/nodes/locales/{en-US → en}/knxUltimate-config.json +7 -3
  96. package/nodes/locales/{en-US → en}/knxUltimate.html +91 -98
  97. package/nodes/locales/{en-US → en}/knxUltimateAlerter.html +2 -11
  98. package/nodes/locales/{en-US → en}/knxUltimateAutoResponder.html +23 -30
  99. package/nodes/locales/en/knxUltimateGarageDoorBarrierOpener.html +27 -0
  100. package/nodes/locales/{en-US → en}/knxUltimateGlobalContext.html +13 -22
  101. package/nodes/locales/{en-US → en}/knxUltimateHATranslator.html +1 -2
  102. package/nodes/locales/en/knxUltimateHueBattery.html +25 -0
  103. package/nodes/locales/en/knxUltimateHueBattery.json +30 -0
  104. package/nodes/locales/en/knxUltimateHueButton.html +39 -0
  105. package/nodes/locales/en/knxUltimateHueButton.json +34 -0
  106. package/nodes/locales/en/knxUltimateHueCameraMotion.html +27 -0
  107. package/nodes/locales/en/knxUltimateHueCameraMotion.json +30 -0
  108. package/nodes/locales/en/knxUltimateHueContactSensor.json +26 -0
  109. package/nodes/locales/en/knxUltimateHueHumiditySensor.html +27 -0
  110. package/nodes/locales/en/knxUltimateHueHumiditySensor.json +30 -0
  111. package/nodes/locales/en/knxUltimateHueLight.html +101 -0
  112. package/nodes/locales/{en-US → en}/knxUltimateHueLight.json +13 -3
  113. package/nodes/locales/{en-US → en}/knxUltimateHueLightSensor.html +1 -1
  114. package/nodes/locales/en/knxUltimateHueMotion.html +29 -0
  115. package/nodes/locales/en/knxUltimateHueMotion.json +27 -0
  116. package/nodes/locales/en/knxUltimateHuePlug.html +41 -0
  117. package/nodes/locales/en/knxUltimateHuePlug.json +33 -0
  118. package/nodes/locales/en/knxUltimateHueScene.html +36 -0
  119. package/nodes/locales/en/knxUltimateHueScene.json +41 -0
  120. package/nodes/locales/en/knxUltimateHueTapDial.html +31 -0
  121. package/nodes/locales/en/knxUltimateHueTapDial.json +28 -0
  122. package/nodes/locales/{en-US → en}/knxUltimateHueTemperatureSensor.html +1 -1
  123. package/nodes/locales/en/knxUltimateHueTemperatureSensor.json +30 -0
  124. package/nodes/locales/{en-US → en}/knxUltimateHueZigbeeConnectivity.html +4 -4
  125. package/nodes/locales/en/knxUltimateHueZigbeeConnectivity.json +30 -0
  126. package/nodes/locales/{en-US → en}/knxUltimateHuedevice_software_update.html +4 -4
  127. package/nodes/locales/en/knxUltimateHuedevice_software_update.json +30 -0
  128. package/nodes/locales/{en-US → en}/knxUltimateLoadControl.html +5 -6
  129. package/nodes/locales/{en-US → en}/knxUltimateLogger.html +6 -15
  130. package/nodes/locales/{en-US → en}/knxUltimateSceneController.html +15 -23
  131. package/nodes/locales/{en-US → en}/knxUltimateViewer.html +11 -13
  132. package/nodes/locales/en/knxUltimateWatchDog.html +233 -0
  133. package/nodes/locales/es/common.json +12 -0
  134. package/nodes/locales/es/hue-config.html +20 -0
  135. package/nodes/locales/es/hue-config.json +19 -0
  136. package/nodes/locales/es/knxUltimate-config.html +138 -0
  137. package/nodes/locales/es/knxUltimate-config.json +108 -0
  138. package/nodes/locales/es/knxUltimate.html +545 -0
  139. package/nodes/locales/es/knxUltimate.json +105 -0
  140. package/nodes/locales/es/knxUltimateAlerter.html +124 -0
  141. package/nodes/locales/es/knxUltimateAlerter.json +24 -0
  142. package/nodes/locales/es/knxUltimateAutoResponder.html +55 -0
  143. package/nodes/locales/es/knxUltimateAutoResponder.json +5 -0
  144. package/nodes/locales/es/knxUltimateGarageDoorBarrierOpener.json +11 -0
  145. package/nodes/locales/es/knxUltimateGlobalContext.html +114 -0
  146. package/nodes/locales/es/knxUltimateGlobalContext.json +21 -0
  147. package/nodes/locales/es/knxUltimateHATranslator.html +15 -0
  148. package/nodes/locales/es/knxUltimateHATranslator.json +5 -0
  149. package/nodes/locales/es/knxUltimateHueBattery.html +25 -0
  150. package/nodes/locales/es/knxUltimateHueBattery.json +30 -0
  151. package/nodes/locales/es/knxUltimateHueButton.html +39 -0
  152. package/nodes/locales/es/knxUltimateHueButton.json +34 -0
  153. package/nodes/locales/es/knxUltimateHueCameraMotion.html +27 -0
  154. package/nodes/locales/es/knxUltimateHueCameraMotion.json +30 -0
  155. package/nodes/locales/es/knxUltimateHueContactSensor.html +25 -0
  156. package/nodes/locales/es/knxUltimateHueContactSensor.json +26 -0
  157. package/nodes/locales/es/knxUltimateHueHumiditySensor.html +27 -0
  158. package/nodes/locales/es/knxUltimateHueHumiditySensor.json +30 -0
  159. package/nodes/locales/es/knxUltimateHueLight.html +101 -0
  160. package/nodes/locales/es/knxUltimateHueLight.json +84 -0
  161. package/nodes/locales/es/knxUltimateHueLightSensor.html +27 -0
  162. package/nodes/locales/es/knxUltimateHueLightSensor.json +19 -0
  163. package/nodes/locales/es/knxUltimateHueMotion.html +29 -0
  164. package/nodes/locales/es/knxUltimateHueMotion.json +27 -0
  165. package/nodes/locales/es/knxUltimateHuePlug.html +41 -0
  166. package/nodes/locales/es/knxUltimateHuePlug.json +33 -0
  167. package/nodes/locales/es/knxUltimateHueScene.html +36 -0
  168. package/nodes/locales/es/knxUltimateHueScene.json +41 -0
  169. package/nodes/locales/es/knxUltimateHueTapDial.html +31 -0
  170. package/nodes/locales/es/knxUltimateHueTapDial.json +28 -0
  171. package/nodes/locales/es/knxUltimateHueTemperatureSensor.html +27 -0
  172. package/nodes/locales/es/knxUltimateHueTemperatureSensor.json +30 -0
  173. package/nodes/locales/es/knxUltimateHueZigbeeConnectivity.html +28 -0
  174. package/nodes/locales/es/knxUltimateHueZigbeeConnectivity.json +30 -0
  175. package/nodes/locales/es/knxUltimateHuedevice_software_update.html +25 -0
  176. package/nodes/locales/es/knxUltimateHuedevice_software_update.json +30 -0
  177. package/nodes/locales/es/knxUltimateLoadControl.html +61 -0
  178. package/nodes/locales/es/knxUltimateLoadControl.json +21 -0
  179. package/nodes/locales/es/knxUltimateLogger.html +120 -0
  180. package/nodes/locales/es/knxUltimateLogger.json +19 -0
  181. package/nodes/locales/es/knxUltimateSceneController.html +85 -0
  182. package/nodes/locales/es/knxUltimateSceneController.json +29 -0
  183. package/nodes/locales/es/knxUltimateViewer.html +441 -0
  184. package/nodes/locales/es/knxUltimateViewer.json +11 -0
  185. package/nodes/locales/es/knxUltimateWatchDog.html +179 -0
  186. package/nodes/locales/es/knxUltimateWatchDog.json +23 -0
  187. package/nodes/locales/fr/common.json +12 -0
  188. package/nodes/locales/fr/hue-config.html +20 -0
  189. package/nodes/locales/fr/hue-config.json +19 -0
  190. package/nodes/locales/fr/knxUltimate-config.html +149 -0
  191. package/nodes/locales/fr/knxUltimate-config.json +108 -0
  192. package/nodes/locales/fr/knxUltimate.html +543 -0
  193. package/nodes/locales/fr/knxUltimate.json +105 -0
  194. package/nodes/locales/fr/knxUltimateAlerter.html +124 -0
  195. package/nodes/locales/fr/knxUltimateAlerter.json +24 -0
  196. package/nodes/locales/fr/knxUltimateAutoResponder.html +67 -0
  197. package/nodes/locales/fr/knxUltimateAutoResponder.json +5 -0
  198. package/nodes/locales/fr/knxUltimateGarageDoorBarrierOpener.json +11 -0
  199. package/nodes/locales/fr/knxUltimateGlobalContext.html +113 -0
  200. package/nodes/locales/fr/knxUltimateGlobalContext.json +21 -0
  201. package/nodes/locales/fr/knxUltimateHATranslator.html +15 -0
  202. package/nodes/locales/fr/knxUltimateHATranslator.json +5 -0
  203. package/nodes/locales/fr/knxUltimateHueBattery.html +25 -0
  204. package/nodes/locales/fr/knxUltimateHueBattery.json +30 -0
  205. package/nodes/locales/fr/knxUltimateHueButton.html +39 -0
  206. package/nodes/locales/fr/knxUltimateHueButton.json +34 -0
  207. package/nodes/locales/fr/knxUltimateHueCameraMotion.html +27 -0
  208. package/nodes/locales/fr/knxUltimateHueCameraMotion.json +30 -0
  209. package/nodes/locales/fr/knxUltimateHueContactSensor.html +25 -0
  210. package/nodes/locales/fr/knxUltimateHueContactSensor.json +26 -0
  211. package/nodes/locales/fr/knxUltimateHueHumiditySensor.html +27 -0
  212. package/nodes/locales/fr/knxUltimateHueHumiditySensor.json +30 -0
  213. package/nodes/locales/fr/knxUltimateHueLight.html +101 -0
  214. package/nodes/locales/fr/knxUltimateHueLight.json +84 -0
  215. package/nodes/locales/fr/knxUltimateHueLightSensor.html +27 -0
  216. package/nodes/locales/fr/knxUltimateHueLightSensor.json +19 -0
  217. package/nodes/locales/fr/knxUltimateHueMotion.html +29 -0
  218. package/nodes/locales/fr/knxUltimateHueMotion.json +27 -0
  219. package/nodes/locales/fr/knxUltimateHuePlug.html +41 -0
  220. package/nodes/locales/fr/knxUltimateHuePlug.json +33 -0
  221. package/nodes/locales/fr/knxUltimateHueScene.html +36 -0
  222. package/nodes/locales/fr/knxUltimateHueScene.json +41 -0
  223. package/nodes/locales/fr/knxUltimateHueTapDial.html +31 -0
  224. package/nodes/locales/fr/knxUltimateHueTapDial.json +28 -0
  225. package/nodes/locales/fr/knxUltimateHueTemperatureSensor.html +27 -0
  226. package/nodes/locales/fr/knxUltimateHueTemperatureSensor.json +30 -0
  227. package/nodes/locales/fr/knxUltimateHueZigbeeConnectivity.html +28 -0
  228. package/nodes/locales/fr/knxUltimateHueZigbeeConnectivity.json +30 -0
  229. package/nodes/locales/fr/knxUltimateHuedevice_software_update.html +25 -0
  230. package/nodes/locales/fr/knxUltimateHuedevice_software_update.json +30 -0
  231. package/nodes/locales/fr/knxUltimateLoadControl.html +61 -0
  232. package/nodes/locales/fr/knxUltimateLoadControl.json +21 -0
  233. package/nodes/locales/fr/knxUltimateLogger.html +118 -0
  234. package/nodes/locales/fr/knxUltimateLogger.json +19 -0
  235. package/nodes/locales/fr/knxUltimateSceneController.html +87 -0
  236. package/nodes/locales/fr/knxUltimateSceneController.json +29 -0
  237. package/nodes/locales/fr/knxUltimateViewer.html +441 -0
  238. package/nodes/locales/fr/knxUltimateViewer.json +11 -0
  239. package/nodes/locales/fr/knxUltimateWatchDog.html +177 -0
  240. package/nodes/locales/fr/knxUltimateWatchDog.json +23 -0
  241. package/nodes/locales/{it-IT → it}/hue-config.html +6 -6
  242. package/nodes/locales/{it-IT → it}/knxUltimate-config.html +21 -29
  243. package/nodes/locales/it/knxUltimate-config.json +7 -3
  244. package/nodes/locales/{it-IT → it}/knxUltimate.html +33 -40
  245. package/nodes/locales/{it-IT → it}/knxUltimateAlerter.html +13 -17
  246. package/nodes/locales/{it-IT → it}/knxUltimateAutoResponder.html +23 -26
  247. package/nodes/locales/it/knxUltimateGarageDoorBarrierOpener.html +27 -0
  248. package/nodes/locales/{it-IT → it}/knxUltimateGlobalContext.html +12 -14
  249. package/nodes/locales/{it-IT → it}/knxUltimateHATranslator.html +1 -2
  250. package/nodes/locales/it/knxUltimateHueBattery.html +25 -0
  251. package/nodes/locales/it/knxUltimateHueBattery.json +18 -6
  252. package/nodes/locales/it/knxUltimateHueButton.html +53 -0
  253. package/nodes/locales/it/knxUltimateHueButton.json +21 -2
  254. package/nodes/locales/it/knxUltimateHueCameraMotion.html +41 -0
  255. package/nodes/locales/it/knxUltimateHueCameraMotion.json +30 -0
  256. package/nodes/locales/{it-IT → it}/knxUltimateHueContactSensor.html +3 -3
  257. package/nodes/locales/it/knxUltimateHueContactSensor.json +13 -2
  258. package/nodes/locales/it/knxUltimateHueHumiditySensor 2.html +11 -0
  259. package/nodes/locales/it/knxUltimateHueHumiditySensor.html +27 -0
  260. package/nodes/locales/it/knxUltimateHueHumiditySensor.json +30 -0
  261. package/nodes/locales/{it-IT → it}/knxUltimateHueLight.html +28 -29
  262. package/nodes/locales/it/knxUltimateHueLight.json +13 -3
  263. package/nodes/locales/{it-IT → it}/knxUltimateHueLightSensor.html +2 -2
  264. package/nodes/locales/it/knxUltimateHueMotion.html +29 -0
  265. package/nodes/locales/it/knxUltimateHueMotion.json +16 -5
  266. package/nodes/locales/it/knxUltimateHuePlug.html +41 -0
  267. package/nodes/locales/it/knxUltimateHuePlug.json +33 -0
  268. package/nodes/locales/it/knxUltimateHueScene.html +50 -0
  269. package/nodes/locales/it/knxUltimateHueScene.json +16 -3
  270. package/nodes/locales/it/knxUltimateHueTapDial.html +45 -0
  271. package/nodes/locales/it/knxUltimateHueTapDial.json +14 -2
  272. package/nodes/locales/{it-IT → it}/knxUltimateHueTemperatureSensor.html +2 -2
  273. package/nodes/locales/it/knxUltimateHueTemperatureSensor.json +18 -6
  274. package/nodes/locales/{it-IT → it}/knxUltimateHueZigbeeConnectivity.html +5 -5
  275. package/nodes/locales/it/knxUltimateHueZigbeeConnectivity.json +18 -6
  276. package/nodes/locales/{it-IT → it}/knxUltimateHuedevice_software_update.html +4 -4
  277. package/nodes/locales/it/knxUltimateHuedevice_software_update.json +12 -0
  278. package/nodes/locales/{it-IT → it}/knxUltimateLoadControl.html +6 -7
  279. package/nodes/locales/{it-IT → it}/knxUltimateLogger.html +13 -8
  280. package/nodes/locales/{it-IT → it}/knxUltimateSceneController.html +14 -12
  281. package/nodes/locales/{it-IT → it}/knxUltimateViewer.html +7 -10
  282. package/nodes/locales/it/knxUltimateWatchDog.html +173 -0
  283. package/nodes/locales/zh-CN/hue-config.html +2 -2
  284. package/nodes/locales/zh-CN/knxUltimate-config.html +11 -20
  285. package/nodes/locales/zh-CN/knxUltimate.html +25 -31
  286. package/nodes/locales/zh-CN/knxUltimateAlerter.html +5 -9
  287. package/nodes/locales/zh-CN/knxUltimateAutoResponder.html +22 -27
  288. package/nodes/locales/zh-CN/knxUltimateGarageDoorBarrierOpener.html +6 -42
  289. package/nodes/locales/zh-CN/knxUltimateGlobalContext.html +9 -11
  290. package/nodes/locales/zh-CN/knxUltimateHATranslator.html +2 -3
  291. package/nodes/locales/zh-CN/knxUltimateHueBattery.html +14 -7
  292. package/nodes/locales/zh-CN/knxUltimateHueBattery.json +18 -6
  293. package/nodes/locales/zh-CN/knxUltimateHueButton.html +39 -23
  294. package/nodes/locales/zh-CN/knxUltimateHueButton.json +21 -2
  295. package/nodes/locales/zh-CN/knxUltimateHueCameraMotion.html +41 -0
  296. package/nodes/locales/zh-CN/knxUltimateHueCameraMotion.json +30 -0
  297. package/nodes/locales/zh-CN/knxUltimateHueContactSensor.html +2 -2
  298. package/nodes/locales/zh-CN/knxUltimateHueContactSensor.json +13 -2
  299. package/nodes/locales/zh-CN/knxUltimateHueHumiditySensor.html +27 -0
  300. package/nodes/locales/zh-CN/knxUltimateHueHumiditySensor.json +30 -0
  301. package/nodes/locales/zh-CN/knxUltimateHueLight.html +33 -32
  302. package/nodes/locales/zh-CN/knxUltimateHueLight.json +13 -3
  303. package/nodes/locales/zh-CN/knxUltimateHueLightSensor.html +3 -3
  304. package/nodes/locales/zh-CN/knxUltimateHueMotion.html +17 -14
  305. package/nodes/locales/zh-CN/knxUltimateHueMotion.json +16 -5
  306. package/nodes/locales/zh-CN/knxUltimateHuePlug.html +41 -0
  307. package/nodes/locales/zh-CN/knxUltimateHuePlug.json +33 -0
  308. package/nodes/locales/zh-CN/knxUltimateHueScene.html +48 -42
  309. package/nodes/locales/zh-CN/knxUltimateHueScene.json +15 -2
  310. package/nodes/locales/zh-CN/knxUltimateHueTapDial.html +33 -18
  311. package/nodes/locales/zh-CN/knxUltimateHueTapDial.json +14 -2
  312. package/nodes/locales/zh-CN/knxUltimateHueTemperatureSensor.html +1 -1
  313. package/nodes/locales/zh-CN/knxUltimateHueTemperatureSensor.json +19 -6
  314. package/nodes/locales/zh-CN/knxUltimateHueZigbeeConnectivity.html +4 -4
  315. package/nodes/locales/zh-CN/knxUltimateHueZigbeeConnectivity.json +18 -6
  316. package/nodes/locales/zh-CN/knxUltimateHuedevice_software_update.html +5 -5
  317. package/nodes/locales/zh-CN/knxUltimateHuedevice_software_update.json +12 -0
  318. package/nodes/locales/zh-CN/knxUltimateLoadControl.html +8 -9
  319. package/nodes/locales/zh-CN/knxUltimateLogger.html +8 -3
  320. package/nodes/locales/zh-CN/knxUltimateSceneController.html +8 -6
  321. package/nodes/locales/zh-CN/knxUltimateViewer.html +9 -13
  322. package/nodes/locales/zh-CN/knxUltimateWatchDog.html +158 -0
  323. package/nodes/utils/hueEngine.mjs +14 -8
  324. package/package.json +5 -2
  325. package/resources/htmlUtils.js +27 -0
  326. package/scripts/manual_translate_fr_es.py +149 -0
  327. package/scripts/sync-help-from-wiki.js +98 -0
  328. package/scripts/update-help-from-wiki.js +116 -0
  329. package/tutorial/HUE Api/Hue CLIP API.html +47356 -0
  330. package/tutorial/HUE Api/Hue CLIP API_files/bootstrap.min.css +6 -0
  331. package/tutorial/HUE Api/Hue CLIP API_files/bootstrap.min.js +6 -0
  332. package/tutorial/HUE Api/Hue CLIP API_files/default.min.css +1 -0
  333. package/tutorial/HUE Api/Hue CLIP API_files/highlight.min.js +1296 -0
  334. package/tutorial/HUE Api/Hue CLIP API_files/jquery-3.5.1.min.js +2 -0
  335. package/tutorial/knxUltimate-AllNodes-Presentazione.md +190 -0
  336. package/tutorial/knxUltimateHueBattery-teleprompter.txt +5 -1
  337. package/tutorial/knxUltimateHueBattery.md +8 -5
  338. package/tutorial/knxUltimateHueCameraMotion-teleprompter.txt +44 -0
  339. package/tutorial/knxUltimateHueCameraMotion.md +45 -0
  340. package/tutorial/knxUltimateHueHumiditySensor-teleprompter.txt +43 -0
  341. package/tutorial/knxUltimateHueHumiditySensor.md +45 -0
  342. package/tutorial/knxUltimateHueLightSensor-teleprompter.txt +4 -0
  343. package/tutorial/knxUltimateHueLightSensor.md +5 -5
  344. package/tutorial/knxUltimateHueMotion-teleprompter.txt +4 -0
  345. package/tutorial/knxUltimateHueMotion.md +8 -4
  346. package/tutorial/knxUltimateHuePlug-teleprompter.txt +48 -0
  347. package/tutorial/knxUltimateHuePlug.md +49 -0
  348. package/tutorial/knxUltimateHueScene-teleprompter.txt +4 -0
  349. package/tutorial/knxUltimateHueTapDial-teleprompter.txt +4 -0
  350. package/tutorial/knxUltimateHueTapDial.md +8 -4
  351. package/tutorial/knxUltimateHueTemperatureSensor-teleprompter.txt +4 -0
  352. package/tutorial/knxUltimateHueTemperatureSensor.md +5 -4
  353. package/tutorial/knxUltimateHueZigbeeConnectivity-teleprompter.txt +4 -0
  354. package/tutorial/knxUltimateHueZigbeeConnectivity.md +4 -3
  355. package/tutorial/knxUltimateHuedevice_software_update-teleprompter.txt +4 -0
  356. package/tutorial/knxUltimateHuedevice_software_update.md +5 -5
  357. package/nodes/locales/de-DE/knxUltimateGarageDoorBarrierOpener.html +0 -63
  358. package/nodes/locales/de-DE/knxUltimateHueBattery.html +0 -18
  359. package/nodes/locales/de-DE/knxUltimateHueButton.html +0 -37
  360. package/nodes/locales/de-DE/knxUltimateHueMotion.html +0 -26
  361. package/nodes/locales/de-DE/knxUltimateHueScene.html +0 -44
  362. package/nodes/locales/de-DE/knxUltimateHueTapDial.html +0 -30
  363. package/nodes/locales/en-US/knxUltimateGarageDoorBarrierOpener.html +0 -63
  364. package/nodes/locales/en-US/knxUltimateHueBattery.html +0 -18
  365. package/nodes/locales/en-US/knxUltimateHueBattery.json +0 -18
  366. package/nodes/locales/en-US/knxUltimateHueButton.html +0 -37
  367. package/nodes/locales/en-US/knxUltimateHueButton.json +0 -15
  368. package/nodes/locales/en-US/knxUltimateHueContactSensor.json +0 -15
  369. package/nodes/locales/en-US/knxUltimateHueLight.html +0 -102
  370. package/nodes/locales/en-US/knxUltimateHueMotion.html +0 -26
  371. package/nodes/locales/en-US/knxUltimateHueMotion.json +0 -16
  372. package/nodes/locales/en-US/knxUltimateHueScene.html +0 -44
  373. package/nodes/locales/en-US/knxUltimateHueScene.json +0 -28
  374. package/nodes/locales/en-US/knxUltimateHueTapDial.html +0 -30
  375. package/nodes/locales/en-US/knxUltimateHueTapDial.json +0 -16
  376. package/nodes/locales/en-US/knxUltimateHueTemperatureSensor.json +0 -18
  377. package/nodes/locales/en-US/knxUltimateHueZigbeeConnectivity.json +0 -18
  378. package/nodes/locales/en-US/knxUltimateHuedevice_software_update.json +0 -18
  379. package/nodes/locales/it-IT/knxUltimateGarageDoorBarrierOpener.html +0 -63
  380. package/nodes/locales/it-IT/knxUltimateHueBattery.html +0 -18
  381. package/nodes/locales/it-IT/knxUltimateHueButton.html +0 -36
  382. package/nodes/locales/it-IT/knxUltimateHueMotion.html +0 -26
  383. package/nodes/locales/it-IT/knxUltimateHueScene.html +0 -44
  384. package/nodes/locales/it-IT/knxUltimateHueTapDial.html +0 -30
  385. /package/nodes/locales/{en-US → en}/common.json +0 -0
  386. /package/nodes/locales/{en-US → en}/hue-config.json +0 -0
  387. /package/nodes/locales/{en-US → en}/knxUltimate.json +0 -0
  388. /package/nodes/locales/{en-US → en}/knxUltimateAlerter.json +0 -0
  389. /package/nodes/locales/{en-US → en}/knxUltimateAutoResponder.json +0 -0
  390. /package/nodes/locales/{en-US → en}/knxUltimateGarageDoorBarrierOpener.json +0 -0
  391. /package/nodes/locales/{en-US → en}/knxUltimateGlobalContext.json +0 -0
  392. /package/nodes/locales/{en-US → en}/knxUltimateHATranslator.json +0 -0
  393. /package/nodes/locales/{en-US → en}/knxUltimateHueContactSensor.html +0 -0
  394. /package/nodes/locales/{en-US → en}/knxUltimateHueLightSensor.json +0 -0
  395. /package/nodes/locales/{en-US → en}/knxUltimateLoadControl.json +0 -0
  396. /package/nodes/locales/{en-US → en}/knxUltimateLogger.json +0 -0
  397. /package/nodes/locales/{en-US → en}/knxUltimateSceneController.json +0 -0
  398. /package/nodes/locales/{en-US → en}/knxUltimateViewer.json +0 -0
  399. /package/nodes/locales/{en-US → en}/knxUltimateWatchDog.json +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 4.0.12** - October 2025<br/>
10
+ - KNX Config node: replaced the "errors only" status filter with a configurable status throttle (0/1/3/5/10/30 s) that emits only the latest status after the chosen delay, preventing editor memory growth when many nodes update.<br/>
11
+ - HUE Light node: the "Keep brightness" option now restores the last active dim level when toggled via KNX On/Off instead of forcing 100%.<br/>
12
+
13
+ **Version 4.0.11** - October 2025<br/>
14
+ - HUE nodes: hardened KNX telegram handling with a shared safe-send guard so editor events no longer ceases to function, when the KNX gateway is offline.<br/>
15
+ - HUE Contact Sensor node: placeholders now leverage i18n translations with graceful fallback when translation keys are missing.<br/>
16
+ - Editor polish: unified the default width of the `name` input across KNX and Hue nodes for a consistent layout.<br/>
17
+ - KNX Scene Controller, Alerter and Load Control nodes: GA autocompletes now open their suggestion list immediately on focus/click to speed up GA selection.<br/>
18
+ - Docs: audited external links; Hue API references require developer login but all other anchors resolve correctly.<br/>
19
+ - HUE Light node: added configuration UI and runtime support for Hue lamp dynamic effects (candle, fireplace, etc.) with KNX mappings and status feedback.<br/>
20
+ - NEW: Added Hue Plug/Outlet node to map KNX on/off control to Philips Hue smart plugs.<br/>
21
+ - NEW: Added Hue Humidity Sensor node to expose relative humidity readings from Hue bridges to KNX.<br/>
22
+ - NEW: Added Hue Camera Motion node to forward Hue camera motion detections to KNX, with optional flow output pins.<br/>
23
+ - Hue Button node: refreshed editor layout and switched to Hue `button.button_report.event` instead of the deprecated `last_event`.<br/>
24
+ - Hue Battery, Motion, Temperature, Light Sensor and Zigbee Connectivity nodes now share the unified editor layout with refresh icon, KNX-aware tabs and optional flow pin toggles.<br/>
25
+ - Docs: cleaned bold markdown spacing across KNX Ultimate help translations to avoid rendering glitches.<br/>
26
+
9
27
  **Version 4.0.10** - October 2025<br/>
10
28
  - KNX Config node: you can now choose wether to display only the errors in the node statuses only errors.<br/>
11
29
 
@@ -1961,4 +1979,3 @@ This is an interim version, to quick fix some issues. Please report any issue wi
1961
1979
 
1962
1980
  **Version 0.0.1 BETA**<br/>
1963
1981
  - Initial release<br/>
1964
-
@@ -74,10 +74,16 @@ module.exports = (RED) => {
74
74
  RED.httpAdmin.get('/knxultimateCheckHueConnected', (req, res) => {
75
75
  try {
76
76
  const serverId = RED.nodes.getNode(req.query.serverId); // Retrieve node.id of the config node.
77
+ if (!serverId) {
78
+ res.json({ ready: false });
79
+ return;
80
+ }
77
81
  if (serverId.hueAllResources === null || serverId.hueAllResources === undefined) {
78
82
  (async function main() {
79
83
  try {
80
- await serverId.loadResourcesFromHUEBridge();
84
+ if (typeof serverId.loadResourcesFromHUEBridge === 'function') {
85
+ await serverId.loadResourcesFromHUEBridge();
86
+ }
81
87
  } catch (error) {
82
88
  RED.log.error(`Errore RED.httpAdmin.get('/knxultimateCheckHueConnected' ${error.stack}`);
83
89
  }
@@ -168,7 +168,7 @@
168
168
  <div id="waitWindow" hidden>
169
169
  <br/><br/>
170
170
  <p align="center">
171
- <i class="fa-solid fa-hourglass-start fa-spin-pulse fa-4x"></i><br/><br/>
171
+ <i class="fa-solid fa-hourglass-start fa-spin-pulse fa-2x"></i><br/><br/>
172
172
  <span data-i18n="hue-config.properties.wait_message"></span>
173
173
  </p>
174
174
  </div>
@@ -231,4 +231,4 @@
231
231
  </div>
232
232
 
233
233
 
234
- </script>
234
+ </script>
@@ -246,6 +246,9 @@ module.exports = (RED) => {
246
246
  let allResources;
247
247
  if (_rtype === "light" || _rtype === "grouped_light") {
248
248
  allResources = node.hueAllResources.filter((a) => a.type === "light" || a.type === "grouped_light");
249
+ } else if (_rtype === "plug") {
250
+ allResources = node.hueAllResources.filter((a) => a.type === "plug" || a.type === "smartplug" || a.type === "smart_plug");
251
+ console.log('getResources plug raw resources', allResources.map((res) => ({ id: res.id, type: res.type, owner: res.owner?.rtype })));
249
252
  } else {
250
253
  allResources = node.hueAllResources.filter((a) => a.type === _rtype);
251
254
  }
@@ -324,6 +327,19 @@ module.exports = (RED) => {
324
327
  id: resource.id,
325
328
  });
326
329
  }
330
+ if (_rtype === "plug") {
331
+ const linkedDevice = node.hueAllResources.find((dev) => dev.type === "device" && dev.services.find((serv) => serv.rid === resource.id));
332
+ const room = node.hueAllRooms?.find((roomItem) => roomItem.children?.find((child) => child.rid === linkedDevice?.id));
333
+ const plugName = linkedDevice?.metadata?.name || resource.metadata?.name || "Unnamed Plug";
334
+ const stateLabel = resource?.on?.on === true ? "on" : "off";
335
+ console.log('getResources plug direct resource', { id: resource.id, type: resource.type, name: plugName, linkedDevice: linkedDevice?.id });
336
+ retArray.push({
337
+ name: `Plug: ${plugName}${room !== undefined ? `, room ${room.metadata.name}` : ""} [${stateLabel}]`,
338
+ id: resource.id,
339
+ type: resource.type,
340
+ deviceObject: resource,
341
+ });
342
+ }
327
343
  if (_rtype === "temperature") {
328
344
  const Room = node.hueAllRooms.find((room) => room.children.find((child) => child.rid === resource.owner.rid));
329
345
  const linkedDevName = node.hueAllResources.find((dev) => dev.type === "device" && dev.services.find((serv) => serv.rid === resource.id)).metadata.name || "";
@@ -332,6 +348,14 @@ module.exports = (RED) => {
332
348
  id: resource.id,
333
349
  });
334
350
  }
351
+ if (_rtype === "humidity") {
352
+ const Room = node.hueAllRooms.find((room) => room.children.find((child) => child.rid === resource.owner.rid));
353
+ const linkedDevName = node.hueAllResources.find((dev) => dev.type === "device" && dev.services.find((serv) => serv.rid === resource.id)).metadata.name || "";
354
+ retArray.push({
355
+ name: `Humidity: ${linkedDevName}${Room !== undefined ? `, room ${Room.metadata.name}` : ""}`,
356
+ id: resource.id,
357
+ });
358
+ }
335
359
  if (_rtype === "device_power") {
336
360
  const Room = node.hueAllRooms.find((room) => room.children.find((child) => child.rid === resource.owner.rid));
337
361
  const linkedDevName = node.hueAllResources.find((dev) => dev.type === "device" && dev.services.find((serv) => serv.rid === resource.id)).metadata.name || "";
@@ -379,6 +403,38 @@ module.exports = (RED) => {
379
403
  });
380
404
  }
381
405
  }
406
+ if (_rtype === "plug" && retArray.length === 0) {
407
+ const plugDevices = node.hueAllResources.filter((dev) => {
408
+ if (dev.type !== "device" || !Array.isArray(dev.services)) return false;
409
+ const archetypePlug = dev.product_data?.product_archetype === 'plug' || dev.metadata?.archetype === 'plug' || /plug/i.test(dev.product_data?.product_name || '') || /plug/i.test(dev.metadata?.name || '');
410
+ const hasService = dev.services.some((serv) => ['plug', 'smartplug', 'smart_plug', 'light'].includes(serv.rtype || ''));
411
+ return archetypePlug && hasService;
412
+ });
413
+ plugDevices.forEach((device) => {
414
+ try {
415
+ const plugService = device.services.find((serv) => ['plug', 'smartplug', 'smart_plug', 'light'].includes(serv.rtype || ''));
416
+ if (!plugService) return;
417
+ const plugResource = node.hueAllResources.find((res) => res.id === plugService.rid) || {};
418
+ const room = node.hueAllRooms?.find((roomItem) => roomItem.children?.find((child) => child.rid === device.id));
419
+ const plugName = device.metadata?.name || plugResource.metadata?.name || "Unnamed Plug";
420
+ const stateLabel = plugResource?.on?.on === true ? "on" : (plugResource?.on?.on === false ? "off" : "");
421
+ retArray.push({
422
+ name: `Plug: ${plugName}${room !== undefined ? `, room ${room.metadata.name}` : ""}${stateLabel ? ` [${stateLabel}]` : ""}`,
423
+ id: plugService.rid || device.id,
424
+ type: plugService.rtype || plugResource.type || 'light',
425
+ deviceObject: plugResource.on ? plugResource : {
426
+ id: plugService.rid || device.id,
427
+ type: plugService.rtype || plugResource.type || 'light',
428
+ on: plugResource.on,
429
+ owner: { rid: device.id, rtype: 'device' },
430
+ },
431
+ });
432
+ } catch (err) {
433
+ node.sysLogger?.warn(`KNXUltimateHue: getResources plug fallback error ${err.message}`);
434
+ }
435
+ });
436
+ }
437
+ node.sysLogger?.debug(`getResources plug returning ${retArray.length}`);
382
438
  return { devices: retArray };
383
439
  } catch (error) {
384
440
  node.sysLogger?.error(`KNXUltimateHue: hueEngine: classHUE: getResources: error ${error.message}`);
@@ -28,7 +28,7 @@
28
28
  tunnelUserPassword: { value: "" },
29
29
  tunnelUserId: { value: "" },
30
30
  autoReconnect: { value: "yes" },
31
- statusDisplayPolicy: { value: "all" }
31
+ statusUpdateThrottle: { value: "0" }
32
32
  },
33
33
  credentials: {
34
34
  keyringFilePassword: { type: "password" }
@@ -1148,13 +1148,17 @@
1148
1148
  </div>
1149
1149
 
1150
1150
  <div class="form-row">
1151
- <label for="node-config-input-statusDisplayPolicy">
1152
- <i class="fa fa-eye"></i>
1153
- <span data-i18n="knxUltimate-config.advanced.status_display_policy"></span>
1151
+ <label for="node-config-input-statusUpdateThrottle">
1152
+ <i class="fa fa-clock-o"></i>
1153
+ <span data-i18n="knxUltimate-config.advanced.status_throttle"></span>
1154
1154
  </label>
1155
- <select id="node-config-input-statusDisplayPolicy" style="width:40%;">
1156
- <option value="all" data-i18n="knxUltimate-config.advanced.status_display_all"></option>
1157
- <option value="errors" data-i18n="knxUltimate-config.advanced.status_display_errors"></option>
1155
+ <select id="node-config-input-statusUpdateThrottle" style="width:40%;">
1156
+ <option value="0" data-i18n="knxUltimate-config.advanced.status_throttle_none"></option>
1157
+ <option value="1" data-i18n="knxUltimate-config.advanced.status_throttle_1s"></option>
1158
+ <option value="3" data-i18n="knxUltimate-config.advanced.status_throttle_3s"></option>
1159
+ <option value="5" data-i18n="knxUltimate-config.advanced.status_throttle_5s"></option>
1160
+ <option value="10" data-i18n="knxUltimate-config.advanced.status_throttle_10s"></option>
1161
+ <option value="30" data-i18n="knxUltimate-config.advanced.status_throttle_30s"></option>
1158
1162
  </select>
1159
1163
  </div>
1160
1164
  </p>
@@ -24,8 +24,6 @@ const loggerClass = require('./utils/sysLogger')
24
24
  const payloadRounder = require("./utils/payloadManipulation");
25
25
  const utils = require('./utils/utils');
26
26
 
27
- const STATUS_DISPLAY_ALLOWED_COLORS = new Set(['red', 'yellow']);
28
-
29
27
  // DATAPONT MANIPULATION HELPERS
30
28
  // ####################
31
29
  const sortBy = (field) => (a, b) => {
@@ -220,12 +218,39 @@ module.exports = (RED) => {
220
218
  node.autoReconnect = true;
221
219
  }
222
220
  node.ignoreTelegramsWithRepeatedFlag = config.ignoreTelegramsWithRepeatedFlag === undefined ? false : config.ignoreTelegramsWithRepeatedFlag;
223
- const policyFromConfig = typeof config.statusDisplayPolicy === "string" ? config.statusDisplayPolicy : "all";
224
- node.statusDisplayPolicy = ['all', 'errors'].includes(policyFromConfig) ? policyFromConfig : "all";
225
- node.shouldDisplayStatus = (fill) => {
226
- if (node.statusDisplayPolicy !== 'errors') return true;
227
- const normalizedFill = (typeof fill === 'string' ? fill : '').toLowerCase();
228
- return STATUS_DISPLAY_ALLOWED_COLORS.has(normalizedFill);
221
+ const throttleSecondsRaw = Number(config.statusUpdateThrottle);
222
+ node.statusUpdateThrottleMs = Number.isFinite(throttleSecondsRaw) && throttleSecondsRaw > 0
223
+ ? throttleSecondsRaw * 1000
224
+ : 0;
225
+ node.applyStatusUpdate = (targetNode, status) => {
226
+ try {
227
+ if (!targetNode || typeof targetNode.status !== 'function') return;
228
+ const throttle = node.statusUpdateThrottleMs;
229
+ if (!throttle) {
230
+ targetNode.status(status);
231
+ return;
232
+ }
233
+ if (!targetNode.__knxStatusThrottle) {
234
+ targetNode.__knxStatusThrottle = { pending: undefined, timer: null };
235
+ }
236
+ const tracker = targetNode.__knxStatusThrottle;
237
+ tracker.pending = status;
238
+ if (tracker.timer) return;
239
+ tracker.timer = setTimeout(() => {
240
+ try {
241
+ if (tracker.pending !== undefined) {
242
+ targetNode.status(tracker.pending);
243
+ }
244
+ } catch (timerError) {
245
+ node.sysLogger?.warn('Unable to apply throttled status: ' + timerError.message);
246
+ } finally {
247
+ tracker.pending = undefined;
248
+ tracker.timer = null;
249
+ }
250
+ }, throttle);
251
+ } catch (error) {
252
+ node.sysLogger?.warn('applyStatusUpdate error: ' + error.message);
253
+ }
229
254
  };
230
255
  // 24/07/2021 KNX Secure checks...
231
256
  node.keyringFileXML = typeof config.keyringFileXML === "undefined" || config.keyringFileXML.trim() === "" ? "" : config.keyringFileXML;
@@ -161,16 +161,97 @@
161
161
  })
162
162
  }
163
163
 
164
+ const applyEditorOptions = (editor) => {
165
+ try {
166
+ if (!editor) return;
167
+ if (typeof editor.updateOptions === 'function') {
168
+ editor.updateOptions({ lineNumbers: 'off', minimap: { enabled: false }, scrollbar: { verticalScrollbarSize: 8, horizontalScrollbarSize: 8 } });
169
+ } else if (editor.renderer && typeof editor.renderer.setShowGutter === 'function') {
170
+ editor.renderer.setShowGutter(false);
171
+ }
172
+ if (typeof editor.setShowPrintMargin === 'function') editor.setShowPrintMargin(false);
173
+ } catch (error) { }
174
+ };
175
+
176
+ const highlightEditor = (editor, active) => {
177
+ if (!editor) return;
178
+ try {
179
+ if (editor.renderer && editor.renderer.scroller) {
180
+ editor.renderer.scroller.style.backgroundColor = active ? '#e6ffe6' : '';
181
+ }
182
+ if (editor.renderer && editor.renderer.content) {
183
+ editor.renderer.content.style.backgroundColor = active ? '#e6ffe6' : '';
184
+ }
185
+ if (typeof editor.getDomNode === 'function') {
186
+ const dom = editor.getDomNode();
187
+ if (dom) dom.style.backgroundColor = active ? '#e6ffe6' : '';
188
+ } else if (editor.container) {
189
+ editor.container.style.backgroundColor = active ? '#e6ffe6' : '';
190
+ }
191
+ } catch (error) { }
192
+ };
193
+
194
+ const attachFocusHandlers = (editor) => {
195
+ if (!editor) return;
196
+ try {
197
+ if (typeof editor.on === 'function' && editor.renderer) {
198
+ editor.on('focus', () => { node.activeCodeEditor = editor; highlightEditor(editor, true); });
199
+ editor.on('blur', () => highlightEditor(editor, false));
200
+ } else if (typeof editor.onDidFocusEditorWidget === 'function') {
201
+ editor.onDidFocusEditorWidget(() => { node.activeCodeEditor = editor; highlightEditor(editor, true); });
202
+ if (typeof editor.onDidBlurEditorWidget === 'function') {
203
+ editor.onDidBlurEditorWidget(() => highlightEditor(editor, false));
204
+ }
205
+ }
206
+ } catch (error) { }
207
+ };
208
+
209
+ const insertTextIntoEditor = (editor, text) => {
210
+ if (!editor || !text) return;
211
+ try {
212
+ if (editor.session && typeof editor.session.insert === 'function') {
213
+ editor.focus();
214
+ editor.session.insert(editor.getCursorPosition(), text);
215
+ return;
216
+ }
217
+ if (typeof editor.executeEdits === 'function' && typeof editor.getPosition === 'function' && typeof monaco !== 'undefined') {
218
+ const position = editor.getPosition();
219
+ if (!position) return;
220
+ const range = new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column);
221
+ editor.executeEdits('knxInsertGA', [{ range, text, forceMoveMarkers: true }]);
222
+ editor.setPosition({ lineNumber: position.lineNumber, column: position.column + text.length });
223
+ editor.focus();
224
+ }
225
+ } catch (error) { }
226
+ };
227
+
164
228
  node.sendMsgToKNXCodeEditor = RED.editor.createEditor({
165
229
  id: 'sendMsgToKNXCode-editor',
166
230
  mode: 'ace/mode/nrjavascript',
167
231
  value: node.sendMsgToKNXCode
168
232
  });
233
+ applyEditorOptions(node.sendMsgToKNXCodeEditor);
169
234
  node.receiveMsgFromKNXCodeEditor = RED.editor.createEditor({
170
235
  id: 'receiveMsgFromKNXCode-editor',
171
236
  mode: 'ace/mode/nrjavascript',
172
237
  value: node.receiveMsgFromKNXCode
173
238
  });
239
+ applyEditorOptions(node.receiveMsgFromKNXCodeEditor);
240
+ node.activeCodeEditor = null;
241
+ attachFocusHandlers(node.sendMsgToKNXCodeEditor);
242
+ attachFocusHandlers(node.receiveMsgFromKNXCodeEditor);
243
+
244
+ $("#btn-insert-knxFunctionGA").off('click').on('click', function () {
245
+ const value = $("#node-input-knxFunctionHelperGAList").val();
246
+ if (!value || value.trim() === '') {
247
+ $("#node-input-knxFunctionHelperGAList").focus();
248
+ return;
249
+ }
250
+ const editor = node.activeCodeEditor || node.sendMsgToKNXCodeEditor || node.receiveMsgFromKNXCodeEditor;
251
+ if (!editor) return;
252
+ insertTextIntoEditor(editor, value);
253
+ });
254
+
174
255
  const configureSnippetPicker = (snippets, inputSelector, datalistSelector, applySnippet) => {
175
256
  const inputEl = $(inputSelector)
176
257
  const datalistEl = $(datalistSelector)
@@ -718,7 +799,7 @@
718
799
  <i class="fa fa-tag"></i>
719
800
  <span data-i18n="knxUltimate.properties.node-input-name"></span>
720
801
  </label>
721
- <input style="width:220px;" type="text" id="node-input-name"
802
+ <input style="flex:1 1 240px; min-width:240px; max-width:240px;" type="text" id="node-input-name"
722
803
  data-i18n="[placeholder]knxUltimate.properties.node-input-name" />
723
804
  </div>
724
805
  <div class="form-row" id="divTopic">
@@ -897,7 +978,11 @@
897
978
  <i class="fa fa-search"></i> <span data-i18n="knxUltimate.snippets.searchGA"></span>
898
979
  </label>
899
980
  <input type="text" id="node-input-knxFunctionHelperGAList"
900
- data-i18n="[placeholder]knxUltimate.placeholder.search" />
981
+ data-i18n="[placeholder]knxUltimate.placeholder.search" style="max-width:260px;" />
982
+ <button type="button" class="red-ui-button" id="btn-insert-knxFunctionGA" title="Insert"
983
+ style="margin-left:4px;">
984
+ <i class="fa fa-level-down"></i>
985
+ </button>
901
986
  </div>
902
987
 
903
988
 
@@ -11,8 +11,17 @@ module.exports = function (RED) {
11
11
  RED.nodes.createNode(this, config);
12
12
  const node = this;
13
13
  node.serverKNX = RED.nodes.getNode(config.server) || undefined;
14
+ const pushStatus = (status) => {
15
+ const provider = node.serverKNX;
16
+ if (provider && typeof provider.applyStatusUpdate === 'function') {
17
+ provider.applyStatusUpdate(node, status);
18
+ } else {
19
+ node.status(status);
20
+ }
21
+ };
22
+
14
23
  if (node.serverKNX === undefined) {
15
- node.status({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
24
+ pushStatus({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
16
25
  return;
17
26
  }
18
27
 
@@ -22,7 +31,7 @@ module.exports = function (RED) {
22
31
  fill, shape, text, payload, GA, dpt, devicename,
23
32
  }) => {
24
33
  try {
25
- if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
34
+ if (node.serverKNX === null) { pushStatus({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
26
35
  if (node.icountMessageInWindow == -999) return; // Locked out, doesn't change status.
27
36
  const dDate = new Date();
28
37
  // 30/08/2019 Display only the things selected in the config
@@ -31,12 +40,7 @@ module.exports = function (RED) {
31
40
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ` DPT${dpt}`;
32
41
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload;
33
42
  const statusText = `${GA + payload + (node.listenallga === true ? ` ${devicename}` : '')} (day ${dDate.getDate()}, ${dDate.toLocaleTimeString()}) ${text}`;
34
- const shouldUpdateStatus = (node.serverKNX && typeof node.serverKNX.shouldDisplayStatus === 'function')
35
- ? node.serverKNX.shouldDisplayStatus(fill)
36
- : true;
37
- if (shouldUpdateStatus) {
38
- node.status({ fill, shape, text: statusText });
39
- }
43
+ pushStatus({ fill, shape, text: statusText });
40
44
  // 16/02/2020 signal errors to the server
41
45
  if (fill.toUpperCase() === 'RED') {
42
46
  if (node.serverKNX) {
@@ -119,8 +119,11 @@
119
119
  }
120
120
 
121
121
  }
122
- }).focus(function () {
123
- $(this).autocomplete('search', $(this).val() + 'exactmatch');
122
+ });
123
+ oTopicField.on('focus.knxUltimateAlerter click.knxUltimateAlerter', function () {
124
+ try {
125
+ $(this).autocomplete('search', '');
126
+ } catch (error) { /* empty */ }
124
127
  });
125
128
  try { if (oNodeServer && oNodeServer.id) KNX_enableSecureFormatting(oTopicField, oNodeServer.id); } catch (e) {}
126
129
 
@@ -202,7 +205,7 @@
202
205
 
203
206
  <div class="form-row">
204
207
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="knxUltimateAlerter.properties.node-input-name"></span> </label>
205
- <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateAlerter.properties.node-input-name">
208
+ <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateAlerter.properties.node-input-name" style="flex:1 1 240px; min-width:240px; max-width:240px;">
206
209
  </div>
207
210
 
208
211
  <div class="form-row">
@@ -242,5 +245,3 @@
242
245
  </div>
243
246
 
244
247
  </script>
245
-
246
-
@@ -11,8 +11,18 @@ module.exports = function (RED) {
11
11
  RED.nodes.createNode(this, config);
12
12
  const node = this;
13
13
  node.serverKNX = RED.nodes.getNode(config.server) || undefined;
14
+ const pushStatus = (status) => {
15
+ if (status === undefined || status === null) return;
16
+ const provider = node.serverKNX;
17
+ if (provider && typeof provider.applyStatusUpdate === 'function') {
18
+ provider.applyStatusUpdate(node, status);
19
+ } else {
20
+ node.status(status);
21
+ }
22
+ };
23
+
14
24
  if (node.serverKNX === undefined) {
15
- node.status({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
25
+ pushStatus({ fill: 'red', shape: 'dot', text: '[THE GATEWAY NODE HAS BEEN DISABLED]' });
16
26
  return;
17
27
  }
18
28
  node.name = config.name || 'KNX Alerter';
@@ -33,14 +43,6 @@ module.exports = function (RED) {
33
43
  node.whentostart = config.whentostart === undefined ? 'ifnewalert' : config.whentostart;
34
44
  node.timerinterval = (config.timerinterval === undefined || config.timerinterval == '') ? '2' : config.timerinterval;
35
45
 
36
- const shouldDisplayStatus = (color) => {
37
- const provider = node.serverKNX;
38
- if (provider && typeof provider.shouldDisplayStatus === 'function') {
39
- return provider.shouldDisplayStatus(color);
40
- }
41
- return true;
42
- };
43
-
44
46
  if (config.initialreadGAInRules === undefined) {
45
47
  node.initialread = 1;
46
48
  } else {
@@ -61,9 +63,7 @@ module.exports = function (RED) {
61
63
  devicename = devicename || '';
62
64
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt;
63
65
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload;
64
- if (shouldDisplayStatus(fill)) {
65
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
66
- }
66
+ pushStatus({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
67
67
  } catch (error) {
68
68
  }
69
69
  };
@@ -76,9 +76,7 @@ module.exports = function (RED) {
76
76
  devicename = devicename || '';
77
77
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt;
78
78
  try {
79
- if (shouldDisplayStatus(fill)) {
80
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
81
- }
79
+ pushStatus({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
82
80
  } catch (error) {
83
81
  }
84
82
  };
@@ -87,7 +87,7 @@
87
87
  <label for="node-input-name" >
88
88
  <i class="fa fa-tag"></i> Name
89
89
  </label>
90
- <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateAutoResponder.node-input-name" />
90
+ <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateAutoResponder.node-input-name" style="flex:1 1 240px; min-width:240px; max-width:240px;" />
91
91
  </div>
92
92
 
93
93
  <div class="form-row">
@@ -97,4 +97,3 @@
97
97
 
98
98
  </script>
99
99
 
100
-
@@ -52,19 +52,19 @@ module.exports = function (RED) {
52
52
  node.commandText = []; // Raw list Respond To
53
53
  node.timerSaveExposedGAs = null;
54
54
 
55
- const shouldDisplayStatus = (color) => {
55
+ const pushStatus = (status) => {
56
+ if (!status) return;
56
57
  const provider = node.serverKNX;
57
- if (provider && typeof provider.shouldDisplayStatus === 'function') {
58
- return provider.shouldDisplayStatus(color);
58
+ if (provider && typeof provider.applyStatusUpdate === 'function') {
59
+ provider.applyStatusUpdate(node, status);
60
+ } else {
61
+ node.status(status);
59
62
  }
60
- return true;
61
63
  };
62
64
 
63
65
  const updateStatus = (status) => {
64
66
  if (!status) return;
65
- if (shouldDisplayStatus(status.fill)) {
66
- node.status(status);
67
- }
67
+ pushStatus(status);
68
68
  };
69
69
  if (node.serverKNX === null) { updateStatus({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
70
70
 
@@ -86,7 +86,7 @@
86
86
  <i class="fa fa-tag"></i>
87
87
  <span data-i18n="knxUltimateGlobalContext.node-input-name"></span>
88
88
  </label>
89
- <input style="width:35%;" type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateGlobalContext.node-input-name" />
89
+ <input style="flex:1 1 240px; min-width:240px; max-width:240px;" type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateGlobalContext.node-input-name" />
90
90
  </div>
91
91
 
92
92
  <div class="form-row">
@@ -123,4 +123,3 @@
123
123
  </div>
124
124
 
125
125
  </script>
126
-
@@ -57,19 +57,19 @@ module.exports = function (RED) {
57
57
  node.exposedGAs = []
58
58
  node.timerExposedGAs = null
59
59
 
60
- const shouldDisplayStatus = (color) => {
60
+ const pushStatus = (status) => {
61
+ if (!status) return;
61
62
  const provider = node.serverKNX;
62
- if (provider && typeof provider.shouldDisplayStatus === 'function') {
63
- return provider.shouldDisplayStatus(color);
63
+ if (provider && typeof provider.applyStatusUpdate === 'function') {
64
+ provider.applyStatusUpdate(node, status);
65
+ } else {
66
+ node.status(status);
64
67
  }
65
- return true;
66
68
  };
67
69
 
68
70
  const updateStatus = (status) => {
69
71
  if (!status) return;
70
- if (shouldDisplayStatus(status.fill)) {
71
- node.status(status);
72
- }
72
+ pushStatus(status);
73
73
  };
74
74
 
75
75
  // Used to call the status update from the config node.