node-red-contrib-knx-ultimate 4.0.9 → 4.0.11

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 (400) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +3 -4
  3. package/nodes/hue-config.html +2 -2
  4. package/nodes/hue-config.js +56 -0
  5. package/nodes/knxUltimate-config.html +13 -1
  6. package/nodes/knxUltimate-config.js +9 -0
  7. package/nodes/knxUltimate.html +87 -2
  8. package/nodes/knxUltimate.js +7 -1
  9. package/nodes/knxUltimateAlerter.html +6 -5
  10. package/nodes/knxUltimateAlerter.js +14 -2
  11. package/nodes/knxUltimateAutoResponder.html +1 -2
  12. package/nodes/knxUltimateAutoResponder.js +24 -9
  13. package/nodes/knxUltimateGlobalContext.html +1 -2
  14. package/nodes/knxUltimateGlobalContext.js +18 -3
  15. package/nodes/knxUltimateHueBattery.html +549 -222
  16. package/nodes/knxUltimateHueBattery.js +49 -10
  17. package/nodes/knxUltimateHueButton.html +688 -452
  18. package/nodes/knxUltimateHueButton.js +48 -19
  19. package/nodes/knxUltimateHueCameraMotion.html +631 -0
  20. package/nodes/knxUltimateHueCameraMotion.js +215 -0
  21. package/nodes/knxUltimateHueContactSensor.html +512 -212
  22. package/nodes/knxUltimateHueContactSensor.js +38 -7
  23. package/nodes/knxUltimateHueHumiditySensor.html +601 -0
  24. package/nodes/knxUltimateHueHumiditySensor.js +198 -0
  25. package/nodes/knxUltimateHueLight.html +788 -199
  26. package/nodes/knxUltimateHueLight.js +327 -71
  27. package/nodes/knxUltimateHueLightSensor.html +538 -224
  28. package/nodes/knxUltimateHueLightSensor.js +42 -8
  29. package/nodes/knxUltimateHueMotion.html +536 -215
  30. package/nodes/knxUltimateHueMotion.js +45 -7
  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 +37 -10
  35. package/nodes/knxUltimateHueTapDial.html +543 -217
  36. package/nodes/knxUltimateHueTapDial.js +89 -29
  37. package/nodes/knxUltimateHueTemperatureSensor.html +541 -222
  38. package/nodes/knxUltimateHueTemperatureSensor.js +52 -13
  39. package/nodes/knxUltimateHueZigbeeConnectivity.html +549 -222
  40. package/nodes/knxUltimateHueZigbeeConnectivity.js +49 -10
  41. package/nodes/knxUltimateHuedevice_software_update.html +554 -222
  42. package/nodes/knxUltimateHuedevice_software_update.js +50 -9
  43. package/nodes/knxUltimateLoadControl.html +17 -6
  44. package/nodes/knxUltimateLoadControl.js +18 -3
  45. package/nodes/knxUltimateLogger.html +1 -2
  46. package/nodes/knxUltimateLogger.js +17 -2
  47. package/nodes/knxUltimateSceneController.html +7 -4
  48. package/nodes/knxUltimateSceneController.js +17 -2
  49. package/nodes/knxUltimateViewer.html +1 -2
  50. package/nodes/knxUltimateViewer.js +18 -3
  51. package/nodes/knxUltimateWatchDog.html +1 -1
  52. package/nodes/knxUltimateWatchDog.js +17 -2
  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 -32
  95. package/nodes/locales/{en-US → en}/knxUltimate-config.json +3 -0
  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 +104 -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 +104 -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 -28
  243. package/nodes/locales/it/knxUltimate-config.json +3 -0
  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 +6 -3
  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/hue-config-teleprompter.txt +43 -43
  336. package/tutorial/knxUltimate-config-teleprompter.txt +74 -74
  337. package/tutorial/knxUltimate-teleprompter.txt +60 -60
  338. package/tutorial/knxUltimateAlerter-teleprompter.txt +48 -48
  339. package/tutorial/knxUltimateAutoResponder-teleprompter.txt +43 -43
  340. package/tutorial/knxUltimateGlobalContext-teleprompter.txt +44 -44
  341. package/tutorial/knxUltimateHATranslator-teleprompter.txt +45 -45
  342. package/tutorial/knxUltimateHueBattery-teleprompter.txt +38 -38
  343. package/tutorial/knxUltimateHueButton-teleprompter.txt +45 -45
  344. package/tutorial/knxUltimateHueContactSensor-teleprompter.txt +28 -28
  345. package/tutorial/knxUltimateHueLight-teleprompter.txt +50 -50
  346. package/tutorial/knxUltimateHueLightSensor-teleprompter.txt +42 -42
  347. package/tutorial/knxUltimateHueMotion-teleprompter.txt +39 -39
  348. package/tutorial/knxUltimateHueScene-teleprompter.txt +45 -45
  349. package/tutorial/knxUltimateHueTapDial-teleprompter.txt +40 -40
  350. package/tutorial/knxUltimateHueTemperatureSensor-teleprompter.txt +42 -42
  351. package/tutorial/knxUltimateHueZigbeeConnectivity-teleprompter.txt +41 -41
  352. package/tutorial/knxUltimateHuedevice_software_update-teleprompter.txt +42 -42
  353. package/tutorial/knxUltimateLoadControl-teleprompter.txt +40 -40
  354. package/tutorial/knxUltimateLogger-teleprompter.txt +39 -39
  355. package/tutorial/knxUltimateSceneController-teleprompter.txt +38 -38
  356. package/tutorial/knxUltimateViewer-teleprompter.txt +30 -30
  357. package/tutorial/knxUltimateWatchDog-teleprompter.txt +39 -39
  358. package/nodes/locales/de-DE/knxUltimateGarageDoorBarrierOpener.html +0 -63
  359. package/nodes/locales/de-DE/knxUltimateHueBattery.html +0 -18
  360. package/nodes/locales/de-DE/knxUltimateHueButton.html +0 -37
  361. package/nodes/locales/de-DE/knxUltimateHueMotion.html +0 -26
  362. package/nodes/locales/de-DE/knxUltimateHueScene.html +0 -44
  363. package/nodes/locales/de-DE/knxUltimateHueTapDial.html +0 -30
  364. package/nodes/locales/en-US/knxUltimateGarageDoorBarrierOpener.html +0 -63
  365. package/nodes/locales/en-US/knxUltimateHueBattery.html +0 -18
  366. package/nodes/locales/en-US/knxUltimateHueBattery.json +0 -18
  367. package/nodes/locales/en-US/knxUltimateHueButton.html +0 -37
  368. package/nodes/locales/en-US/knxUltimateHueButton.json +0 -15
  369. package/nodes/locales/en-US/knxUltimateHueContactSensor.json +0 -15
  370. package/nodes/locales/en-US/knxUltimateHueLight.html +0 -102
  371. package/nodes/locales/en-US/knxUltimateHueMotion.html +0 -26
  372. package/nodes/locales/en-US/knxUltimateHueMotion.json +0 -16
  373. package/nodes/locales/en-US/knxUltimateHueScene.html +0 -44
  374. package/nodes/locales/en-US/knxUltimateHueScene.json +0 -28
  375. package/nodes/locales/en-US/knxUltimateHueTapDial.html +0 -30
  376. package/nodes/locales/en-US/knxUltimateHueTapDial.json +0 -16
  377. package/nodes/locales/en-US/knxUltimateHueTemperatureSensor.json +0 -18
  378. package/nodes/locales/en-US/knxUltimateHueZigbeeConnectivity.json +0 -18
  379. package/nodes/locales/en-US/knxUltimateHuedevice_software_update.json +0 -18
  380. package/nodes/locales/it-IT/knxUltimateGarageDoorBarrierOpener.html +0 -63
  381. package/nodes/locales/it-IT/knxUltimateHueBattery.html +0 -18
  382. package/nodes/locales/it-IT/knxUltimateHueButton.html +0 -36
  383. package/nodes/locales/it-IT/knxUltimateHueMotion.html +0 -26
  384. package/nodes/locales/it-IT/knxUltimateHueScene.html +0 -44
  385. package/nodes/locales/it-IT/knxUltimateHueTapDial.html +0 -30
  386. /package/nodes/locales/{en-US → en}/common.json +0 -0
  387. /package/nodes/locales/{en-US → en}/hue-config.json +0 -0
  388. /package/nodes/locales/{en-US → en}/knxUltimate.json +0 -0
  389. /package/nodes/locales/{en-US → en}/knxUltimateAlerter.json +0 -0
  390. /package/nodes/locales/{en-US → en}/knxUltimateAutoResponder.json +0 -0
  391. /package/nodes/locales/{en-US → en}/knxUltimateGarageDoorBarrierOpener.json +0 -0
  392. /package/nodes/locales/{en-US → en}/knxUltimateGlobalContext.json +0 -0
  393. /package/nodes/locales/{en-US → en}/knxUltimateHATranslator.json +0 -0
  394. /package/nodes/locales/{en-US → en}/knxUltimateHueContactSensor.html +0 -0
  395. /package/nodes/locales/{en-US → en}/knxUltimateHueLightSensor.json +0 -0
  396. /package/nodes/locales/{en-US → en}/knxUltimateLoadControl.json +0 -0
  397. /package/nodes/locales/{en-US → en}/knxUltimateLogger.json +0 -0
  398. /package/nodes/locales/{en-US → en}/knxUltimateSceneController.json +0 -0
  399. /package/nodes/locales/{en-US → en}/knxUltimateViewer.json +0 -0
  400. /package/nodes/locales/{en-US → en}/knxUltimateWatchDog.json +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,23 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 4.0.11** - October 2025<br/>
10
+ - 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/>
11
+ - HUE Contact Sensor node: placeholders now leverage i18n translations with graceful fallback when translation keys are missing.<br/>
12
+ - Editor polish: unified the default width of the `name` input across KNX and Hue nodes for a consistent layout.<br/>
13
+ - 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/>
14
+ - Docs: audited external links; Hue API references require developer login but all other anchors resolve correctly.<br/>
15
+ - HUE Light node: added configuration UI and runtime support for Hue lamp dynamic effects (candle, fireplace, etc.) with KNX mappings and status feedback.<br/>
16
+ - NEW: Added Hue Plug/Outlet node to map KNX on/off control to Philips Hue smart plugs.<br/>
17
+ - NEW: Added Hue Humidity Sensor node to expose relative humidity readings from Hue bridges to KNX.<br/>
18
+ - NEW: Added Hue Camera Motion node to forward Hue camera motion detections to KNX, with optional flow output pins.<br/>
19
+ - Hue Button node: refreshed editor layout and switched to Hue `button.button_report.event` instead of the deprecated `last_event`.<br/>
20
+ - 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/>
21
+ - Docs: cleaned bold markdown spacing across KNX Ultimate help translations to avoid rendering glitches.<br/>
22
+
23
+ **Version 4.0.10** - October 2025<br/>
24
+ - KNX Config node: you can now choose wether to display only the errors in the node statuses only errors.<br/>
25
+
9
26
  **Version 4.0.9** - September 2025<br/>
10
27
  - KNX Config node: now the ethernet interface is automatically selected, based on the KNX Gateway's IP subnet.<br/>
11
28
  - Added the details of keyring in clear text, when the loglevel is set to "debug".<br/>
@@ -1958,4 +1975,3 @@ This is an interim version, to quick fix some issues. Please report any issue wi
1958
1975
 
1959
1976
  **Version 0.0.1 BETA**<br/>
1960
1977
  - Initial release<br/>
1961
-
package/README.md CHANGED
@@ -15,10 +15,11 @@
15
15
 
16
16
  <p align='center'>
17
17
  <img width="110px" src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/KNX_CERTI_MARK_RGB.jpg" ></br>
18
- <span style="font-size:0.7em;color:grey;">Authorized KNX logo by KNX Association*</span></br></br>
18
+ <span style="font-size:0.7em;color:grey;">Authorized KNX logo by KNX Association*</span>
19
+ </p>
20
+ <p align='center'>
19
21
  <img width="110px" src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/knxsecure.png" ></br>
20
22
  </p>
21
-
22
23
  </br>
23
24
 
24
25
 
@@ -28,8 +29,6 @@
28
29
  for providing me with KNX Secure stuffs to test with.</center>
29
30
  </p>
30
31
 
31
-
32
- </br>
33
32
  </br>
34
33
  </br>
35
34
 
@@ -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}`);
@@ -27,7 +27,8 @@
27
27
  tunnelInterfaceIndividualAddress: { value: "" },
28
28
  tunnelUserPassword: { value: "" },
29
29
  tunnelUserId: { value: "" },
30
- autoReconnect: { value: "yes" }
30
+ autoReconnect: { value: "yes" },
31
+ statusDisplayPolicy: { value: "all" }
31
32
  },
32
33
  credentials: {
33
34
  keyringFilePassword: { type: "password" }
@@ -1145,6 +1146,17 @@
1145
1146
  <!-- <// DEBUG LEVELS: success < debug < info < warn < error < disable
1146
1147
  </div> -->
1147
1148
  </div>
1149
+
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>
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>
1158
+ </select>
1159
+ </div>
1148
1160
  </p>
1149
1161
  </div>
1150
1162
  <div id="tabs-3">
@@ -24,6 +24,8 @@ 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
+
27
29
  // DATAPONT MANIPULATION HELPERS
28
30
  // ####################
29
31
  const sortBy = (field) => (a, b) => {
@@ -218,6 +220,13 @@ module.exports = (RED) => {
218
220
  node.autoReconnect = true;
219
221
  }
220
222
  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);
229
+ };
221
230
  // 24/07/2021 KNX Secure checks...
222
231
  node.keyringFileXML = typeof config.keyringFileXML === "undefined" || config.keyringFileXML.trim() === "" ? "" : config.keyringFileXML;
223
232
  node.knxSecureSelected = typeof config.knxSecureSelected === "undefined" ? false : config.knxSecureSelected;
@@ -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
 
@@ -30,7 +30,13 @@ module.exports = function (RED) {
30
30
  devicename = devicename || '';
31
31
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ` DPT${dpt}`;
32
32
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload;
33
- node.status({ fill, shape, text: `${GA + payload + (node.listenallga === true ? ` ${devicename}` : '')} (day ${dDate.getDate()}, ${dDate.toLocaleTimeString()}) ${text}` });
33
+ 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
+ }
34
40
  // 16/02/2020 signal errors to the server
35
41
  if (fill.toUpperCase() === 'RED') {
36
42
  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
-
@@ -33,6 +33,14 @@ module.exports = function (RED) {
33
33
  node.whentostart = config.whentostart === undefined ? 'ifnewalert' : config.whentostart;
34
34
  node.timerinterval = (config.timerinterval === undefined || config.timerinterval == '') ? '2' : config.timerinterval;
35
35
 
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
+
36
44
  if (config.initialreadGAInRules === undefined) {
37
45
  node.initialread = 1;
38
46
  } else {
@@ -53,7 +61,9 @@ module.exports = function (RED) {
53
61
  devicename = devicename || '';
54
62
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt;
55
63
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload;
56
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
64
+ if (shouldDisplayStatus(fill)) {
65
+ node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
66
+ }
57
67
  } catch (error) {
58
68
  }
59
69
  };
@@ -66,7 +76,9 @@ module.exports = function (RED) {
66
76
  devicename = devicename || '';
67
77
  dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt;
68
78
  try {
69
- node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
79
+ if (shouldDisplayStatus(fill)) {
80
+ node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text });
81
+ }
70
82
  } catch (error) {
71
83
  }
72
84
  };
@@ -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
-
@@ -51,7 +51,22 @@ module.exports = function (RED) {
51
51
  node.exposedGAs = [];
52
52
  node.commandText = []; // Raw list Respond To
53
53
  node.timerSaveExposedGAs = null;
54
- if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
54
+
55
+ const shouldDisplayStatus = (color) => {
56
+ const provider = node.serverKNX;
57
+ if (provider && typeof provider.shouldDisplayStatus === 'function') {
58
+ return provider.shouldDisplayStatus(color);
59
+ }
60
+ return true;
61
+ };
62
+
63
+ const updateStatus = (status) => {
64
+ if (!status) return;
65
+ if (shouldDisplayStatus(status.fill)) {
66
+ node.status(status);
67
+ }
68
+ };
69
+ if (node.serverKNX === null) { updateStatus({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return; }
55
70
 
56
71
  try {
57
72
  const baseLogLevel = (node.serverKNX && node.serverKNX.loglevel) ? node.serverKNX.loglevel : 'error';
@@ -109,7 +124,7 @@ module.exports = function (RED) {
109
124
 
110
125
  // Add the ETS CSV file list to exposedGAs
111
126
  if (node.serverKNX.csv === undefined || node.serverKNX.csv === '' || node.serverKNX.csv.length === 0) {
112
- node.status({ fill: 'grey', shape: 'ring', text: 'No ETS file imported', payload: '', dpt: '', devicename: '' });
127
+ updateStatus({ fill: 'grey', shape: 'ring', text: 'No ETS file imported', payload: '', dpt: '', devicename: '' });
113
128
  //return;
114
129
  } else {
115
130
  node.serverKNX.csv.forEach(element => {
@@ -120,14 +135,14 @@ module.exports = function (RED) {
120
135
  curGa.enabled = false;
121
136
  }
122
137
  })
123
- node.status({ fill: 'green', shape: 'ring', text: 'ETS file loaded', payload: '', dpt: '', devicename: '' });
138
+ updateStatus({ fill: 'green', shape: 'ring', text: 'ETS file loaded', payload: '', dpt: '', devicename: '' });
124
139
  }
125
140
 
126
141
  // Fill the filter list
127
142
  try {
128
143
  node.commandText = JSON.parse(config.commandText);
129
144
  } catch (error) {
130
- node.status({ fill: 'red', shape: 'dot', text: 'JSON error: ' + error.message, payload: '', dpt: '', devicename: '' });
145
+ updateStatus({ fill: 'red', shape: 'dot', text: 'JSON error: ' + error.message, payload: '', dpt: '', devicename: '' });
131
146
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: node.commandText = JSON.parse(config.commandText) ${error.stack}`);
132
147
  return;
133
148
  }
@@ -164,10 +179,10 @@ module.exports = function (RED) {
164
179
  // Delete all not wanted GAs, that aren't in the node.commandText directive list.
165
180
  node.exposedGAs = node.exposedGAs.filter(a => (a.enabled !== undefined && a.enabled === true));
166
181
 
167
- node.status({ fill: 'green', shape: 'ring', text: 'JSON parsed: ' + node.commandText.length + " directive(s).", payload: '', dpt: '', devicename: '' });
182
+ updateStatus({ fill: 'green', shape: 'ring', text: 'JSON parsed: ' + node.commandText.length + " directive(s).", payload: '', dpt: '', devicename: '' });
168
183
  } else {
169
184
  // Error
170
- node.status({ fill: 'red', shape: 'dot', text: 'JSON error: ga or default keys not set. Abort.', payload: '', dpt: '', devicename: '' });
185
+ updateStatus({ fill: 'red', shape: 'dot', text: 'JSON error: ga or default keys not set. Abort.', payload: '', dpt: '', devicename: '' });
171
186
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: node.commandText.forEach(element.. JSON error: ga or default keys not set. Abort.`);
172
187
  return;
173
188
  }
@@ -191,7 +206,7 @@ module.exports = function (RED) {
191
206
  // Take only RAW data and decode it with the dpt specified by the commandText directive
192
207
  decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(oGa.dpt));
193
208
  } catch (error) {
194
- node.status({ fill: 'red', shape: 'dot', text: 'const decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(oGa.dpt)); ' + error.message, payload: '', dpt: '', devicename: '' });
209
+ updateStatus({ fill: 'red', shape: 'dot', text: 'const decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(oGa.dpt)); ' + error.message, payload: '', dpt: '', devicename: '' });
195
210
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimateAutoResponder: const decodedPayload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(oGa.dpt)); ${error.stack}`);
196
211
  }
197
212
  oGa.payload = decodedPayload
@@ -211,9 +226,9 @@ module.exports = function (RED) {
211
226
  const dDate = new Date()
212
227
  if (oFoundGA.address !== undefined && oFoundGA.dpt !== undefined && retVal !== undefined) {
213
228
  node.serverKNX.sendKNXTelegramToKNXEngine({ grpaddr: oFoundGA.address, payload: retVal, dpt: oFoundGA.dpt, outputtype: 'response', nodecallerid: node.id });
214
- node.status({ fill: 'blue', shape: 'dot', text: 'Respond ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
229
+ updateStatus({ fill: 'blue', shape: 'dot', text: 'Respond ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
215
230
  } else {
216
- node.status({ fill: 'yellow', shape: 'ring', text: 'Issue responding ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
231
+ updateStatus({ fill: 'yellow', shape: 'ring', text: 'Issue responding ' + oFoundGA.address + ' => ' + retVal + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
217
232
  }
218
233
  }
219
234
  } catch (error) {
@@ -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
-
@@ -55,17 +55,32 @@ module.exports = function (RED) {
55
55
  node.contextStorage = config.contextStorage !== undefined ? config.contextStorage : ''
56
56
  node.exposeAsVariable = config.exposeAsVariable !== undefined ? config.exposeAsVariable : 'exposeAsVariableREADONLY' // Should expose the Group Addresses to the Global Context?
57
57
  node.exposedGAs = []
58
- node.timerExposedGAs = null
58
+ node.timerExposedGAs = null
59
+
60
+ const shouldDisplayStatus = (color) => {
61
+ const provider = node.serverKNX;
62
+ if (provider && typeof provider.shouldDisplayStatus === 'function') {
63
+ return provider.shouldDisplayStatus(color);
64
+ }
65
+ return true;
66
+ };
67
+
68
+ const updateStatus = (status) => {
69
+ if (!status) return;
70
+ if (shouldDisplayStatus(status.fill)) {
71
+ node.status(status);
72
+ }
73
+ };
59
74
 
60
75
  // Used to call the status update from the config node.
61
76
  node.setNodeStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
62
77
  try {
63
- if (node.serverKNX === null) { node.status({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
78
+ if (node.serverKNX === null) { updateStatus({ fill: 'red', shape: 'dot', text: '[NO GATEWAY SELECTED]' }); return }
64
79
  GA = GA === undefined ? '' : GA
65
80
  payload = payload === undefined ? '' : payload
66
81
  payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
67
82
  const dDate = new Date()
68
- node.status({ fill, shape, text: GA + ' ' + payload + ' ' + text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
83
+ updateStatus({ fill, shape, text: GA + ' ' + payload + ' ' + text + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ')' })
69
84
  } catch (error) {
70
85
  }
71
86
  }