node-red-contrib-knx-ultimate 7.1.4 → 8.0.2

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 (657) hide show
  1. package/CHANGELOG.md +20 -10
  2. package/MIGRATION.md +40 -0
  3. package/README.md +32 -6
  4. package/docs/README.md +34 -0
  5. package/docs/assets/brand/made-in-italy.svg +12 -0
  6. package/examples/Alerter - Device Alert Aggregation.json +5 -2
  7. package/examples/Auto Responder - Read Request Defaults.json +5 -2
  8. package/examples/Garage - Door Controller.json +5 -2
  9. package/examples/Global Context - Expose KNX Values.json +5 -2
  10. package/examples/KNX DateTime - Set Date and Time to Bus.json +111 -89
  11. package/examples/Load Control - Manual Shedding Mode.json +5 -2
  12. package/examples/Logger ETS File and Telegram Count.json +10 -2
  13. package/examples/Scene Controller Recall and Save.json +33 -6
  14. package/examples/Staircase - Timer, Override and Block.json +5 -2
  15. package/examples/WatchDog Connect Disconnect.json +98 -70
  16. package/nodes/commonFunctions.js +0 -587
  17. package/nodes/knxUltimate-config.html +0 -14
  18. package/nodes/knxUltimate-config.js +1 -18
  19. package/nodes/knxUltimate.html +1 -6
  20. package/nodes/knxUltimateIoTBridge.html +0 -14
  21. package/nodes/knxUltimateLegacyMigration.js +75 -0
  22. package/nodes/knxUltimateMultiRouting.html +1 -7
  23. package/nodes/knxUltimateRouterFilter.html +1 -7
  24. package/nodes/knxUltimateUtility.html +0 -6
  25. package/nodes/knxUltimateViewer.html +0 -6
  26. package/nodes/locales/de/knxUltimate-config.html +0 -8
  27. package/nodes/locales/de/knxUltimate.html +0 -8
  28. package/nodes/locales/de/knxUltimateIoTBridge.html +0 -8
  29. package/nodes/locales/de/knxUltimateMultiRouting.html +0 -8
  30. package/nodes/locales/de/knxUltimateRouterFilter.html +0 -8
  31. package/nodes/locales/de/knxUltimateUtility.html +0 -8
  32. package/nodes/locales/de/knxUltimateUtility.json +16 -1
  33. package/nodes/locales/de/knxUltimateViewer.html +0 -8
  34. package/nodes/locales/en/knxUltimate-config.html +0 -8
  35. package/nodes/locales/en/knxUltimate.html +0 -8
  36. package/nodes/locales/en/knxUltimateIoTBridge.html +0 -8
  37. package/nodes/locales/en/knxUltimateMultiRouting.html +0 -8
  38. package/nodes/locales/en/knxUltimateRouterFilter.html +0 -8
  39. package/nodes/locales/en/knxUltimateUtility.html +0 -8
  40. package/nodes/locales/en/knxUltimateUtility.json +16 -1
  41. package/nodes/locales/en/knxUltimateViewer.html +0 -8
  42. package/nodes/locales/es/knxUltimate-config.html +0 -8
  43. package/nodes/locales/es/knxUltimate.html +0 -8
  44. package/nodes/locales/es/knxUltimateIoTBridge.html +0 -8
  45. package/nodes/locales/es/knxUltimateMultiRouting.html +0 -8
  46. package/nodes/locales/es/knxUltimateRouterFilter.html +0 -8
  47. package/nodes/locales/es/knxUltimateUtility.html +0 -8
  48. package/nodes/locales/es/knxUltimateUtility.json +17 -2
  49. package/nodes/locales/es/knxUltimateViewer.html +0 -8
  50. package/nodes/locales/fr/knxUltimate-config.html +0 -8
  51. package/nodes/locales/fr/knxUltimate.html +0 -8
  52. package/nodes/locales/fr/knxUltimateIoTBridge.html +0 -8
  53. package/nodes/locales/fr/knxUltimateMultiRouting.html +0 -8
  54. package/nodes/locales/fr/knxUltimateRouterFilter.html +0 -8
  55. package/nodes/locales/fr/knxUltimateUtility.html +0 -8
  56. package/nodes/locales/fr/knxUltimateUtility.json +16 -1
  57. package/nodes/locales/fr/knxUltimateViewer.html +0 -8
  58. package/nodes/locales/it/knxUltimate-config.html +0 -8
  59. package/nodes/locales/it/knxUltimate.html +0 -8
  60. package/nodes/locales/it/knxUltimateIoTBridge.html +0 -8
  61. package/nodes/locales/it/knxUltimateMultiRouting.html +0 -8
  62. package/nodes/locales/it/knxUltimateRouterFilter.html +0 -8
  63. package/nodes/locales/it/knxUltimateUtility.html +0 -8
  64. package/nodes/locales/it/knxUltimateUtility.json +16 -1
  65. package/nodes/locales/it/knxUltimateViewer.html +0 -8
  66. package/nodes/locales/zh-CN/knxUltimate-config.html +0 -8
  67. package/nodes/locales/zh-CN/knxUltimate.html +0 -8
  68. package/nodes/locales/zh-CN/knxUltimateIoTBridge.html +0 -8
  69. package/nodes/locales/zh-CN/knxUltimateMultiRouting.html +0 -8
  70. package/nodes/locales/zh-CN/knxUltimateRouterFilter.html +0 -8
  71. package/nodes/locales/zh-CN/knxUltimateUtility.html +0 -8
  72. package/nodes/locales/zh-CN/knxUltimateUtility.json +16 -1
  73. package/nodes/locales/zh-CN/knxUltimateViewer.html +0 -8
  74. package/nodes/plugins/knxUltimate-v8-migration-recovery-plugin.html +140 -0
  75. package/package.json +22 -69
  76. package/resources/11f26b4500.js +2 -2
  77. package/resources/KNXAIChatAdapterMappings.js +2 -416
  78. package/resources/configNodeEditorSelection.js +2 -32
  79. package/resources/hueControllerEditorSelection.js +2 -32
  80. package/resources/hueControllerMigrationDialog.js +2 -254
  81. package/resources/hueControllerProfiles.js +2 -9319
  82. package/resources/knxUtilityProfiles.js +2041 -2082
  83. package/resources/legacyMigrationNotice.js +23 -111
  84. package/resources/matterQrScanner.js +2 -98
  85. package/resources/upgradeToV8.js +94 -26
  86. package/scripts/check-legacy-flows.js +142 -0
  87. package/examples/Hue Area Motion - Zone Presence.json +0 -77
  88. package/examples/Hue Battery - Level Status.json +0 -77
  89. package/examples/Hue Button - Short and Dim Commands.json +0 -83
  90. package/examples/Hue Camera Motion - Presence.json +0 -77
  91. package/examples/Hue Config - Bridge Template.json +0 -27
  92. package/examples/Hue Contact Sensor - Open Closed.json +0 -75
  93. package/examples/Hue Device Software Update - Availability.json +0 -77
  94. package/examples/Hue Humidity Sensor - Relative Humidity.json +0 -77
  95. package/examples/Hue Light - Switch and Brightness.json +0 -67
  96. package/examples/Hue Light Sensor - Lux to KNX.json +0 -77
  97. package/examples/Hue Motion - Presence Sensor.json +0 -76
  98. package/examples/Hue Plug - Switch and State.json +0 -63
  99. package/examples/Hue Scene - Recall from KNX.json +0 -63
  100. package/examples/Hue Tap Dial - Relative Dimming.json +0 -76
  101. package/examples/Hue Temperature Sensor - Celsius to KNX.json +0 -77
  102. package/examples/Hue Zigbee Connectivity - Online Status.json +0 -77
  103. package/examples/Matter Controller - Semantic Flow Input.json +0 -248
  104. package/nodes/hue-config.html +0 -378
  105. package/nodes/hue-config.js +0 -846
  106. package/nodes/icons/node-alerter-icon.png +0 -0
  107. package/nodes/icons/node-homekit-icon.png +0 -0
  108. package/nodes/icons/node-homekit-icon.svg +0 -10
  109. package/nodes/icons/node-hue-icon.svg +0 -10
  110. package/nodes/icons/node-knx-icon.png +0 -0
  111. package/nodes/icons/node-logger-icon.png +0 -0
  112. package/nodes/icons/node-logger2-icon.png +0 -0
  113. package/nodes/icons/node-logger2-icon.svg +0 -32
  114. package/nodes/icons/node-matter-bridge-icon.svg +0 -6
  115. package/nodes/icons/node-matter-controller-icon.svg +0 -6
  116. package/nodes/icons/node-matter-icon.svg +0 -12
  117. package/nodes/icons/node-scene-icon.png +0 -0
  118. package/nodes/icons/node-watchdog-icon.png +0 -0
  119. package/nodes/knxUltimateAI.html +0 -1826
  120. package/nodes/knxUltimateAI.js +0 -16797
  121. package/nodes/knxUltimateAIHomeAssistant.html +0 -54
  122. package/nodes/knxUltimateAIHomeAssistant.js +0 -152
  123. package/nodes/knxUltimateAlerter.html +0 -267
  124. package/nodes/knxUltimateAlerter.js +0 -300
  125. package/nodes/knxUltimateAutoResponder.html +0 -128
  126. package/nodes/knxUltimateAutoResponder.js +0 -264
  127. package/nodes/knxUltimateDateTime.html +0 -579
  128. package/nodes/knxUltimateDateTime.js +0 -282
  129. package/nodes/knxUltimateGarage.html +0 -337
  130. package/nodes/knxUltimateGarage.js +0 -504
  131. package/nodes/knxUltimateGlobalContext.html +0 -145
  132. package/nodes/knxUltimateGlobalContext.js +0 -208
  133. package/nodes/knxUltimateHATranslator.html +0 -85
  134. package/nodes/knxUltimateHATranslator.js +0 -83
  135. package/nodes/knxUltimateHueAreaMotion.html +0 -670
  136. package/nodes/knxUltimateHueAreaMotion.js +0 -218
  137. package/nodes/knxUltimateHueBattery.html +0 -646
  138. package/nodes/knxUltimateHueBattery.js +0 -182
  139. package/nodes/knxUltimateHueButton.html +0 -804
  140. package/nodes/knxUltimateHueButton.js +0 -292
  141. package/nodes/knxUltimateHueCameraMotion.html +0 -671
  142. package/nodes/knxUltimateHueCameraMotion.js +0 -218
  143. package/nodes/knxUltimateHueContactSensor.html +0 -609
  144. package/nodes/knxUltimateHueContactSensor.js +0 -188
  145. package/nodes/knxUltimateHueController.html +0 -1765
  146. package/nodes/knxUltimateHueController.js +0 -28
  147. package/nodes/knxUltimateHueHumiditySensor.html +0 -641
  148. package/nodes/knxUltimateHueHumiditySensor.js +0 -201
  149. package/nodes/knxUltimateHueLight.html +0 -2516
  150. package/nodes/knxUltimateHueLight.js +0 -1582
  151. package/nodes/knxUltimateHueLightSensor.html +0 -636
  152. package/nodes/knxUltimateHueLightSensor.js +0 -177
  153. package/nodes/knxUltimateHueMotion.html +0 -634
  154. package/nodes/knxUltimateHueMotion.js +0 -182
  155. package/nodes/knxUltimateHuePlug.html +0 -576
  156. package/nodes/knxUltimateHuePlug.js +0 -341
  157. package/nodes/knxUltimateHueScene.html +0 -967
  158. package/nodes/knxUltimateHueScene.js +0 -349
  159. package/nodes/knxUltimateHueTapDial.html +0 -640
  160. package/nodes/knxUltimateHueTapDial.js +0 -268
  161. package/nodes/knxUltimateHueTemperatureSensor.html +0 -639
  162. package/nodes/knxUltimateHueTemperatureSensor.js +0 -184
  163. package/nodes/knxUltimateHueZigbeeConnectivity.html +0 -648
  164. package/nodes/knxUltimateHueZigbeeConnectivity.js +0 -182
  165. package/nodes/knxUltimateHuedevice_software_update.html +0 -650
  166. package/nodes/knxUltimateHuedevice_software_update.js +0 -182
  167. package/nodes/knxUltimateLoadControl.html +0 -425
  168. package/nodes/knxUltimateLoadControl.js +0 -443
  169. package/nodes/knxUltimateLogger.html +0 -197
  170. package/nodes/knxUltimateLogger.js +0 -224
  171. package/nodes/knxUltimateMatterBridge.html +0 -689
  172. package/nodes/knxUltimateMatterBridge.js +0 -464
  173. package/nodes/knxUltimateMatterControllerDevice.html +0 -2851
  174. package/nodes/knxUltimateMatterControllerDevice.js +0 -1747
  175. package/nodes/knxUltimateSceneController.html +0 -529
  176. package/nodes/knxUltimateSceneController.js +0 -437
  177. package/nodes/knxUltimateStaircase.html +0 -346
  178. package/nodes/knxUltimateStaircase.js +0 -463
  179. package/nodes/knxUltimateWatchDog.html +0 -241
  180. package/nodes/knxUltimateWatchDog.js +0 -230
  181. package/nodes/locales/de/hue-config.html +0 -33
  182. package/nodes/locales/de/hue-config.json +0 -21
  183. package/nodes/locales/de/knxUltimateAI.html +0 -13
  184. package/nodes/locales/de/knxUltimateAI.json +0 -231
  185. package/nodes/locales/de/knxUltimateAIHomeAssistant.html +0 -11
  186. package/nodes/locales/de/knxUltimateAlerter.html +0 -159
  187. package/nodes/locales/de/knxUltimateAlerter.json +0 -27
  188. package/nodes/locales/de/knxUltimateAutoResponder.html +0 -96
  189. package/nodes/locales/de/knxUltimateAutoResponder.json +0 -8
  190. package/nodes/locales/de/knxUltimateDateTime.html +0 -45
  191. package/nodes/locales/de/knxUltimateDateTime.json +0 -32
  192. package/nodes/locales/de/knxUltimateGarage.html +0 -79
  193. package/nodes/locales/de/knxUltimateGarage.json +0 -51
  194. package/nodes/locales/de/knxUltimateGlobalContext.html +0 -76
  195. package/nodes/locales/de/knxUltimateGlobalContext.json +0 -24
  196. package/nodes/locales/de/knxUltimateHATranslator.html +0 -25
  197. package/nodes/locales/de/knxUltimateHATranslator.json +0 -8
  198. package/nodes/locales/de/knxUltimateHueAreaMotion.html +0 -44
  199. package/nodes/locales/de/knxUltimateHueAreaMotion.json +0 -31
  200. package/nodes/locales/de/knxUltimateHueBattery.html +0 -37
  201. package/nodes/locales/de/knxUltimateHueBattery.json +0 -30
  202. package/nodes/locales/de/knxUltimateHueButton.html +0 -52
  203. package/nodes/locales/de/knxUltimateHueButton.json +0 -34
  204. package/nodes/locales/de/knxUltimateHueCameraMotion.html +0 -38
  205. package/nodes/locales/de/knxUltimateHueCameraMotion.json +0 -30
  206. package/nodes/locales/de/knxUltimateHueContactSensor.html +0 -35
  207. package/nodes/locales/de/knxUltimateHueContactSensor.json +0 -26
  208. package/nodes/locales/de/knxUltimateHueController.html +0 -690
  209. package/nodes/locales/de/knxUltimateHueController.json +0 -64
  210. package/nodes/locales/de/knxUltimateHueHumiditySensor.html +0 -38
  211. package/nodes/locales/de/knxUltimateHueHumiditySensor.json +0 -30
  212. package/nodes/locales/de/knxUltimateHueLight.html +0 -121
  213. package/nodes/locales/de/knxUltimateHueLight.json +0 -94
  214. package/nodes/locales/de/knxUltimateHueLightSensor.html +0 -38
  215. package/nodes/locales/de/knxUltimateHueLightSensor.json +0 -19
  216. package/nodes/locales/de/knxUltimateHueMotion.html +0 -41
  217. package/nodes/locales/de/knxUltimateHueMotion.json +0 -27
  218. package/nodes/locales/de/knxUltimateHuePlug.html +0 -50
  219. package/nodes/locales/de/knxUltimateHuePlug.json +0 -33
  220. package/nodes/locales/de/knxUltimateHueScene.html +0 -45
  221. package/nodes/locales/de/knxUltimateHueScene.json +0 -41
  222. package/nodes/locales/de/knxUltimateHueTapDial.html +0 -40
  223. package/nodes/locales/de/knxUltimateHueTapDial.json +0 -28
  224. package/nodes/locales/de/knxUltimateHueTemperatureSensor.html +0 -38
  225. package/nodes/locales/de/knxUltimateHueTemperatureSensor.json +0 -30
  226. package/nodes/locales/de/knxUltimateHueZigbeeConnectivity.html +0 -39
  227. package/nodes/locales/de/knxUltimateHueZigbeeConnectivity.json +0 -30
  228. package/nodes/locales/de/knxUltimateHuedevice_software_update.html +0 -36
  229. package/nodes/locales/de/knxUltimateHuedevice_software_update.json +0 -30
  230. package/nodes/locales/de/knxUltimateLoadControl.html +0 -69
  231. package/nodes/locales/de/knxUltimateLoadControl.json +0 -28
  232. package/nodes/locales/de/knxUltimateLogger.html +0 -126
  233. package/nodes/locales/de/knxUltimateLogger.json +0 -31
  234. package/nodes/locales/de/knxUltimateMatterBridge.html +0 -65
  235. package/nodes/locales/de/knxUltimateMatterBridge.json +0 -123
  236. package/nodes/locales/de/knxUltimateMatterControllerDevice.html +0 -57
  237. package/nodes/locales/de/knxUltimateMatterControllerDevice.json +0 -146
  238. package/nodes/locales/de/knxUltimateSceneController.html +0 -98
  239. package/nodes/locales/de/knxUltimateSceneController.json +0 -32
  240. package/nodes/locales/de/knxUltimateStaircase.html +0 -77
  241. package/nodes/locales/de/knxUltimateStaircase.json +0 -62
  242. package/nodes/locales/de/knxUltimateWatchDog.html +0 -178
  243. package/nodes/locales/de/knxUltimateWatchDog.json +0 -27
  244. package/nodes/locales/de/matter-config.html +0 -47
  245. package/nodes/locales/de/matter-config.json +0 -47
  246. package/nodes/locales/de/matterbridge-config.html +0 -45
  247. package/nodes/locales/de/matterbridge-config.json +0 -25
  248. package/nodes/locales/en/hue-config.html +0 -31
  249. package/nodes/locales/en/hue-config.json +0 -21
  250. package/nodes/locales/en/knxUltimateAI.html +0 -13
  251. package/nodes/locales/en/knxUltimateAI.json +0 -234
  252. package/nodes/locales/en/knxUltimateAIHomeAssistant.html +0 -11
  253. package/nodes/locales/en/knxUltimateAlerter.html +0 -164
  254. package/nodes/locales/en/knxUltimateAlerter.json +0 -27
  255. package/nodes/locales/en/knxUltimateAutoResponder.html +0 -94
  256. package/nodes/locales/en/knxUltimateAutoResponder.json +0 -8
  257. package/nodes/locales/en/knxUltimateDateTime.html +0 -67
  258. package/nodes/locales/en/knxUltimateDateTime.json +0 -32
  259. package/nodes/locales/en/knxUltimateGarage.html +0 -79
  260. package/nodes/locales/en/knxUltimateGarage.json +0 -51
  261. package/nodes/locales/en/knxUltimateGlobalContext.html +0 -124
  262. package/nodes/locales/en/knxUltimateGlobalContext.json +0 -24
  263. package/nodes/locales/en/knxUltimateHATranslator.html +0 -25
  264. package/nodes/locales/en/knxUltimateHATranslator.json +0 -8
  265. package/nodes/locales/en/knxUltimateHueAreaMotion.html +0 -44
  266. package/nodes/locales/en/knxUltimateHueAreaMotion.json +0 -31
  267. package/nodes/locales/en/knxUltimateHueBattery.html +0 -37
  268. package/nodes/locales/en/knxUltimateHueBattery.json +0 -30
  269. package/nodes/locales/en/knxUltimateHueButton.html +0 -52
  270. package/nodes/locales/en/knxUltimateHueButton.json +0 -34
  271. package/nodes/locales/en/knxUltimateHueCameraMotion.html +0 -38
  272. package/nodes/locales/en/knxUltimateHueCameraMotion.json +0 -30
  273. package/nodes/locales/en/knxUltimateHueContactSensor.html +0 -35
  274. package/nodes/locales/en/knxUltimateHueContactSensor.json +0 -26
  275. package/nodes/locales/en/knxUltimateHueController.html +0 -691
  276. package/nodes/locales/en/knxUltimateHueController.json +0 -64
  277. package/nodes/locales/en/knxUltimateHueHumiditySensor.html +0 -38
  278. package/nodes/locales/en/knxUltimateHueHumiditySensor.json +0 -30
  279. package/nodes/locales/en/knxUltimateHueLight.html +0 -124
  280. package/nodes/locales/en/knxUltimateHueLight.json +0 -94
  281. package/nodes/locales/en/knxUltimateHueLightSensor.html +0 -38
  282. package/nodes/locales/en/knxUltimateHueLightSensor.json +0 -19
  283. package/nodes/locales/en/knxUltimateHueMotion.html +0 -41
  284. package/nodes/locales/en/knxUltimateHueMotion.json +0 -27
  285. package/nodes/locales/en/knxUltimateHuePlug.html +0 -50
  286. package/nodes/locales/en/knxUltimateHuePlug.json +0 -33
  287. package/nodes/locales/en/knxUltimateHueScene.html +0 -45
  288. package/nodes/locales/en/knxUltimateHueScene.json +0 -41
  289. package/nodes/locales/en/knxUltimateHueTapDial.html +0 -40
  290. package/nodes/locales/en/knxUltimateHueTapDial.json +0 -28
  291. package/nodes/locales/en/knxUltimateHueTemperatureSensor.html +0 -38
  292. package/nodes/locales/en/knxUltimateHueTemperatureSensor.json +0 -30
  293. package/nodes/locales/en/knxUltimateHueZigbeeConnectivity.html +0 -39
  294. package/nodes/locales/en/knxUltimateHueZigbeeConnectivity.json +0 -30
  295. package/nodes/locales/en/knxUltimateHuedevice_software_update.html +0 -36
  296. package/nodes/locales/en/knxUltimateHuedevice_software_update.json +0 -30
  297. package/nodes/locales/en/knxUltimateLoadControl.html +0 -76
  298. package/nodes/locales/en/knxUltimateLoadControl.json +0 -28
  299. package/nodes/locales/en/knxUltimateLogger.html +0 -161
  300. package/nodes/locales/en/knxUltimateLogger.json +0 -31
  301. package/nodes/locales/en/knxUltimateMatterBridge.html +0 -65
  302. package/nodes/locales/en/knxUltimateMatterBridge.json +0 -123
  303. package/nodes/locales/en/knxUltimateMatterControllerDevice.html +0 -57
  304. package/nodes/locales/en/knxUltimateMatterControllerDevice.json +0 -146
  305. package/nodes/locales/en/knxUltimateSceneController.html +0 -117
  306. package/nodes/locales/en/knxUltimateSceneController.json +0 -32
  307. package/nodes/locales/en/knxUltimateStaircase.html +0 -77
  308. package/nodes/locales/en/knxUltimateStaircase.json +0 -62
  309. package/nodes/locales/en/knxUltimateWatchDog.html +0 -244
  310. package/nodes/locales/en/knxUltimateWatchDog.json +0 -27
  311. package/nodes/locales/en/matter-config.html +0 -47
  312. package/nodes/locales/en/matter-config.json +0 -48
  313. package/nodes/locales/en/matterbridge-config.html +0 -45
  314. package/nodes/locales/en/matterbridge-config.json +0 -25
  315. package/nodes/locales/es/hue-config.html +0 -31
  316. package/nodes/locales/es/hue-config.json +0 -21
  317. package/nodes/locales/es/knxUltimateAI.html +0 -13
  318. package/nodes/locales/es/knxUltimateAI.json +0 -231
  319. package/nodes/locales/es/knxUltimateAIHomeAssistant.html +0 -11
  320. package/nodes/locales/es/knxUltimateAlerter.html +0 -164
  321. package/nodes/locales/es/knxUltimateAlerter.json +0 -27
  322. package/nodes/locales/es/knxUltimateAutoResponder.html +0 -81
  323. package/nodes/locales/es/knxUltimateAutoResponder.json +0 -8
  324. package/nodes/locales/es/knxUltimateDateTime.html +0 -45
  325. package/nodes/locales/es/knxUltimateDateTime.json +0 -32
  326. package/nodes/locales/es/knxUltimateGarage.html +0 -79
  327. package/nodes/locales/es/knxUltimateGarage.json +0 -51
  328. package/nodes/locales/es/knxUltimateGlobalContext.html +0 -128
  329. package/nodes/locales/es/knxUltimateGlobalContext.json +0 -24
  330. package/nodes/locales/es/knxUltimateHATranslator.html +0 -25
  331. package/nodes/locales/es/knxUltimateHATranslator.json +0 -8
  332. package/nodes/locales/es/knxUltimateHueAreaMotion.html +0 -44
  333. package/nodes/locales/es/knxUltimateHueAreaMotion.json +0 -31
  334. package/nodes/locales/es/knxUltimateHueBattery.html +0 -37
  335. package/nodes/locales/es/knxUltimateHueBattery.json +0 -30
  336. package/nodes/locales/es/knxUltimateHueButton.html +0 -52
  337. package/nodes/locales/es/knxUltimateHueButton.json +0 -34
  338. package/nodes/locales/es/knxUltimateHueCameraMotion.html +0 -38
  339. package/nodes/locales/es/knxUltimateHueCameraMotion.json +0 -30
  340. package/nodes/locales/es/knxUltimateHueContactSensor.html +0 -35
  341. package/nodes/locales/es/knxUltimateHueContactSensor.json +0 -26
  342. package/nodes/locales/es/knxUltimateHueController.html +0 -691
  343. package/nodes/locales/es/knxUltimateHueController.json +0 -64
  344. package/nodes/locales/es/knxUltimateHueHumiditySensor.html +0 -38
  345. package/nodes/locales/es/knxUltimateHueHumiditySensor.json +0 -30
  346. package/nodes/locales/es/knxUltimateHueLight.html +0 -124
  347. package/nodes/locales/es/knxUltimateHueLight.json +0 -94
  348. package/nodes/locales/es/knxUltimateHueLightSensor.html +0 -38
  349. package/nodes/locales/es/knxUltimateHueLightSensor.json +0 -19
  350. package/nodes/locales/es/knxUltimateHueMotion.html +0 -41
  351. package/nodes/locales/es/knxUltimateHueMotion.json +0 -27
  352. package/nodes/locales/es/knxUltimateHuePlug.html +0 -50
  353. package/nodes/locales/es/knxUltimateHuePlug.json +0 -33
  354. package/nodes/locales/es/knxUltimateHueScene.html +0 -45
  355. package/nodes/locales/es/knxUltimateHueScene.json +0 -41
  356. package/nodes/locales/es/knxUltimateHueTapDial.html +0 -40
  357. package/nodes/locales/es/knxUltimateHueTapDial.json +0 -28
  358. package/nodes/locales/es/knxUltimateHueTemperatureSensor.html +0 -38
  359. package/nodes/locales/es/knxUltimateHueTemperatureSensor.json +0 -30
  360. package/nodes/locales/es/knxUltimateHueZigbeeConnectivity.html +0 -39
  361. package/nodes/locales/es/knxUltimateHueZigbeeConnectivity.json +0 -30
  362. package/nodes/locales/es/knxUltimateHuedevice_software_update.html +0 -36
  363. package/nodes/locales/es/knxUltimateHuedevice_software_update.json +0 -30
  364. package/nodes/locales/es/knxUltimateLoadControl.html +0 -76
  365. package/nodes/locales/es/knxUltimateLoadControl.json +0 -28
  366. package/nodes/locales/es/knxUltimateLogger.html +0 -162
  367. package/nodes/locales/es/knxUltimateLogger.json +0 -31
  368. package/nodes/locales/es/knxUltimateMatterBridge.html +0 -65
  369. package/nodes/locales/es/knxUltimateMatterBridge.json +0 -123
  370. package/nodes/locales/es/knxUltimateMatterControllerDevice.html +0 -57
  371. package/nodes/locales/es/knxUltimateMatterControllerDevice.json +0 -146
  372. package/nodes/locales/es/knxUltimateSceneController.html +0 -115
  373. package/nodes/locales/es/knxUltimateSceneController.json +0 -32
  374. package/nodes/locales/es/knxUltimateStaircase.html +0 -77
  375. package/nodes/locales/es/knxUltimateStaircase.json +0 -62
  376. package/nodes/locales/es/knxUltimateWatchDog.html +0 -230
  377. package/nodes/locales/es/knxUltimateWatchDog.json +0 -27
  378. package/nodes/locales/es/matter-config.html +0 -47
  379. package/nodes/locales/es/matter-config.json +0 -47
  380. package/nodes/locales/es/matterbridge-config.html +0 -45
  381. package/nodes/locales/es/matterbridge-config.json +0 -25
  382. package/nodes/locales/fr/hue-config.html +0 -31
  383. package/nodes/locales/fr/hue-config.json +0 -21
  384. package/nodes/locales/fr/knxUltimateAI.html +0 -13
  385. package/nodes/locales/fr/knxUltimateAI.json +0 -231
  386. package/nodes/locales/fr/knxUltimateAIHomeAssistant.html +0 -11
  387. package/nodes/locales/fr/knxUltimateAlerter.html +0 -164
  388. package/nodes/locales/fr/knxUltimateAlerter.json +0 -27
  389. package/nodes/locales/fr/knxUltimateAutoResponder.html +0 -92
  390. package/nodes/locales/fr/knxUltimateAutoResponder.json +0 -8
  391. package/nodes/locales/fr/knxUltimateDateTime.html +0 -45
  392. package/nodes/locales/fr/knxUltimateDateTime.json +0 -32
  393. package/nodes/locales/fr/knxUltimateGarage.html +0 -79
  394. package/nodes/locales/fr/knxUltimateGarage.json +0 -51
  395. package/nodes/locales/fr/knxUltimateGlobalContext.html +0 -122
  396. package/nodes/locales/fr/knxUltimateGlobalContext.json +0 -24
  397. package/nodes/locales/fr/knxUltimateHATranslator.html +0 -25
  398. package/nodes/locales/fr/knxUltimateHATranslator.json +0 -8
  399. package/nodes/locales/fr/knxUltimateHueAreaMotion.html +0 -44
  400. package/nodes/locales/fr/knxUltimateHueAreaMotion.json +0 -31
  401. package/nodes/locales/fr/knxUltimateHueBattery.html +0 -37
  402. package/nodes/locales/fr/knxUltimateHueBattery.json +0 -30
  403. package/nodes/locales/fr/knxUltimateHueButton.html +0 -52
  404. package/nodes/locales/fr/knxUltimateHueButton.json +0 -34
  405. package/nodes/locales/fr/knxUltimateHueCameraMotion.html +0 -38
  406. package/nodes/locales/fr/knxUltimateHueCameraMotion.json +0 -30
  407. package/nodes/locales/fr/knxUltimateHueContactSensor.html +0 -35
  408. package/nodes/locales/fr/knxUltimateHueContactSensor.json +0 -26
  409. package/nodes/locales/fr/knxUltimateHueController.html +0 -691
  410. package/nodes/locales/fr/knxUltimateHueController.json +0 -64
  411. package/nodes/locales/fr/knxUltimateHueHumiditySensor.html +0 -38
  412. package/nodes/locales/fr/knxUltimateHueHumiditySensor.json +0 -30
  413. package/nodes/locales/fr/knxUltimateHueLight.html +0 -124
  414. package/nodes/locales/fr/knxUltimateHueLight.json +0 -86
  415. package/nodes/locales/fr/knxUltimateHueLightSensor.html +0 -38
  416. package/nodes/locales/fr/knxUltimateHueLightSensor.json +0 -19
  417. package/nodes/locales/fr/knxUltimateHueMotion.html +0 -41
  418. package/nodes/locales/fr/knxUltimateHueMotion.json +0 -27
  419. package/nodes/locales/fr/knxUltimateHuePlug.html +0 -50
  420. package/nodes/locales/fr/knxUltimateHuePlug.json +0 -33
  421. package/nodes/locales/fr/knxUltimateHueScene.html +0 -45
  422. package/nodes/locales/fr/knxUltimateHueScene.json +0 -41
  423. package/nodes/locales/fr/knxUltimateHueTapDial.html +0 -40
  424. package/nodes/locales/fr/knxUltimateHueTapDial.json +0 -28
  425. package/nodes/locales/fr/knxUltimateHueTemperatureSensor.html +0 -38
  426. package/nodes/locales/fr/knxUltimateHueTemperatureSensor.json +0 -30
  427. package/nodes/locales/fr/knxUltimateHueZigbeeConnectivity.html +0 -39
  428. package/nodes/locales/fr/knxUltimateHueZigbeeConnectivity.json +0 -30
  429. package/nodes/locales/fr/knxUltimateHuedevice_software_update.html +0 -36
  430. package/nodes/locales/fr/knxUltimateHuedevice_software_update.json +0 -30
  431. package/nodes/locales/fr/knxUltimateLoadControl.html +0 -76
  432. package/nodes/locales/fr/knxUltimateLoadControl.json +0 -28
  433. package/nodes/locales/fr/knxUltimateLogger.html +0 -160
  434. package/nodes/locales/fr/knxUltimateLogger.json +0 -31
  435. package/nodes/locales/fr/knxUltimateMatterBridge.html +0 -65
  436. package/nodes/locales/fr/knxUltimateMatterBridge.json +0 -123
  437. package/nodes/locales/fr/knxUltimateMatterControllerDevice.html +0 -57
  438. package/nodes/locales/fr/knxUltimateMatterControllerDevice.json +0 -146
  439. package/nodes/locales/fr/knxUltimateSceneController.html +0 -117
  440. package/nodes/locales/fr/knxUltimateSceneController.json +0 -32
  441. package/nodes/locales/fr/knxUltimateStaircase.html +0 -77
  442. package/nodes/locales/fr/knxUltimateStaircase.json +0 -62
  443. package/nodes/locales/fr/knxUltimateWatchDog.html +0 -228
  444. package/nodes/locales/fr/knxUltimateWatchDog.json +0 -27
  445. package/nodes/locales/fr/matter-config.html +0 -47
  446. package/nodes/locales/fr/matter-config.json +0 -47
  447. package/nodes/locales/fr/matterbridge-config.html +0 -45
  448. package/nodes/locales/fr/matterbridge-config.json +0 -25
  449. package/nodes/locales/it/hue-config.html +0 -33
  450. package/nodes/locales/it/hue-config.json +0 -21
  451. package/nodes/locales/it/knxUltimateAI.html +0 -13
  452. package/nodes/locales/it/knxUltimateAI.json +0 -234
  453. package/nodes/locales/it/knxUltimateAIHomeAssistant.html +0 -11
  454. package/nodes/locales/it/knxUltimateAlerter.html +0 -159
  455. package/nodes/locales/it/knxUltimateAlerter.json +0 -27
  456. package/nodes/locales/it/knxUltimateAutoResponder.html +0 -96
  457. package/nodes/locales/it/knxUltimateAutoResponder.json +0 -8
  458. package/nodes/locales/it/knxUltimateDateTime.html +0 -67
  459. package/nodes/locales/it/knxUltimateDateTime.json +0 -32
  460. package/nodes/locales/it/knxUltimateGarage.html +0 -79
  461. package/nodes/locales/it/knxUltimateGarage.json +0 -51
  462. package/nodes/locales/it/knxUltimateGlobalContext.html +0 -81
  463. package/nodes/locales/it/knxUltimateGlobalContext.json +0 -24
  464. package/nodes/locales/it/knxUltimateHATranslator.html +0 -24
  465. package/nodes/locales/it/knxUltimateHATranslator.json +0 -8
  466. package/nodes/locales/it/knxUltimateHueAreaMotion.html +0 -44
  467. package/nodes/locales/it/knxUltimateHueAreaMotion.json +0 -31
  468. package/nodes/locales/it/knxUltimateHueBattery.html +0 -37
  469. package/nodes/locales/it/knxUltimateHueBattery.json +0 -30
  470. package/nodes/locales/it/knxUltimateHueButton.html +0 -52
  471. package/nodes/locales/it/knxUltimateHueButton.json +0 -34
  472. package/nodes/locales/it/knxUltimateHueCameraMotion.html +0 -38
  473. package/nodes/locales/it/knxUltimateHueCameraMotion.json +0 -30
  474. package/nodes/locales/it/knxUltimateHueContactSensor.html +0 -35
  475. package/nodes/locales/it/knxUltimateHueContactSensor.json +0 -26
  476. package/nodes/locales/it/knxUltimateHueController.html +0 -690
  477. package/nodes/locales/it/knxUltimateHueController.json +0 -64
  478. package/nodes/locales/it/knxUltimateHueHumiditySensor 2.html +0 -11
  479. package/nodes/locales/it/knxUltimateHueHumiditySensor.html +0 -38
  480. package/nodes/locales/it/knxUltimateHueHumiditySensor.json +0 -30
  481. package/nodes/locales/it/knxUltimateHueLight.html +0 -124
  482. package/nodes/locales/it/knxUltimateHueLight.json +0 -94
  483. package/nodes/locales/it/knxUltimateHueLightSensor.html +0 -38
  484. package/nodes/locales/it/knxUltimateHueLightSensor.json +0 -19
  485. package/nodes/locales/it/knxUltimateHueMotion.html +0 -41
  486. package/nodes/locales/it/knxUltimateHueMotion.json +0 -27
  487. package/nodes/locales/it/knxUltimateHuePlug.html +0 -50
  488. package/nodes/locales/it/knxUltimateHuePlug.json +0 -33
  489. package/nodes/locales/it/knxUltimateHueScene.html +0 -45
  490. package/nodes/locales/it/knxUltimateHueScene.json +0 -41
  491. package/nodes/locales/it/knxUltimateHueTapDial.html +0 -40
  492. package/nodes/locales/it/knxUltimateHueTapDial.json +0 -28
  493. package/nodes/locales/it/knxUltimateHueTemperatureSensor.html +0 -38
  494. package/nodes/locales/it/knxUltimateHueTemperatureSensor.json +0 -30
  495. package/nodes/locales/it/knxUltimateHueZigbeeConnectivity.html +0 -39
  496. package/nodes/locales/it/knxUltimateHueZigbeeConnectivity.json +0 -30
  497. package/nodes/locales/it/knxUltimateHuedevice_software_update.html +0 -35
  498. package/nodes/locales/it/knxUltimateHuedevice_software_update.json +0 -30
  499. package/nodes/locales/it/knxUltimateLoadControl.html +0 -76
  500. package/nodes/locales/it/knxUltimateLoadControl.json +0 -28
  501. package/nodes/locales/it/knxUltimateLogger.html +0 -132
  502. package/nodes/locales/it/knxUltimateLogger.json +0 -31
  503. package/nodes/locales/it/knxUltimateMatterBridge.html +0 -65
  504. package/nodes/locales/it/knxUltimateMatterBridge.json +0 -123
  505. package/nodes/locales/it/knxUltimateMatterControllerDevice.html +0 -57
  506. package/nodes/locales/it/knxUltimateMatterControllerDevice.json +0 -146
  507. package/nodes/locales/it/knxUltimateSceneController.html +0 -101
  508. package/nodes/locales/it/knxUltimateSceneController.json +0 -32
  509. package/nodes/locales/it/knxUltimateStaircase.html +0 -77
  510. package/nodes/locales/it/knxUltimateStaircase.json +0 -62
  511. package/nodes/locales/it/knxUltimateWatchDog.html +0 -194
  512. package/nodes/locales/it/knxUltimateWatchDog.json +0 -27
  513. package/nodes/locales/it/matter-config.html +0 -47
  514. package/nodes/locales/it/matter-config.json +0 -48
  515. package/nodes/locales/it/matterbridge-config.html +0 -45
  516. package/nodes/locales/it/matterbridge-config.json +0 -25
  517. package/nodes/locales/zh-CN/hue-config.html +0 -33
  518. package/nodes/locales/zh-CN/hue-config.json +0 -21
  519. package/nodes/locales/zh-CN/knxUltimateAI.html +0 -13
  520. package/nodes/locales/zh-CN/knxUltimateAI.json +0 -231
  521. package/nodes/locales/zh-CN/knxUltimateAIHomeAssistant.html +0 -11
  522. package/nodes/locales/zh-CN/knxUltimateAlerter.html +0 -159
  523. package/nodes/locales/zh-CN/knxUltimateAlerter.json +0 -27
  524. package/nodes/locales/zh-CN/knxUltimateAutoResponder.html +0 -94
  525. package/nodes/locales/zh-CN/knxUltimateAutoResponder.json +0 -8
  526. package/nodes/locales/zh-CN/knxUltimateDateTime.html +0 -45
  527. package/nodes/locales/zh-CN/knxUltimateDateTime.json +0 -32
  528. package/nodes/locales/zh-CN/knxUltimateGarage.html +0 -79
  529. package/nodes/locales/zh-CN/knxUltimateGarage.json +0 -51
  530. package/nodes/locales/zh-CN/knxUltimateGlobalContext.html +0 -77
  531. package/nodes/locales/zh-CN/knxUltimateGlobalContext.json +0 -24
  532. package/nodes/locales/zh-CN/knxUltimateHATranslator.html +0 -25
  533. package/nodes/locales/zh-CN/knxUltimateHATranslator.json +0 -8
  534. package/nodes/locales/zh-CN/knxUltimateHueAreaMotion.html +0 -44
  535. package/nodes/locales/zh-CN/knxUltimateHueAreaMotion.json +0 -31
  536. package/nodes/locales/zh-CN/knxUltimateHueBattery.html +0 -37
  537. package/nodes/locales/zh-CN/knxUltimateHueBattery.json +0 -30
  538. package/nodes/locales/zh-CN/knxUltimateHueButton.html +0 -52
  539. package/nodes/locales/zh-CN/knxUltimateHueButton.json +0 -34
  540. package/nodes/locales/zh-CN/knxUltimateHueCameraMotion.html +0 -38
  541. package/nodes/locales/zh-CN/knxUltimateHueCameraMotion.json +0 -30
  542. package/nodes/locales/zh-CN/knxUltimateHueContactSensor.html +0 -35
  543. package/nodes/locales/zh-CN/knxUltimateHueContactSensor.json +0 -26
  544. package/nodes/locales/zh-CN/knxUltimateHueController.html +0 -693
  545. package/nodes/locales/zh-CN/knxUltimateHueController.json +0 -64
  546. package/nodes/locales/zh-CN/knxUltimateHueHumiditySensor.html +0 -38
  547. package/nodes/locales/zh-CN/knxUltimateHueHumiditySensor.json +0 -30
  548. package/nodes/locales/zh-CN/knxUltimateHueLight.html +0 -126
  549. package/nodes/locales/zh-CN/knxUltimateHueLight.json +0 -86
  550. package/nodes/locales/zh-CN/knxUltimateHueLightSensor.html +0 -38
  551. package/nodes/locales/zh-CN/knxUltimateHueLightSensor.json +0 -9
  552. package/nodes/locales/zh-CN/knxUltimateHueMotion.html +0 -41
  553. package/nodes/locales/zh-CN/knxUltimateHueMotion.json +0 -27
  554. package/nodes/locales/zh-CN/knxUltimateHuePlug.html +0 -50
  555. package/nodes/locales/zh-CN/knxUltimateHuePlug.json +0 -33
  556. package/nodes/locales/zh-CN/knxUltimateHueScene.html +0 -45
  557. package/nodes/locales/zh-CN/knxUltimateHueScene.json +0 -41
  558. package/nodes/locales/zh-CN/knxUltimateHueTapDial.html +0 -40
  559. package/nodes/locales/zh-CN/knxUltimateHueTapDial.json +0 -28
  560. package/nodes/locales/zh-CN/knxUltimateHueTemperatureSensor.html +0 -38
  561. package/nodes/locales/zh-CN/knxUltimateHueTemperatureSensor.json +0 -30
  562. package/nodes/locales/zh-CN/knxUltimateHueZigbeeConnectivity.html +0 -39
  563. package/nodes/locales/zh-CN/knxUltimateHueZigbeeConnectivity.json +0 -30
  564. package/nodes/locales/zh-CN/knxUltimateHuedevice_software_update.html +0 -36
  565. package/nodes/locales/zh-CN/knxUltimateHuedevice_software_update.json +0 -30
  566. package/nodes/locales/zh-CN/knxUltimateLoadControl.html +0 -76
  567. package/nodes/locales/zh-CN/knxUltimateLoadControl.json +0 -28
  568. package/nodes/locales/zh-CN/knxUltimateLogger.html +0 -126
  569. package/nodes/locales/zh-CN/knxUltimateLogger.json +0 -31
  570. package/nodes/locales/zh-CN/knxUltimateMatterBridge.html +0 -65
  571. package/nodes/locales/zh-CN/knxUltimateMatterBridge.json +0 -123
  572. package/nodes/locales/zh-CN/knxUltimateMatterControllerDevice.html +0 -57
  573. package/nodes/locales/zh-CN/knxUltimateMatterControllerDevice.json +0 -146
  574. package/nodes/locales/zh-CN/knxUltimateSceneController.html +0 -98
  575. package/nodes/locales/zh-CN/knxUltimateSceneController.json +0 -32
  576. package/nodes/locales/zh-CN/knxUltimateStaircase.html +0 -77
  577. package/nodes/locales/zh-CN/knxUltimateStaircase.json +0 -62
  578. package/nodes/locales/zh-CN/knxUltimateWatchDog.html +0 -178
  579. package/nodes/locales/zh-CN/knxUltimateWatchDog.json +0 -27
  580. package/nodes/locales/zh-CN/matter-config.html +0 -47
  581. package/nodes/locales/zh-CN/matter-config.json +0 -47
  582. package/nodes/locales/zh-CN/matterbridge-config.html +0 -45
  583. package/nodes/locales/zh-CN/matterbridge-config.json +0 -25
  584. package/nodes/matter-config.html +0 -578
  585. package/nodes/matter-config.js +0 -387
  586. package/nodes/matterbridge-config.html +0 -198
  587. package/nodes/matterbridge-config.js +0 -261
  588. package/nodes/plugins/knxUltimate-cerebrum-runtime-plugin.js +0 -79
  589. package/nodes/plugins/knxUltimate-migration-notice-plugin.html +0 -44
  590. package/nodes/plugins/knxUltimateAI-vue/assets/app.css +0 -1
  591. package/nodes/plugins/knxUltimateAI-vue/assets/app.js +0 -13
  592. package/nodes/plugins/knxUltimateAI-vue/assets/chunk-html2canvas.esm.js +0 -5
  593. package/nodes/plugins/knxUltimateAI-vue/assets/chunk-index.es.js +0 -5
  594. package/nodes/plugins/knxUltimateAI-vue/assets/chunk-jspdf.es.min.js +0 -79
  595. package/nodes/plugins/knxUltimateAI-vue/assets/chunk-purify.es.js +0 -3
  596. package/nodes/plugins/knxUltimateAI-vue/index.html +0 -13
  597. package/nodes/utils/HueEventStream.mjs +0 -176
  598. package/nodes/utils/colorManipulators/XYFromRGB_Supergiovane.js +0 -113
  599. package/nodes/utils/colorManipulators/hueColorConverter.js +0 -521
  600. package/nodes/utils/http.js +0 -291
  601. package/nodes/utils/hueControllerProfileAdapter.js +0 -104
  602. package/nodes/utils/hueControllerProfiles/runtime/area_motion.js +0 -221
  603. package/nodes/utils/hueControllerProfiles/runtime/button.js +0 -295
  604. package/nodes/utils/hueControllerProfiles/runtime/camera_motion.js +0 -221
  605. package/nodes/utils/hueControllerProfiles/runtime/contact.js +0 -191
  606. package/nodes/utils/hueControllerProfiles/runtime/device_power.js +0 -185
  607. package/nodes/utils/hueControllerProfiles/runtime/device_software_update.js +0 -185
  608. package/nodes/utils/hueControllerProfiles/runtime/humidity.js +0 -204
  609. package/nodes/utils/hueControllerProfiles/runtime/light.js +0 -1585
  610. package/nodes/utils/hueControllerProfiles/runtime/light_level.js +0 -180
  611. package/nodes/utils/hueControllerProfiles/runtime/motion.js +0 -185
  612. package/nodes/utils/hueControllerProfiles/runtime/plug.js +0 -344
  613. package/nodes/utils/hueControllerProfiles/runtime/relative_rotary.js +0 -271
  614. package/nodes/utils/hueControllerProfiles/runtime/scene.js +0 -352
  615. package/nodes/utils/hueControllerProfiles/runtime/temperature.js +0 -187
  616. package/nodes/utils/hueControllerProfiles/runtime/zigbee_connectivity.js +0 -185
  617. package/nodes/utils/hueControllerResourceCatalog.js +0 -71
  618. package/nodes/utils/hueEngine.mjs +0 -469
  619. package/nodes/utils/knxAiCamera.js +0 -302
  620. package/nodes/utils/knxAiCatalogRetrieval.js +0 -349
  621. package/nodes/utils/knxAiCerebrum.js +0 -406
  622. package/nodes/utils/knxAiChatContext.js +0 -496
  623. package/nodes/utils/knxAiEventHistory.js +0 -521
  624. package/nodes/utils/knxAiHomeMemory.js +0 -1021
  625. package/nodes/utils/knxAiScheduler.js +0 -445
  626. package/nodes/utils/knxAiSemanticContext.js +0 -662
  627. package/nodes/utils/knxAiTelegramVoice.js +0 -545
  628. package/nodes/utils/knxAiWebAccess.js +0 -631
  629. package/nodes/utils/lightEngines/canonicalLight.js +0 -75
  630. package/nodes/utils/lightEngines/hueLightEngine.js +0 -51
  631. package/nodes/utils/lightEngines/index.js +0 -25
  632. package/nodes/utils/lightEngines/knxLightCommand.js +0 -79
  633. package/nodes/utils/lightEngines/lightEngine.js +0 -46
  634. package/nodes/utils/lightEngines/matterHueShim.js +0 -59
  635. package/nodes/utils/lightEngines/matterLightEngine.js +0 -117
  636. package/nodes/utils/matterBridgeDeviceFactory.mjs +0 -780
  637. package/nodes/utils/matterBridgeEngine.mjs +0 -297
  638. package/nodes/utils/matterControllerCommandGate.js +0 -47
  639. package/nodes/utils/matterControllerProfiles/doorLock.js +0 -258
  640. package/nodes/utils/matterControllerProfiles/fan.js +0 -19
  641. package/nodes/utils/matterControllerProfiles/index.js +0 -34
  642. package/nodes/utils/matterControllerProfiles/mappedEndpoint.js +0 -217
  643. package/nodes/utils/matterControllerProfiles/switch.js +0 -13
  644. package/nodes/utils/matterControllerProfiles/thermostat.js +0 -19
  645. package/nodes/utils/matterControllerProfiles/universal.js +0 -462
  646. package/nodes/utils/matterControllerProfiles/windowCovering.js +0 -19
  647. package/nodes/utils/matterControllerSemanticInput.js +0 -212
  648. package/nodes/utils/matterEngine.mjs +0 -894
  649. package/nodes/utils/matterEnvironmentLock.mjs +0 -32
  650. package/nodes/utils/matterKnxConverter.js +0 -204
  651. package/nodes/utils/matterStorageBackup.js +0 -100
  652. package/resources/HA-icon.png +0 -0
  653. package/resources/dim.png +0 -0
  654. package/resources/rgb.png +0 -0
  655. package/resources/tunablewhite.png +0 -0
  656. package/resources/zxing-browser-0.2.0.min.js +0 -1
  657. package/resources/zxing-browser-LICENSE.txt +0 -21
@@ -1,1585 +0,0 @@
1
- // Canonical private runtime profile for HUE Controller: light.
2
- // This module is shipped with the Controller but is intentionally absent from
3
- // package.json, so Node-RED never registers it as a separate palette node.
4
- /* eslint-disable no-param-reassign */
5
- /* eslint-disable camelcase */
6
- /* eslint-disable max-len */
7
- /* eslint-disable no-lonely-if */
8
- const cloneDeep = require('lodash/cloneDeep')
9
- const dptlib = require('knxultimate').dptlib
10
- const hueColorConverter = require('../../colorManipulators/hueColorConverter')
11
-
12
- module.exports = function (RED) {
13
- function knxUltimateHueLight (config) {
14
- RED.nodes.createNode(this, config)
15
- const node = this
16
- node.serverKNX = RED.nodes.getNode(config.server) || undefined
17
- node.serverHue = RED.nodes.getNode(config.serverHue) || undefined
18
-
19
- // Convert for backward compatibility
20
- if (config.nameLightKelvinDIM === undefined) {
21
- config.nameLightKelvinDIM = config.nameLightHSV
22
- config.GALightKelvinDIM = config.GALightHSV
23
- config.dptLightKelvinDIM = config.dptLightHSV
24
-
25
- config.nameLightKelvinPercentage = config.nameLightHSVPercentage
26
- config.GALightKelvinPercentage = config.GALightHSVPercentage
27
- config.dptLightKelvinPercentage = config.dptLightHSVPercentage
28
-
29
- config.nameLightKelvinPercentageState = config.nameLightHSVState
30
- config.GALightKelvinPercentageState = config.GALightHSVState
31
- config.dptLightKelvinPercentageState = config.dptLightHSVState
32
- }
33
-
34
- node.topic = node.name
35
- node.name = config.name === undefined ? 'Hue' : config.name
36
- node.outputtopic = node.name
37
- node.dpt = ''
38
- node.notifyreadrequest = true
39
- node.notifyreadrequestalsorespondtobus = 'false'
40
- node.notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized = ''
41
- node.notifyresponse = false
42
- node.notifywrite = true
43
- node.initialread = true
44
- node.listenallga = true // Don't remove
45
- node.outputtype = 'write'
46
- node.outputRBE = 'false' // Apply or not RBE to the output (Messages coming from flow)
47
- node.inputRBE = 'false' // Apply or not RBE to the input (Messages coming from BUS)
48
- node.currentPayload = '' // Current value for the RBE input and for the .previouspayload msg
49
- node.passthrough = 'no'
50
- node.formatmultiplyvalue = 1
51
- node.formatnegativevalue = 'leave'
52
- node.formatdecimalsvalue = 2
53
- node.currentHUEDevice = undefined // At start, this value is filled by a call to HUE api. It stores a value representing the current light status.
54
- node.HUEDeviceWhileDaytime = null// This retains the HUE device status while daytime, to be restored after nighttime elapsed.
55
- node.HUELightsBelongingToGroupWhileDaytime = null // Array contains all light belonging to the grouped_light (if grouped_light is selected)
56
- node.DayTime = true
57
- node.isGrouped_light = config.hueDevice.split('#')[1] === 'grouped_light'
58
- node.hueDevice = config.hueDevice.split('#')[0]
59
- node.initializingAtStart = (config.readStatusAtStartup === undefined || config.readStatusAtStartup === 'yes')
60
- config.specifySwitchOnBrightness = (config.specifySwitchOnBrightness === undefined || config.specifySwitchOnBrightness === '') ? 'temperature' : config.specifySwitchOnBrightness
61
- config.specifySwitchOnBrightnessNightTime = (config.specifySwitchOnBrightnessNightTime === undefined || config.specifySwitchOnBrightnessNightTime === '') ? 'no' : config.specifySwitchOnBrightnessNightTime
62
- config.colorAtSwitchOnDayTime = (config.colorAtSwitchOnDayTime === '' || config.colorAtSwitchOnDayTime === undefined) ? '{ "kelvin":3000, "brightness":100 }' : config.colorAtSwitchOnDayTime
63
- config.colorAtSwitchOnNightTime = (config.colorAtSwitchOnNightTime === '' || config.colorAtSwitchOnNightTime === undefined) ? '{ "kelvin":2700, "brightness":20 }' : config.colorAtSwitchOnNightTime
64
- config.colorAtSwitchOnDayTime = config.colorAtSwitchOnDayTime.replace('geen', 'green')
65
- config.colorAtSwitchOnNightTime = config.colorAtSwitchOnNightTime.replace('geen', 'green')
66
- config.dimSpeed = (config.dimSpeed === undefined || config.dimSpeed === '') ? 5000 : Number(config.dimSpeed)
67
- config.HSVDimSpeed = (config.HSVDimSpeed === undefined || config.HSVDimSpeed === '') ? 5000 : Number(config.HSVDimSpeed)
68
- config.invertDimTunableWhiteDirection = config.invertDimTunableWhiteDirection !== undefined
69
- config.restoreDayMode = config.restoreDayMode === undefined ? 'no' : config.restoreDayMode // no or setDayByFastSwitchLightSingle or setDayByFastSwitchLightALL
70
- config.updateLocalStateFromKNXWrite = config.updateLocalStateFromKNXWrite === true || config.updateLocalStateFromKNXWrite === 'true' // Starting from v 4.1.31
71
- node.timerCheckForFastLightSwitch = null
72
- config.invertDayNight = config.invertDayNight === undefined ? false : config.invertDayNight
73
- node.HSVObject = null // { h, s, v };// Store the current light calculated HSV
74
-
75
- // Transform HEX in RGB and stringified json in json oblects.
76
- if (config.colorAtSwitchOnDayTime.indexOf('#') !== -1) {
77
- // Transform to rgb.
78
- try {
79
- config.colorAtSwitchOnDayTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnDayTime.replace('#', ''))
80
- } catch (error) {
81
- config.colorAtSwitchOnDayTime = { kelvin: 3000, brightness: 100 }
82
- }
83
- } else {
84
- try {
85
- config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime)
86
- } catch (error) {
87
- RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnDayTime): ${error.message} : ${error.stack || ''} `)
88
- config.colorAtSwitchOnDayTime = ''
89
- }
90
- }
91
- // Same thing, but with night color
92
- if (config.colorAtSwitchOnNightTime.indexOf('#') !== -1) {
93
- // Transform to rgb.
94
- try {
95
- config.colorAtSwitchOnNightTime = hueColorConverter.ColorConverter.hexRgb(config.colorAtSwitchOnNightTime.replace('#', ''))
96
- } catch (error) {
97
- config.colorAtSwitchOnNightTime = { kelvin: 2700, brightness: 20 }
98
- }
99
- } else {
100
- try {
101
- config.colorAtSwitchOnNightTime = JSON.parse(config.colorAtSwitchOnNightTime)
102
- } catch (error) {
103
- RED.log.error(`knxUltimateHueLight: config.colorAtSwitchOnDayTime = JSON.parse(config.colorAtSwitchOnNightTime): ${error.message} : ${error.stack || ''} `)
104
- config.colorAtSwitchOnNightTime = ''
105
- }
106
- }
107
-
108
- const formatTs = (date) => {
109
- const d = date instanceof Date ? date : new Date(date)
110
- const provider = node.serverKNX
111
- if (provider && typeof provider.formatStatusTimestamp === 'function') return provider.formatStatusTimestamp(d)
112
- return `${d.getDate()}, ${d.toLocaleTimeString()}`
113
- }
114
-
115
- node.syncCurrentHUEDeviceFromKNXState = function syncCurrentHUEDeviceFromKNXState (_state) { // Starting from v 4.1.31
116
- if (config.updateLocalStateFromKNXWrite !== true) return // Starting from v 4.1.31
117
- if (_state === undefined || _state === null || typeof _state !== 'object') return // Starting from v 4.1.31
118
- if (node.currentHUEDevice === undefined || node.currentHUEDevice === null) return // Starting from v 4.1.31
119
- if (_state.on !== undefined && typeof _state.on.on === 'boolean') { // Starting from v 4.1.31
120
- if (node.currentHUEDevice.on === undefined || node.currentHUEDevice.on === null) node.currentHUEDevice.on = {} // Starting from v 4.1.31
121
- node.currentHUEDevice.on.on = _state.on.on // Starting from v 4.1.31
122
- } // Starting from v 4.1.31
123
- if (_state.dimming !== undefined && _state.dimming !== null && _state.dimming.brightness !== undefined) { // Starting from v 4.1.31
124
- if (node.currentHUEDevice.dimming === undefined || node.currentHUEDevice.dimming === null) node.currentHUEDevice.dimming = {} // Starting from v 4.1.31
125
- node.currentHUEDevice.dimming.brightness = _state.dimming.brightness // Starting from v 4.1.31
126
- } // Starting from v 4.1.31
127
- if (_state.color !== undefined && _state.color !== null && _state.color.xy !== undefined) { // Starting from v 4.1.31
128
- if (node.currentHUEDevice.color === undefined || node.currentHUEDevice.color === null) node.currentHUEDevice.color = {} // Starting from v 4.1.31
129
- node.currentHUEDevice.color.xy = cloneDeep(_state.color.xy) // Starting from v 4.1.31
130
- } // Starting from v 4.1.31
131
- if (_state.color_temperature !== undefined && _state.color_temperature !== null && _state.color_temperature.mirek !== undefined) { // Starting from v 4.1.31
132
- if (node.currentHUEDevice.color_temperature === undefined || node.currentHUEDevice.color_temperature === null) node.currentHUEDevice.color_temperature = {} // Starting from v 4.1.31
133
- node.currentHUEDevice.color_temperature.mirek = _state.color_temperature.mirek // Starting from v 4.1.31
134
- } // Starting from v 4.1.31
135
- } // Starting from v 4.1.31
136
-
137
- // Used to call the status update from the config node.
138
- node.setNodeStatus = ({
139
- fill, shape, text, payload
140
- }) => {
141
- try {
142
- if (node.currentHUEDevice?.on?.on === true) { fill = 'blue'; shape = 'dot' } else { fill = 'blue'; shape = 'ring' };
143
- if (payload === undefined) payload = ''
144
- const dDate = new Date()
145
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
146
- node.sKNXNodeStatusText = `|KNX: ${text} ${payload} (${formatTs(dDate)})`
147
- node.status({ fill, shape, text: (node.sHUENodeStatusText || '') + ' ' + (node.sKNXNodeStatusText || '') })
148
- } catch (error) { }
149
- }
150
- // Used to call the status update from the HUE config node.
151
- node.setNodeStatusHue = ({ fill, shape, text, payload }) => {
152
- try {
153
- if (node.currentHUEDevice?.on?.on === true) { fill = 'blue'; shape = 'dot' } else { fill = 'blue'; shape = 'ring' };
154
- if (payload === undefined) payload = ''
155
- const dDate = new Date()
156
- payload = typeof payload === 'object' ? JSON.stringify(payload) : payload.toString()
157
- node.sHUENodeStatusText = `|HUE: ${text} ${payload} (${formatTs(dDate)})`
158
- node.status({ fill, shape, text: node.sHUENodeStatusText + ' ' + (node.sKNXNodeStatusText || '') })
159
- } catch (error) { }
160
- }
161
-
162
- node.writeHueState = function writeHueState (_state) {
163
- const defaultOperation = node.isGrouped_light === false ? 'setLight' : 'setGroupedLight'
164
- const isGroupedLightOff = node.isGrouped_light === true && node.currentHUEDevice?.on?.on === false
165
- const stateKeys = _state && typeof _state === 'object' ? Object.keys(_state) : []
166
- const presetKeys = ['dimming', 'color', 'color_temperature', 'gradient']
167
- const actionableKeys = ['dimming', ...presetKeys]
168
- const hasActionablePayload = stateKeys.some((key) => actionableKeys.includes(key))
169
- const mustPresetGroupedLightChildren = isGroupedLightOff &&
170
- stateKeys.some((key) => presetKeys.includes(key))
171
-
172
- if (!mustPresetGroupedLightChildren) {
173
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
174
- return
175
- }
176
-
177
- (async () => {
178
- try {
179
- const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
180
- RED.log.debug(`knxUltimateHueLight: preset grouped_light children before group on. Group=${node.hueDevice} lights=${Array.isArray(groupLights) ? groupLights.length : 0}`)
181
- let hasWrittenAtLeastOneLight = false
182
- for (let index = 0; index < groupLights.length; index++) {
183
- const light = groupLights[index]
184
- if (!light?.id) continue
185
- const lightState = {}
186
- let hasActionableStateForLight = false
187
-
188
- if (_state.dimming !== undefined && light.dimming !== undefined) {
189
- lightState.dimming = cloneDeep(_state.dimming)
190
- hasActionableStateForLight = true
191
- }
192
- if (_state.color !== undefined && light.color !== undefined) {
193
- lightState.color = cloneDeep(_state.color)
194
- hasActionableStateForLight = true
195
- }
196
- if (_state.color_temperature !== undefined && light.color_temperature !== undefined) {
197
- lightState.color_temperature = cloneDeep(_state.color_temperature)
198
- hasActionableStateForLight = true
199
- }
200
- if (_state.gradient !== undefined && light.gradient !== undefined) {
201
- lightState.gradient = cloneDeep(_state.gradient)
202
- hasActionableStateForLight = true
203
- }
204
-
205
- if (!hasActionableStateForLight) continue
206
- node.serverHue.hueManager.writeHueQueueAdd(light.id, lightState, 'setLight')
207
- hasWrittenAtLeastOneLight = true
208
- }
209
-
210
- if (!hasWrittenAtLeastOneLight || !hasActionablePayload) {
211
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
212
- return
213
- }
214
-
215
- if (_state?.on?.on !== true) return
216
-
217
- const groupedLightState = { on: cloneDeep(_state.on) }
218
- if (_state.dynamics !== undefined) groupedLightState.dynamics = cloneDeep(_state.dynamics)
219
- RED.log.debug(`knxUltimateHueLight: turning on grouped_light after children preset. Group=${node.hueDevice}`)
220
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, groupedLightState, defaultOperation)
221
- } catch (error) {
222
- RED.log.debug(`knxUltimateHueLight: node.writeHueState fallback to grouped_light write: ${error.message}`)
223
- node.serverHue.hueManager.writeHueQueueAdd(node.hueDevice, _state, defaultOperation)
224
- }
225
- })()
226
- }
227
-
228
- node.deleteHueStateQueue = function deleteHueStateQueue () {
229
- node.serverHue.hueManager.deleteHueQueue(node.hueDevice)
230
- if (node.isGrouped_light !== true) return;
231
-
232
- (async () => {
233
- try {
234
- const groupLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
235
- for (let index = 0; index < groupLights.length; index++) {
236
- const light = groupLights[index]
237
- if (!light?.id) continue
238
- node.serverHue.hueManager.deleteHueQueue(light.id)
239
- }
240
- } catch (error) {
241
- RED.log.debug(`knxUltimateHueLight: node.deleteHueStateQueue: ${error.message}`)
242
- }
243
- })()
244
- }
245
-
246
- function getRandomIntInclusive (min, max) {
247
- min = Math.ceil(min)
248
- max = Math.floor(max)
249
- return Math.floor(Math.random() * (max - min + 1) + min) // The maximum is inclusive and the minimum is inclusive
250
- }
251
-
252
- // This function is called by the hue-config.js
253
- node.handleSend = (msg) => {
254
- if (node.currentHUEDevice === undefined && node.serverHue?.linkStatus === 'connected') {
255
- node.setNodeStatusHue({
256
- fill: 'yellow',
257
- shape: 'ring',
258
- text: 'Initializing. Please wait.',
259
- payload: ''
260
- })
261
- return
262
- }
263
- if (msg.knx.event !== 'GroupValue_Read' && node.currentHUEDevice !== undefined) {
264
- let state = {}
265
- try {
266
- switch (msg.knx.destination) {
267
- case config.GALightSwitch:
268
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightSwitch))
269
-
270
- // 15/05/2024 Supergiovane: check the Override to Day option
271
- // config.restoreDayMode can be: no or setDayByFastSwitchLightSingle or setDayByFastSwitchLightALL
272
- // ----------------------------------------------------------
273
- if (config.restoreDayMode === 'setDayByFastSwitchLightSingle' || config.restoreDayMode === 'setDayByFastSwitchLightALL') {
274
- if (node.DayTime === false) {
275
- if (msg.payload === true) {
276
- if (node.timerCheckForFastLightSwitch === null) {
277
- node.timerCheckForFastLightSwitch = setTimeout(() => {
278
- node.DayTime = false
279
- RED.log.debug('knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to false after node.timerCheckForFastLightSwitch elapsed')
280
- node.timerCheckForFastLightSwitch = null
281
- }, 10000) // 10 seconds
282
- } else {
283
- if (config.restoreDayMode === 'setDayByFastSwitchLightALL') {
284
- // Turn off the Day/Night group address
285
- if (config.GADaylightSensor !== undefined && config.GADaylightSensor !== '') {
286
- if (node.timerCheckForFastLightSwitch !== null) { clearTimeout(node.timerCheckForFastLightSwitch); node.timerCheckForFastLightSwitch = null }
287
- RED.log.debug(`knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime the group address ${config.GADaylightSensor}`)
288
- node.serverKNX.sendKNXTelegramToKNXEngine({
289
- grpaddr: config.GADaylightSensor,
290
- payload: config.invertDayNight === false,
291
- dpt: config.dptDaylightSensor,
292
- outputtype: 'write',
293
- nodecallerid: node.id
294
- })
295
- }
296
- }
297
- node.DayTime = true
298
- RED.log.debug('knxUltimateHueLight: node.timerCheckForFastLightSwitch: set daytime to true')
299
- }
300
- }
301
- }
302
- }
303
- // ----------------------------------------------------------
304
-
305
- if (msg.payload === true) {
306
- // From HUE Api core concepts:
307
- // If you try and control multiple conflicting parameters at once e.g. {"color": {"xy": {"x":0.5,"y":0.5}}, "color_temperature": {"mirek": 250}}
308
- // the lights can only physically do one, for this we apply the rule that xy beats ct. Simple.
309
- // color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
310
- if ((node.DayTime === true && config.specifySwitchOnBrightness === 'no') && ((node.isGrouped_light === false && node.HUEDeviceWhileDaytime !== null) || (node.isGrouped_light === true && node.HUELightsBelongingToGroupWhileDaytime !== null))) {
311
- if (node.isGrouped_light === false && node.HUEDeviceWhileDaytime !== null) {
312
- // The DayNight has switched into day, so restore the previous light status
313
- state = { on: { on: true }, dimming: node.HUEDeviceWhileDaytime.dimming, color: node.HUEDeviceWhileDaytime.color, color_temperature: node.HUEDeviceWhileDaytime.color_temperature }
314
- if (node.HUEDeviceWhileDaytime.color_temperature !== undefined && node.HUEDeviceWhileDaytime.color_temperature.mirek === null) delete state.color_temperature // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
315
- node.writeHueState(state)
316
- node.setNodeStatusHue({
317
- fill: 'green',
318
- shape: 'dot',
319
- text: 'KNX->HUE',
320
- payload: 'Restore light status'
321
- })
322
- node.HUEDeviceWhileDaytime = null // Nullize the object.
323
- } else if (node.isGrouped_light === true && node.HUELightsBelongingToGroupWhileDaytime !== null) {
324
- // The DayNight has switched into day, so restore the previous light state, belonging to the group
325
- let bAtLeastOneIsOn = false
326
- for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) { // Ensure, at least 1 lamp was on, otherwise turn all lamps on
327
- const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0]
328
- if (element.on.on === true) {
329
- bAtLeastOneIsOn = true
330
- break
331
- }
332
- }
333
- for (let index = 0; index < node.HUELightsBelongingToGroupWhileDaytime.length; index++) {
334
- const element = node.HUELightsBelongingToGroupWhileDaytime[index].light[0]
335
- if (bAtLeastOneIsOn === true) {
336
- state = { on: element.on, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature }
337
- } else {
338
- // Failsafe all on
339
- state = { on: { on: true }, dimming: element.dimming, color: element.color, color_temperature: element.color_temperature }
340
- }
341
- if (element.color_temperature !== undefined && element.color_temperature.mirek === null) delete state.color_temperature // Otherwise the lamp will not turn on due to an error. color_temperature.mirek: color temperature in mirek is null when the light color is not in the ct spectrum
342
- node.serverHue.hueManager.writeHueQueueAdd(element.id, state, 'setLight')
343
- }
344
- node.setNodeStatusHue({
345
- fill: 'green',
346
- shape: 'dot',
347
- text: 'KNX->HUE',
348
- payload: "Resuming all group's light"
349
- })
350
- node.HUELightsBelongingToGroupWhileDaytime = null // Nullize the object.
351
- return
352
- }
353
- } else {
354
- let colorChoosen
355
- let temperatureChoosen
356
- let brightnessChoosen
357
- // The light must support the temperature (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
358
- if (node.currentHUEDevice.color_temperature !== undefined) {
359
- if (node.DayTime === true && config.specifySwitchOnBrightness === 'temperature') {
360
- temperatureChoosen = config.colorAtSwitchOnDayTime.kelvin
361
- } else if (node.DayTime === false && config.enableDayNightLighting === 'temperature') {
362
- temperatureChoosen = config.colorAtSwitchOnNightTime.kelvin
363
- }
364
- }
365
- if (node.currentHUEDevice.dimming !== undefined) {
366
- // Check wether the user selected specific brightness at switch on (in this case, colorAtSwitchOnNightTime is an object {kelvin:xx, brightness:yy})
367
- if (node.DayTime === true && config.specifySwitchOnBrightness === 'temperature') {
368
- brightnessChoosen = config.colorAtSwitchOnDayTime.brightness
369
- } else if (node.DayTime === false && config.enableDayNightLighting === 'temperature') {
370
- brightnessChoosen = config.colorAtSwitchOnNightTime.brightness
371
- }
372
- }
373
- if (node.currentHUEDevice.color !== undefined) {
374
- // Check wether the user selected specific color at switch on (in this case, colorAtSwitchOnDayTime is a text with HTML web color)
375
- if (node.DayTime === true && config.specifySwitchOnBrightness === 'yes') {
376
- colorChoosen = config.colorAtSwitchOnDayTime
377
- } else if (node.DayTime === false && config.enableDayNightLighting === 'yes') {
378
- colorChoosen = config.colorAtSwitchOnNightTime
379
- }
380
- }
381
- // Create the HUE command
382
- if (colorChoosen !== undefined) {
383
- // Now we have a jColorChoosen. Proceed illuminating the light
384
- let gamut = null
385
- if (node.currentHUEDevice.color.gamut !== undefined) {
386
- gamut = node.currentHUEDevice.color.gamut
387
- }
388
- const dretXY = hueColorConverter.ColorConverter.calculateXYFromRGB(colorChoosen.red, colorChoosen.green, colorChoosen.blue, gamut)
389
- const dbright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(colorChoosen.red, colorChoosen.green, colorChoosen.blue)
390
- node.currentHUEDevice.dimming.brightness = Math.round(dbright, 0)
391
- if (node.currentHUEDevice.color !== undefined) node.currentHUEDevice.color.xy = dretXY // 26/03/2024
392
- node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness)
393
- state = dbright > 0 ? { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } } : { on: { on: false } }
394
- // state = { on: { on: true }, dimming: { brightness: dbright }, color: { xy: dretXY } };
395
- } else if (temperatureChoosen !== undefined) {
396
- // Kelvin
397
- const mirek = hueColorConverter.ColorConverter.kelvinToMirek(temperatureChoosen)
398
- node.currentHUEDevice.color_temperature.mirek = mirek
399
- node.currentHUEDevice.dimming.brightness = brightnessChoosen
400
- node.updateKNXBrightnessState(node.currentHUEDevice.dimming.brightness)
401
- // Kelvin temp
402
- state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek } } : { on: { on: false } }
403
- // state = { on: { on: true }, dimming: { brightness: brightnessChoosen }, color_temperature: { mirek: mirek } };
404
- } else if (brightnessChoosen !== undefined) {
405
- state = brightnessChoosen > 0 ? { on: { on: true }, dimming: { brightness: brightnessChoosen } } : { on: { on: false } }
406
- // state = { on: { on: true }, dimming: { brightness: brightnessChoosen } };
407
- } else {
408
- state = { on: { on: true } }
409
- }
410
- }
411
- } else {
412
- // Stop color cycle
413
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
414
- // Stop Blinking
415
- if (node.timerBlink !== undefined) clearInterval(node.timerBlink)
416
- state = { on: { on: false } }
417
- }
418
-
419
- node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
420
- node.writeHueState(state)
421
- node.setNodeStatusHue({
422
- fill: 'green',
423
- shape: 'dot',
424
- text: 'KNX->HUE',
425
- payload: state
426
- })
427
- break
428
- case config.GALightDIM:
429
- // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
430
- // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
431
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
432
- node.hueDimming(msg.payload.decr_incr, msg.payload.data, config.dimSpeed)
433
- node.setNodeStatusHue({
434
- fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
435
- })
436
- break
437
- case config.GALightHSV_H_DIM:
438
- // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
439
- // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
440
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
441
- node.hueDimmingHSV_H(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed)
442
- node.setNodeStatusHue({
443
- fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
444
- })
445
- break
446
- case config.GALightHSV_S_DIM:
447
- // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
448
- // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
449
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightDIM))
450
- node.hueDimmingHSV_S(msg.payload.decr_incr, msg.payload.data, config.HSVDimSpeed)
451
- node.setNodeStatusHue({
452
- fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
453
- })
454
- break
455
- case config.GALightKelvin:
456
- let retMirek
457
- let kelvinValue = 0
458
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvin))
459
- if (config.dptLightKelvin === '7.600') {
460
- if (msg.payload > 6535) msg.payload = 6535
461
- if (msg.payload < 2000) msg.payload = 2000
462
- kelvinValue = msg.payload// hueColorConverter.ColorConverter.scale(msg.payload, [0, 65535], [2000, 6535]);
463
- retMirek = hueColorConverter.ColorConverter.kelvinToMirek(kelvinValue)
464
- } else if (config.dptLightKelvin === '9.002') {
465
- // Relative temperature in Kelvin. Use HUE scale.
466
- if (msg.payload > 6535) msg.payload = 6535
467
- if (msg.payload < 2000) msg.payload = 2000
468
- retMirek = hueColorConverter.ColorConverter.kelvinToMirek(msg.payload)
469
- }
470
- state = { color_temperature: { mirek: retMirek } }
471
- node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
472
- node.writeHueState(state)
473
- node.setNodeStatusHue({
474
- fill: 'green',
475
- shape: 'dot',
476
- text: 'KNX->HUE',
477
- payload: kelvinValue
478
- })
479
- break
480
- case config.GADaylightSensor:
481
- node.DayTime = Boolean(dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptDaylightSensor)))
482
- if (config.invertDayNight === true) node.DayTime = !node.DayTime
483
- if (config.specifySwitchOnBrightness === 'no') {
484
- // This retains the HUE device status while daytime, to be restored after nighttime elapsed. https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/298
485
- if (node.DayTime === false) {
486
- if (node.isGrouped_light === false) node.HUEDeviceWhileDaytime = cloneDeep(node.currentHUEDevice) // DayTime has switched to false: save the currentHUEDevice into the HUEDeviceWhileDaytime
487
- if (node.isGrouped_light === true) {
488
- (async () => {
489
- try {
490
- const retLights = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
491
- node.HUELightsBelongingToGroupWhileDaytime = cloneDeep(retLights) // DayTime has switched to false: save the lights belonging to the group into the HUELightsBelongingToGroupWhileDaytime array
492
- } catch (error) { /* empty */ }
493
- })()
494
- }
495
- }
496
- } else {
497
- node.HUEDeviceWhileDaytime = null
498
- node.HUELightsBelongingToGroupWhileDaytime = null
499
- }
500
- node.setNodeStatusHue({
501
- fill: 'green',
502
- shape: 'dot',
503
- text: 'KNX->HUE Daytime',
504
- payload: node.DayTime
505
- })
506
-
507
- break
508
- case config.GALightKelvinDIM:
509
- if (config.dptLightKelvinDIM === '3.007') {
510
- // MDT smartbutton will dim the color temperature
511
- // { decr_incr: 1, data: 1 } : Start increasing until { decr_incr: 0, data: 0 } is received.
512
- // { decr_incr: 0, data: 1 } : Start decreasing until { decr_incr: 0, data: 0 } is received.
513
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinDIM))
514
- node.hueDimmingTunableWhite(msg.payload.decr_incr, msg.payload.data, 5000)
515
- node.setNodeStatusHue({
516
- fill: 'green', shape: 'dot', text: 'KNX->HUE', payload: JSON.stringify(msg.payload)
517
- })
518
- }
519
- break
520
- case config.GALightKelvinPercentage:
521
- if (config.dptLightKelvinPercentage === '5.001') {
522
- // 0-100% tunable white
523
- msg.payload = 100 - dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightKelvinPercentage))
524
- // msg.payload = msg.payload <= 0 ? 1 : msg.payload
525
- const retMirek = hueColorConverter.ColorConverter.scale(msg.payload, [0, 100], [153, 500])
526
- msg.payload = retMirek
527
- state = { color_temperature: { mirek: msg.payload } }
528
- node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
529
- node.writeHueState(state)
530
- node.setNodeStatusHue({
531
- fill: 'green',
532
- shape: 'dot',
533
- text: 'KNX->HUE',
534
- payload: state
535
- })
536
- }
537
- break
538
- case config.GALightBrightness:
539
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBrightness))
540
- if (typeof msg.payload !== 'number' || Number.isNaN(msg.payload)) throw new Error('Invalid KNX brightness payload')
541
- state = { dimming: { brightness: msg.payload } }
542
- if (msg.payload === 0) {
543
- state.on = { on: false }
544
- } else if (node.currentHUEDevice !== undefined && node.currentHUEDevice.on?.on === true) {
545
- state.on = { on: true }
546
- }
547
- node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
548
- node.writeHueState(state)
549
- node.setNodeStatusHue({
550
- fill: 'green',
551
- shape: 'dot',
552
- text: 'KNX->HUE',
553
- payload: state
554
- })
555
- break
556
- case config.GALightColor:
557
- msg.payload = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColor))
558
- let gamut = null
559
- if (
560
- node.currentHUEDevice !== undefined &&
561
- node.currentHUEDevice.color !== undefined &&
562
- node.currentHUEDevice.color.gamut !== undefined
563
- ) {
564
- gamut = node.currentHUEDevice.color.gamut
565
- }
566
- const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(msg.payload.red, msg.payload.green, msg.payload.blue, gamut)
567
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(msg.payload.red, msg.payload.green, msg.payload.blue)
568
- state = { dimming: { brightness: bright }, color: { xy: retXY } }
569
- if (node.currentHUEDevice === undefined) {
570
- // Grouped light
571
- state.on = { on: bright > 0 }
572
- } else {
573
- // Light
574
- if (node.currentHUEDevice.on.on === false && bright > 0) state.on = { on: true }
575
- if (node.currentHUEDevice.on.on === true && bright === 0) state = { on: { on: false }, dimming: { brightness: bright } }
576
- }
577
- node.syncCurrentHUEDeviceFromKNXState(state) // Starting from v 4.1.31
578
- node.writeHueState(state)
579
- node.setNodeStatusHue({
580
- fill: 'green',
581
- shape: 'dot',
582
- text: 'KNX->HUE',
583
- payload: state
584
- })
585
- break
586
- case config.GALightBlink:
587
- const gaVal = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightBlink))
588
- if (gaVal) {
589
- node.timerBlink = setInterval(() => {
590
- if (node.blinkValue === undefined) node.blinkValue = true
591
- node.blinkValue = !node.blinkValue
592
- msg.payload = node.blinkValue
593
- // state = msg.payload === true ? { on: { on: true } } : { on: { on: false } }
594
- state = msg.payload === true
595
- ? { on: { on: true }, dimming: { brightness: 100 }, dynamics: { duration: 0 } }
596
- : { on: { on: false }, dimming: { brightness: 0 }, dynamics: { duration: 0 } }
597
- node.writeHueState(state)
598
- }, 1500)
599
- } else {
600
- if (node.timerBlink !== undefined) clearInterval(node.timerBlink)
601
- node.writeHueState({ on: { on: false } })
602
- }
603
- node.setNodeStatusHue({
604
- fill: 'green',
605
- shape: 'dot',
606
- text: 'KNX->HUE',
607
- payload: gaVal
608
- })
609
- break
610
- case config.GALightColorCycle:
611
- {
612
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
613
- const gaValColorCycle = dptlib.fromBuffer(msg.knx.rawValue, dptlib.resolve(config.dptLightColorCycle))
614
- if (gaValColorCycle === true) {
615
- node.writeHueState({ on: { on: true } })
616
- node.timerColorCycle = setInterval(() => {
617
- try {
618
- const red = getRandomIntInclusive(0, 255)
619
- const green = getRandomIntInclusive(0, 255)
620
- const blue = getRandomIntInclusive(0, 255)
621
- let gamut = null
622
- if (
623
- node.currentHUEDevice !== undefined &&
624
- node.currentHUEDevice.color !== undefined &&
625
- node.currentHUEDevice.color.gamut !== undefined
626
- ) {
627
- gamut = node.currentHUEDevice.color.gamut
628
- }
629
- const retXY = hueColorConverter.ColorConverter.calculateXYFromRGB(red, green, blue, gamut)
630
- const bright = hueColorConverter.ColorConverter.getBrightnessFromRGBOrHex(red, green, blue)
631
- state = bright > 0 ? { on: { on: true }, dimming: { brightness: bright }, color: { xy: retXY } } : { on: { on: false } }
632
- node.writeHueState(state)
633
- } catch (error) { }
634
- }, 10000)
635
- } else {
636
- if (node.timerColorCycle !== undefined) clearInterval(node.timerColorCycle)
637
- node.writeHueState({ on: { on: false } })
638
- }
639
- node.setNodeStatusHue({
640
- fill: 'green',
641
- shape: 'dot',
642
- text: 'KNX->HUE',
643
- payload: gaValColorCycle
644
- })
645
- }
646
- break
647
- default:
648
- break
649
- }
650
- } catch (error) {
651
- node.status({
652
- fill: 'red',
653
- shape: 'dot',
654
- text: `KNX->HUE errorRead ${error.message} (${formatTs(new Date())})`
655
- })
656
- RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event !== "GroupValue_Read"): ${error.message} : ${error.stack || ''} `)
657
- }
658
- }
659
-
660
- // I must respond to query requests (read request) sent from the KNX BUS
661
- try {
662
- if (msg.knx.event === 'GroupValue_Read' && node.currentHUEDevice !== undefined) {
663
- const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')
664
- let ret
665
- switch (msg.knx.destination) {
666
- case config.GALightState:
667
- ret = node.currentHUEDevice.on.on
668
- if (ret !== undefined) node.updateKNXLightState(ret, 'response')
669
- break
670
- case config.GALightColorState:
671
- ret = node.currentHUEDevice.color.xy
672
- if (ret !== undefined) node.updateKNXLightColorState(node.currentHUEDevice.color, 'response')
673
- break
674
- case config.GALightKelvinPercentageState:
675
- // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
676
- ret = node.currentHUEDevice.color_temperature.mirek
677
- if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, 'response')
678
- // if (node.isGrouped_light === false) {
679
- // ret = node.currentHUEDevice.color_temperature.mirek;
680
- // if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
681
- // } else {
682
- // (async () => {
683
- // try {
684
- // // Find the first light in the collection, having the color_temperature capabilities
685
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
686
- // for (let index = 0; index < devices.length; index++) {
687
- // const element = devices[index];
688
- // if (element.light[0].color_temperature !== undefined) {
689
- // ret = element.light[0].color_temperature.mirek;
690
- // break;
691
- // }
692
- // }
693
- // if (ret !== undefined) node.updateKNXLightKelvinPercentageState(ret, "response");
694
- // } catch (error) { /* empty */ }
695
- // })();
696
- // }
697
- break
698
- case config.GALightBrightnessState:
699
- // Hue keeps the last brightness even when the light is OFF. If the user enabled "brightness status -> 0 on HUE off",
700
- // keep returning 0 while OFF to avoid the KNX status jumping back to the last/start value after some time/read-requests.
701
- if (zeroBrightnessWhenOff === true && node.currentHUEDevice?.on?.on === false) {
702
- ret = 0
703
- } else {
704
- ret = node.currentHUEDevice.dimming.brightness
705
- }
706
- if (ret !== undefined) node.updateKNXBrightnessState(ret, 'response')
707
- break
708
- case config.GALightKelvinState:
709
- // The kelvin level belongs to the group defice, so i don't need to get the first light in the collection (if the device is a grouped_light)
710
- ret = node.currentHUEDevice.color_temperature.mirek
711
- if (ret !== undefined) node.updateKNXLightKelvinState(ret, 'response')
712
- // if (node.isGrouped_light === false) {
713
- // ret = node.currentHUEDevice.color_temperature.mirek;
714
- // if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
715
- // } else {
716
- // (async () => {
717
- // try {
718
- // // Find the first light in the collection, having the color_temperature capabilities
719
- // const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false);
720
- // for (let index = 0; index < devices.length; index++) {
721
- // const element = devices[index];
722
- // if (element.light[0].color_temperature !== undefined) {
723
- // ret = element.light[0].color_temperature.mirek;
724
- // break;
725
- // }
726
- // }
727
- // if (ret !== undefined) node.updateKNXLightKelvinState(ret, "response");
728
- // } catch (error) { /* empty */ }
729
- // })();
730
- // }
731
- break
732
- default:
733
- break
734
- }
735
- }
736
- } catch (error) {
737
- node.status({
738
- fill: 'red',
739
- shape: 'dot',
740
- text: `KNX->HUE error :-( ${error.message} (${formatTs(new Date())})`
741
- })
742
- RED.log.error(`knxUltimateHueLight: node.handleSend: if (msg.knx.event === "GroupValue_Read" && node.currentHUEDevice !== undefined): ${error.message} : ${error.stack || ''} `)
743
- }
744
- }
745
-
746
- // Start dimming
747
- // ***********************************************************
748
- node.hueDimming = function hueDimming (_KNXaction, _KNXbrightness_Direction, _dimSpeedInMillisecs = undefined) {
749
- // 31/10/2023 after many attempts to use dimming_delta function of the HueApeV2, loosing days of my life, without a decent success, will use the standard dimming calculations
750
- // i decide to go to the "step brightness" way.
751
- try {
752
- let hueTelegram = {}
753
- let numStep = 10 // Steps from 0 to 100 by 10
754
- const extendedConf = {}
755
-
756
- // DPT 3.x uses data/step-code 0 for BREAK. The direction bit may be
757
- // either 0 ($00) or 1 ($08), so it must not be part of this check.
758
- if (_KNXbrightness_Direction === 0) {
759
- // STOP DIM
760
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
761
- node.brightnessStep = null
762
- node.deleteHueStateQueue() // Clear dimming queue.
763
- return
764
- }
765
-
766
- // 26/03/2024 set the extended configuration as well, because the light was off (so i've been unable to set it up elsewhere)
767
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
768
- // if (node.currentHUEDevice.color !== undefined) extendedConf.color = { xy: node.currentHUEDevice.color.xy }; // DO NOT ADD THE COLOR, BECAUSE THE COLOR HAS ALSO THE BRIGHTNESS, SO ALL THE DATA NEEDED TO BE SWITCHED ON CORRECLY
769
- if (node.currentHUEDevice.color_temperature !== undefined) extendedConf.color_temperature = { mirek: node.currentHUEDevice.color_temperature.mirek }
770
- }
771
-
772
- // If i'm dimming up while the light is off, start the dim with the initial brightness set to zero
773
- if (_KNXbrightness_Direction > 0 && _KNXaction === 1 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
774
- node.brightnessStep = null
775
- node.currentHUEDevice.dimming.brightness = 0
776
- }
777
-
778
- // Set the actual brightness to start with
779
- if (node.brightnessStep === null || node.brightnessStep === undefined) node.brightnessStep = node.currentHUEDevice.dimming.brightness !== undefined ? node.currentHUEDevice.dimming.brightness : 50
780
- node.brightnessStep = Math.ceil(Number(node.brightnessStep))
781
-
782
- // We have also minDimLevelLight and maxDimLevelLight to take care of.
783
- let minDimLevelLight
784
- if (config.minDimLevelLight === undefined) {
785
- minDimLevelLight = 10
786
- } else if (config.minDimLevelLight === 'useHueLightLevel') {
787
- minDimLevelLight = node.currentHUEDevice.dimming.min_dim_level === undefined ? 10 : node.currentHUEDevice.dimming.min_dim_level
788
- } else {
789
- minDimLevelLight = Number(config.minDimLevelLight)
790
- }
791
- const maxDimLevelLight = config.maxDimLevelLight === undefined ? 100 : Number(config.maxDimLevelLight)
792
-
793
- // Set the speed
794
- _dimSpeedInMillisecs /= numStep
795
- numStep = Math.round((maxDimLevelLight - minDimLevelLight) / numStep, 0)
796
-
797
- if (_KNXbrightness_Direction > 0 && _KNXaction === 1) {
798
- // DIM UP
799
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
800
- node.timerStepDim = setInterval(() => {
801
- node.updateKNXBrightnessState(node.brightnessStep) // Unnecessary, but necessary to set the KNX Status in real time.
802
- node.brightnessStep += numStep
803
- if (node.brightnessStep > maxDimLevelLight) node.brightnessStep = maxDimLevelLight
804
- hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } } // + is to avoid ladder effect
805
- // Switch on the light if off
806
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
807
- hueTelegram.on = { on: true }
808
- Object.assign(hueTelegram, extendedConf) // 26/03/2024 add extended conf
809
- }
810
- // console.log(hueTelegram)
811
- node.writeHueState(hueTelegram)
812
- if (node.brightnessStep >= maxDimLevelLight) clearInterval(node.timerStepDim)
813
- }, _dimSpeedInMillisecs)
814
- }
815
- if (_KNXbrightness_Direction > 0 && _KNXaction === 0) {
816
- if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
817
- // DIM DOWN
818
- if (node.timerStepDim !== undefined) clearInterval(node.timerStepDim)
819
- node.timerStepDim = setInterval(() => {
820
- node.updateKNXBrightnessState(node.brightnessStep) // Unnecessary, but necessary to set the KNX Status in real time.
821
- node.brightnessStep -= numStep
822
- if (node.brightnessStep < minDimLevelLight) node.brightnessStep = minDimLevelLight
823
- hueTelegram = { dimming: { brightness: node.brightnessStep }, dynamics: { duration: _dimSpeedInMillisecs + 500 } }// + 100 is to avoid ladder effect
824
- // Switch off the light if on
825
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStep === 0) {
826
- hueTelegram.on = { on: false }
827
- }
828
- node.writeHueState(hueTelegram)
829
- if (node.brightnessStep <= minDimLevelLight) clearInterval(node.timerStepDim)
830
- }, _dimSpeedInMillisecs)
831
- }
832
- } catch (error) { }
833
- }
834
- // ***********************************************************
835
-
836
- // Start dimming tunable white
837
- // mirek: required(integer minimum: 153, maximum: 500)
838
- // ***********************************************************
839
- node.hueDimmingTunableWhite = function hueDimmingTunableWhite (_KNXaction, _KNXbrightness_DirectionTunableWhite, _dimSpeedInMillisecsTunableWhite = undefined) {
840
- // 23/23/2023 after many attempts to use dimming_delta function of the HueApeV2, loosing days of my life, without a decent success, will use the standard dimming calculations
841
- // i decide to go to the "step brightness" way.
842
- try {
843
- if (_KNXbrightness_DirectionTunableWhite === 0) {
844
- // STOP DIM
845
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
846
- node.brightnessStepTunableWhite = null
847
- node.deleteHueStateQueue() // Clear dimming queue.
848
- return
849
- }
850
-
851
- let numStepTunableWhite = 10 // Steps from 153 to 500
852
- if (config.invertDimTunableWhiteDirection === true) {
853
- if (_KNXaction === 1) { _KNXaction = 0 } else { _KNXaction = 1 }
854
- }
855
-
856
- // Set the actual brightness to start with
857
- if (node.brightnessStepTunableWhite === null || node.brightnessStepTunableWhite === undefined) node.brightnessStepTunableWhite = node.currentHUEDevice.color_temperature.mirek || 372
858
- node.brightnessStepTunableWhite = Math.ceil(Number(node.brightnessStepTunableWhite))
859
-
860
- // Set the speed
861
- _dimSpeedInMillisecsTunableWhite = Math.ceil(_dimSpeedInMillisecsTunableWhite / numStepTunableWhite)
862
-
863
- const minDimLevelLightTunableWhite = 153
864
- const maxDimLevelLightTunableWhite = 500
865
- // numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [0, 100], [minDimLevelLightTunableWhite, maxDimLevelLightTunableWhite]);
866
- // numStepTunableWhite = hueColorConverter.ColorConverter.scale(numStepTunableWhite, [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite], [node.brightnessStepTunableWhite, maxDimLevelLightTunableWhite]);
867
- numStepTunableWhite = Math.round((maxDimLevelLightTunableWhite - minDimLevelLightTunableWhite) / numStepTunableWhite, 0)
868
-
869
- if (_KNXbrightness_DirectionTunableWhite > 0 && _KNXaction === 1) {
870
- // DIM UP
871
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
872
- node.timerStepDimTunableWhite = setInterval(() => {
873
- node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite) // Unnecessary, but necessary to set the KNX Status in real time.
874
- node.brightnessStepTunableWhite += numStepTunableWhite // *2 to speed up the things
875
- if (node.brightnessStepTunableWhite > maxDimLevelLightTunableWhite) node.brightnessStepTunableWhite = maxDimLevelLightTunableWhite
876
- const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } }
877
- // Switch on the light if off
878
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
879
- hueTelegram.on = { on: true }
880
- }
881
- node.writeHueState(hueTelegram)
882
- if (node.brightnessStepTunableWhite >= maxDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite)
883
- }, _dimSpeedInMillisecsTunableWhite)
884
- }
885
- if (_KNXbrightness_DirectionTunableWhite > 0 && _KNXaction === 0) {
886
- if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
887
- // DIM DOWN
888
- if (node.timerStepDimTunableWhite !== undefined) clearInterval(node.timerStepDimTunableWhite)
889
- node.timerStepDimTunableWhite = setInterval(() => {
890
- node.updateKNXLightKelvinPercentageState(node.brightnessStepTunableWhite) // Unnecessary, but necessary to set the KNX Status in real time.
891
- node.brightnessStepTunableWhite -= numStepTunableWhite // *2 to speed up the things
892
- if (node.brightnessStepTunableWhite < minDimLevelLightTunableWhite) node.brightnessStepTunableWhite = minDimLevelLightTunableWhite
893
- const hueTelegram = { color_temperature: { mirek: node.brightnessStepTunableWhite }, dynamics: { duration: _dimSpeedInMillisecsTunableWhite } }
894
- // Switch off the light if on
895
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepTunableWhite === 0) {
896
- hueTelegram.on = { on: false }
897
- }
898
- node.writeHueState(hueTelegram)
899
- if (node.brightnessStepTunableWhite <= minDimLevelLightTunableWhite) clearInterval(node.timerStepDimTunableWhite)
900
- }, _dimSpeedInMillisecsTunableWhite)
901
- }
902
- } catch (error) { }
903
- }
904
- // ***********************************************************
905
-
906
- /**
907
- * Starts dimming / stop dimming of the HUE
908
- * @param {number} _KNXaction 1 for start, 0 for stop
909
- * @param {number} _KNXbrightness_DirectionHSV_H 1 for up, 0 for down
910
- * @param {number} _dimSpeedInMillisecsHSV Speed time in milliseconds
911
- * @returns {}
912
- */
913
- node.hueDimmingHSV_H = function hueDimmingHSV_H (_KNXaction, _KNXbrightness_DirectionHSV_H, _dimSpeedInMillisecsHSV = undefined) {
914
- // After many attempts to use dimming_delta function of the HueApiV2, loosing days of my life, without a decent success, will use the standard dimming calculations
915
- // i decide to go to the "step brightness" way.
916
- try {
917
- if (_KNXbrightness_DirectionHSV_H === 0) {
918
- // STOP DIM
919
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
920
- node.deleteHueStateQueue() // Clear dimming queue.
921
- return
922
- }
923
-
924
- let xyBrightnessToHsv
925
- if (node.currentHUEDevice.color !== undefined && node.currentHUEDevice.color.xy !== undefined) {
926
- // Get the XY + brightness from the lamp and transform it into HSV
927
- // xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(node.currentHUEDevice.color.xy.x, node.currentHUEDevice.color.xy.y, node.currentHUEDevice.dimming.brightness);
928
- xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness)
929
- } else {
930
- return // Something wrong here.
931
- }
932
- let numStepHSV_H = 10 // Steps from 0 to 100
933
-
934
- // Set the actual brightness to start with
935
- if (node.brightnessStepHSV_H === null || node.brightnessStepHSV_H === undefined) node.brightnessStepHSV_H = node.currentHUEDevice.dimming.brightness
936
- node.brightnessStepHSV_H = Math.ceil(Number(node.brightnessStepHSV_H))
937
-
938
- const minDimLevelLightHSV_H = 1
939
- const maxDimLevelLightHSV_H = 100
940
- numStepHSV_H = Math.round((maxDimLevelLightHSV_H - minDimLevelLightHSV_H) / numStepHSV_H, 0)
941
- // Set the speed
942
- _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_H / numStepHSV_H))
943
-
944
- if (_KNXbrightness_DirectionHSV_H > 0 && _KNXaction === 1) {
945
- // DIM UP
946
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
947
- node.timerStepDimHSV_H = setInterval(() => {
948
- node.deleteHueStateQueue() // Clear dimming queue.
949
- node.brightnessStepHSV_H += numStepHSV_H
950
- if (node.brightnessStepHSV_H > maxDimLevelLightHSV_H) node.brightnessStepHSV_H = maxDimLevelLightHSV_H
951
- // node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
952
- xyBrightnessToHsv.h = node.brightnessStepHSV_H
953
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
954
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } } // Add some ms, to prevent the "ladder" step effect.
955
- // Switch on the light if off
956
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
957
- hueTelegram.on = { on: true }
958
- }
959
- node.currentHUEDevice.color.xy = hsvToXYBri// Unnecessary, but necessary to set the KNX Status in real time.
960
- node.updateKNXLightColorState(node.currentHUEDevice.color)
961
- node.writeHueState(hueTelegram)
962
- if (node.brightnessStepHSV_H >= maxDimLevelLightHSV_H) {
963
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
964
- }
965
- }, _dimSpeedInMillisecsHSV)
966
- }
967
- if (_KNXbrightness_DirectionHSV_H > 0 && _KNXaction === 0) {
968
- if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
969
- // DIM DOWN
970
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
971
- node.timerStepDimHSV_H = setInterval(() => {
972
- node.deleteHueStateQueue() // Clear dimming queue.
973
- node.brightnessStepHSV_H -= numStepHSV_H // *2 to speed up the things
974
- if (node.brightnessStepHSV_H < minDimLevelLightHSV_H) node.brightnessStepHSV_H = minDimLevelLightHSV_H
975
- // node.updateKNXLightHSV_H_State(node.brightnessStepHSV_H); // Unnecessary, but necessary to set the KNX Status in real time.
976
- // Produco l'RGB
977
- xyBrightnessToHsv.h = node.brightnessStepHSV_H
978
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
979
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }
980
- // Switch off the light if on
981
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepHSV_H === 0) {
982
- hueTelegram.on = { on: false }
983
- }
984
- node.currentHUEDevice.color.xy = hsvToXYBri// Unnecessary, but necessary to set the KNX Status in real time.
985
- node.updateKNXLightColorState(node.currentHUEDevice.color)
986
- node.writeHueState(hueTelegram)
987
- if (node.brightnessStepHSV_H <= minDimLevelLightHSV_H) {
988
- if (node.timerStepDimHSV_H !== undefined) clearInterval(node.timerStepDimHSV_H)
989
- }
990
- }, _dimSpeedInMillisecsHSV)
991
- }
992
- } catch (error) { /* empty */ }
993
- }
994
- /**
995
- * Starts dimming / stop dimming of the Saturation
996
- * @param {number} _KNXaction 1 for start, 0 for stop
997
- * @param {number} _KNXbrightness_DirectionHSV_S 1 for up, 0 for down
998
- * @param {number} _dimSpeedInMillisecsHSV Speed time in milliseconds
999
- * @returns {}
1000
- */
1001
- node.hueDimmingHSV_S = function hueDimmingHSV_S (_KNXaction, _KNXbrightness_DirectionHSV_S, _dimSpeedInMillisecsHSV = undefined) {
1002
- // After many attempts to use dimming_delta function of the HueApiV2, loosing days of my life, without a decent success, will use the standard dimming calculations
1003
- // i decide to go to the "step brightness" way.
1004
- try {
1005
- if (_KNXbrightness_DirectionHSV_S === 0) {
1006
- // STOP DIM
1007
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1008
- node.deleteHueStateQueue() // Clear dimming queue.
1009
- return
1010
- }
1011
-
1012
- let xyBrightnessToHsv
1013
- if (node.currentHUEDevice.color !== undefined && node.currentHUEDevice.color.xy !== undefined) {
1014
- // Get the XY + brightness from the lamp and transform it into HSV
1015
- xyBrightnessToHsv = hueColorConverter.ColorConverter.xyBrightnessToHsv(hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.x, [0, 1], [0, 100]), hueColorConverter.ColorConverter.scale(node.currentHUEDevice.color.xy.y, [0, 1], [0, 100]), node.currentHUEDevice.dimming.brightness)
1016
- } else {
1017
- return // Something wrong here.
1018
- }
1019
- let numStepHSV_S = 10 // Steps from 0 to 100
1020
-
1021
- // Set the actual brightness to start with
1022
- if (node.brightnessStepHSV_S === null || node.brightnessStepHSV_S === undefined) node.brightnessStepHSV_S = node.currentHUEDevice.dimming.brightness
1023
- node.brightnessStepHSV_S = Math.ceil(Number(node.brightnessStepHSV_S))
1024
-
1025
- const minDimLevelLightHSV_S = 1
1026
- const maxDimLevelLightHSV_S = 100
1027
- numStepHSV_S = Math.round((maxDimLevelLightHSV_S - minDimLevelLightHSV_S) / numStepHSV_S, 0)
1028
- // Set the speed
1029
- _dimSpeedInMillisecsHSV = Math.ceil(_dimSpeedInMillisecsHSV / (maxDimLevelLightHSV_S / numStepHSV_S))
1030
-
1031
- if (_KNXbrightness_DirectionHSV_S > 0 && _KNXaction === 1) {
1032
- // DIM UP
1033
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1034
- node.timerStepDimHSV_S = setInterval(() => {
1035
- node.deleteHueStateQueue() // Clear dimming queue.
1036
- node.brightnessStepHSV_S += numStepHSV_S
1037
- if (node.brightnessStepHSV_S > maxDimLevelLightHSV_S) node.brightnessStepHSV_S = maxDimLevelLightHSV_S
1038
- // node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1039
- xyBrightnessToHsv.s = node.brightnessStepHSV_S
1040
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
1041
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } } // Add some ms, to prevent the "ladder" step effect.
1042
- // Switch on the light if off
1043
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false) {
1044
- hueTelegram.on = { on: true }
1045
- }
1046
- node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri)// Unnecessary, but necessary to set the KNX Status in real time.
1047
- node.updateKNXLightColorState(node.currentHUEDevice.color)
1048
- node.writeHueState(hueTelegram)
1049
- if (node.brightnessStepHSV_S >= maxDimLevelLightHSV_S) {
1050
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1051
- }
1052
- }, _dimSpeedInMillisecsHSV)
1053
- }
1054
- if (_KNXbrightness_DirectionHSV_S > 0 && _KNXaction === 0) {
1055
- if (node.currentHUEDevice.on.on === false) return // Don't dim down, if the light is already off.
1056
- // DIM DOWN
1057
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1058
- node.timerStepDimHSV_S = setInterval(() => {
1059
- node.deleteHueStateQueue() // Clear dimming queue.
1060
- node.brightnessStepHSV_S -= numStepHSV_S // *2 to speed up the things
1061
- if (node.brightnessStepHSV_S < minDimLevelLightHSV_S) node.brightnessStepHSV_S = minDimLevelLightHSV_S
1062
- // node.updateKNXLightHSV_S_State(node.brightnessStepHSV_S); // Unnecessary, but necessary to set the KNX Status in real time.
1063
- // Produco l'RGB
1064
- xyBrightnessToHsv.s = node.brightnessStepHSV_S
1065
- const hsvToXYBri = hueColorConverter.ColorConverter.hsvToxyBrightness(xyBrightnessToHsv, node.currentHUEDevice.color.gamut)
1066
- const hueTelegram = { color: { xy: { x: hsvToXYBri.x, y: hsvToXYBri.y } }, dynamics: { duration: _dimSpeedInMillisecsHSV + 500 } }
1067
- // Switch off the light if on
1068
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true && node.brightnessStepHSV_S === 0) {
1069
- hueTelegram.on = { on: false }
1070
- }
1071
- node.currentHUEDevice.color.xy = cloneDeep(hsvToXYBri)// Unnecessary, but necessary to set the KNX Status in real time.
1072
- node.updateKNXLightColorState(node.currentHUEDevice.color)
1073
- node.writeHueState(hueTelegram)
1074
- if (node.brightnessStepHSV_S <= minDimLevelLightHSV_S) {
1075
- if (node.timerStepDimHSV_S !== undefined) clearInterval(node.timerStepDimHSV_S)
1076
- }
1077
- }, _dimSpeedInMillisecsHSV)
1078
- }
1079
- } catch (error) { /* empty */ }
1080
- }
1081
- // ***********************************************************
1082
-
1083
- node.handleSendHUE = async (_event) => {
1084
- if (_event === undefined) return
1085
- if (_event.type !== 'grouped_light' && _event.type !== 'light') return
1086
-
1087
- // !!!! >>> if the node is a grouped_light, the only values required, thus present, by HUE apis are "on" and "dimming".
1088
- // !!!! >>> For all others properties like for example color and tunable white, i must get the data from one of the child lights.
1089
-
1090
- // (async () => {
1091
- try {
1092
- if (node.currentHUEDevice === undefined || node.serverHue === null || node.serverHue === undefined) {
1093
- node.setNodeStatusHue({
1094
- fill: 'red',
1095
- shape: 'ring',
1096
- text: "Rejected HUE light settings. I'm still not ready...",
1097
- payload: ''
1098
- })
1099
- return
1100
- }
1101
-
1102
- const receivedHUEObject = cloneDeep(_event)
1103
-
1104
- // #region "CALCULATE COLOR AND COLOR TEMPERATURE OF THE LIGHTS BELONGING TO THE GROUPED_LIGHT"
1105
- // Check wether the incoming _event belongs to a light belonging to the group_light
1106
- if (node.isGrouped_light === true && receivedHUEObject.type === 'light') {
1107
- // Handling of not by HUE handled Color Temperature and ColorXY
1108
- let modifiedLight
1109
- const groupChilds = []
1110
- let AverageColorsXYBrightnessAndTemperature // Average color xy and color temp if the node is a grouped light.
1111
- // If the current node is a grouped lights, i must check wether the receivedHUEObject (containing a light) belongs to the node lights collection.
1112
- // Find all the lights in the collection, having the color_temperature capabilities, belonging to the group.
1113
- const devices = await node.serverHue.getAllLightsBelongingToTheGroup(node.hueDevice, false)
1114
- if (devices.length === 0) {
1115
- devices.push(receivedHUEObject)
1116
- }
1117
-
1118
- for (let index = 0; index < devices.length; index++) {
1119
- const element = devices[index]
1120
- if (receivedHUEObject.id === element.id) {
1121
- modifiedLight = element
1122
- // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness //if (receivedHUEObject.dimming !== undefined) modifiedLight.dimming = { brightness: receivedHUEObject.dimming.brightness };
1123
- if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) modifiedLight.color = receivedHUEObject.color
1124
- if (receivedHUEObject.color_temperature !== undefined) modifiedLight.color_temperature = receivedHUEObject.color_temperature
1125
- groupChilds.push(modifiedLight)
1126
- } else {
1127
- // Simply append the light
1128
- if ((element.color_temperature !== undefined && element.color_temperature.mirek !== undefined) ||
1129
- (element.color !== undefined && element.color.xy !== undefined)) {
1130
- groupChilds.push(element)
1131
- }
1132
- }
1133
- }
1134
-
1135
- // Use the arithmetic average of color xy, brightness and color temperature "averageColorXYandKelvinOfGroupedLights"
1136
- if (groupChilds !== undefined) AverageColorsXYBrightnessAndTemperature = await node.serverHue.getAverageColorsXYBrightnessAndTemperature(groupChilds)
1137
-
1138
- // Set the new values based on average calculated above
1139
- // CHECK FIRST THE COLOR_TEMPERATURE, because it can be undefined, because the current selected color
1140
- // is out of the mirek range, so it cannot be represented with the colore temperature.
1141
- if (receivedHUEObject.color_temperature !== undefined && AverageColorsXYBrightnessAndTemperature.mirek !== undefined && receivedHUEObject.color_temperature.mirel_valid === true) {
1142
- receivedHUEObject.color_temperature.mirek = AverageColorsXYBrightnessAndTemperature.mirek
1143
- node.currentHUEDevice.color_temperature = { mirek: AverageColorsXYBrightnessAndTemperature.mirek }
1144
- node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek)
1145
- node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek)
1146
- } else if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined && AverageColorsXYBrightnessAndTemperature.x !== undefined) {
1147
- receivedHUEObject.color.xy.x = AverageColorsXYBrightnessAndTemperature.x
1148
- receivedHUEObject.color.xy.y = AverageColorsXYBrightnessAndTemperature.y
1149
- node.currentHUEDevice.color = { xy: { x: AverageColorsXYBrightnessAndTemperature.x, y: AverageColorsXYBrightnessAndTemperature.y } }
1150
- node.updateKNXLightColorState(receivedHUEObject.color)
1151
- }
1152
- // The dimming is not necessary, beacause the HUE API already sends a group_light event with the average brightness
1153
- // if (receivedHUEObject.dimming !== undefined && AverageColorsXYBrightnessAndTemperature.brightness !== undefined) {
1154
- // receivedHUEObject.dimming = { brightness: AverageColorsXYBrightnessAndTemperature.brightness };
1155
- // }
1156
- // --------------------------------------------------------------------------------------------------
1157
- if (modifiedLight !== undefined && modifiedLight.metadata !== undefined && modifiedLight.metadata.name !== undefined) {
1158
- receivedHUEObject.lightName = modifiedLight.metadata.name
1159
- }
1160
- node.send(receivedHUEObject)
1161
- return
1162
- }
1163
- // #endregion
1164
-
1165
- if (receivedHUEObject.id === node.hueDevice) {
1166
- // Output the msg to the flow
1167
- node.send(receivedHUEObject)
1168
-
1169
- // // DEBUG testing enable/disable HTML UI Tabs
1170
- // delete _event.dimming;
1171
- // delete _event.color;
1172
- // delete _event.color_temperature;
1173
- // delete _event.color_temperature_delta;
1174
-
1175
- if (receivedHUEObject.on !== undefined) {
1176
- node.updateKNXLightState(receivedHUEObject.on.on)
1177
- // In case of switch off, set the dim to zero
1178
- if (receivedHUEObject.on.on === false && (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')) {
1179
- node.updateKNXBrightnessState(0)
1180
- if (receivedHUEObject.dimming !== undefined) delete receivedHUEObject.dimming // Remove event.dimming, because has beem handled by this function and i don't want the function below to take care of it.
1181
- } else if (receivedHUEObject.on.on === true && node.currentHUEDevice.on.on === false) {
1182
- // Turn on: update the dimming KNX Status value as well, but only if we have a reliable value.
1183
- // For grouped_light, the bridge exposes an aggregated brightness value via /resource/grouped_light/{id}.
1184
- let brightVal
1185
- if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
1186
- brightVal = receivedHUEObject.dimming.brightness
1187
- } else if (node.isGrouped_light === true && typeof node.serverHue?.getHueResourceSnapshot === 'function' && config.GALightBrightnessState) {
1188
- try {
1189
- const snapshot = await node.serverHue.getHueResourceSnapshot(node.hueDevice, { forceRefresh: true })
1190
- if (snapshot?.dimming?.brightness !== undefined) brightVal = snapshot.dimming.brightness
1191
- } catch (error) { /* empty */ }
1192
- } else if (node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness !== undefined) {
1193
- brightVal = node.currentHUEDevice.dimming.brightness
1194
- }
1195
- if (brightVal !== undefined) node.updateKNXBrightnessState(brightVal)
1196
- }
1197
- node.currentHUEDevice.on.on = receivedHUEObject.on.on
1198
- }
1199
-
1200
- if (receivedHUEObject.color !== undefined && receivedHUEObject.color.xy !== undefined) { // fixed https://github.com/Supergiovane/node-red-contrib-knx-ultimate/issues/287
1201
- node.updateKNXLightColorState(receivedHUEObject.color)
1202
- node.currentHUEDevice.color = receivedHUEObject.color
1203
- }
1204
-
1205
- if (receivedHUEObject.dimming !== undefined && receivedHUEObject.dimming.brightness !== undefined) {
1206
- const zeroBrightnessWhenOff = (config.updateKNXBrightnessStatusOnHUEOnOff === undefined || config.updateKNXBrightnessStatusOnHUEOnOff === 'onhueoff')
1207
- // Once upon n a time, the light transmit the brightness value of 0.39.
1208
- // To avoid wrongly turn light state on, exit
1209
- if (receivedHUEObject.dimming.brightness < 1) receivedHUEObject.dimming.brightness = 0
1210
- // If the light is OFF and the user wants KNX brightness status to stay 0 while OFF,
1211
- // don't propagate Hue's cached brightness (usually the last/boot brightness) back to KNX.
1212
- if (zeroBrightnessWhenOff === true && node.currentHUEDevice?.on?.on === false && (receivedHUEObject.on === undefined || receivedHUEObject.on.on === false)) {
1213
- if (node.currentHUEDevice.dimming !== undefined) node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness
1214
- } else if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && receivedHUEObject.dimming.brightness === 0) {
1215
- // Do nothing, because the light is off and the dimming also is 0
1216
- } else {
1217
- if (node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === false && (receivedHUEObject.on === undefined || (receivedHUEObject.on !== undefined && receivedHUEObject.on.on === true))) node.updateKNXLightState(receivedHUEObject.dimming.brightness > 0)
1218
- node.updateKNXBrightnessState(receivedHUEObject.dimming.brightness)
1219
- // If the brightness reaches zero, the hue lamp "on" property must be set to zero as well
1220
- if (receivedHUEObject.dimming.brightness === 0 && node.currentHUEDevice.on !== undefined && node.currentHUEDevice.on.on === true) {
1221
- node.writeHueState({ on: { on: false } })
1222
- node.currentHUEDevice.on.on = false
1223
- }
1224
- node.currentHUEDevice.dimming.brightness = receivedHUEObject.dimming.brightness
1225
- }
1226
- }
1227
-
1228
- if (receivedHUEObject.color_temperature !== undefined && receivedHUEObject.color_temperature.mirek !== undefined) {
1229
- node.updateKNXLightKelvinPercentageState(receivedHUEObject.color_temperature.mirek)
1230
- node.updateKNXLightKelvinState(receivedHUEObject.color_temperature.mirek)
1231
- node.currentHUEDevice.color_temperature.mirek = receivedHUEObject.color_temperature.mirek
1232
- }
1233
- }
1234
- } catch (error) {
1235
- node.status({
1236
- fill: 'red',
1237
- shape: 'dot',
1238
- text: `HUE->KNX error ${node.id} ${error.message}. Seee Log`
1239
- })
1240
- RED.log.error(`knxUltimateHueLight: node.handleSendHUE = (_event): ${error.stack}`)
1241
- }
1242
- // })();
1243
- }
1244
-
1245
- // Leave the name after "function", to avoid <anonymous function> in the stack trace, in caso of errors.
1246
- node.updateKNXBrightnessState = function updateKNXBrightnessState (_value, _outputtype = 'write') {
1247
- if (config.GALightBrightnessState !== undefined && config.GALightBrightnessState !== '') {
1248
- const knxMsgPayload = {}
1249
- knxMsgPayload.topic = config.GALightBrightnessState
1250
- knxMsgPayload.dpt = config.dptLightBrightnessState
1251
- knxMsgPayload.payload = _value
1252
- // Send to KNX bus
1253
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1254
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1255
- node.serverKNX.sendKNXTelegramToKNXEngine({
1256
- grpaddr: knxMsgPayload.topic,
1257
- payload: knxMsgPayload.payload,
1258
- dpt: knxMsgPayload.dpt,
1259
- outputtype: _outputtype,
1260
- nodecallerid: node.id
1261
- })
1262
- }
1263
- }
1264
- node.setNodeStatusHue({
1265
- fill: 'blue',
1266
- shape: 'ring',
1267
- text: 'HUE->KNX Bright',
1268
- payload: knxMsgPayload.payload
1269
- })
1270
- }
1271
- }
1272
-
1273
- node.updateKNXLightState = function updateKNXLightState (_value, _outputtype = 'write') {
1274
- try {
1275
- const knxMsgPayload = {}
1276
- knxMsgPayload.topic = config.GALightState
1277
- knxMsgPayload.dpt = config.dptLightState
1278
- knxMsgPayload.payload = _value
1279
- if (config.GALightState !== undefined && config.GALightState !== '') {
1280
- // Check not to have already sent the value
1281
- // Send to KNX bus
1282
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1283
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1284
- node.serverKNX.sendKNXTelegramToKNXEngine({
1285
- grpaddr: knxMsgPayload.topic,
1286
- payload: knxMsgPayload.payload,
1287
- dpt: knxMsgPayload.dpt,
1288
- outputtype: _outputtype,
1289
- nodecallerid: node.id
1290
- })
1291
- }
1292
- }
1293
- node.setNodeStatusHue({
1294
- fill: 'blue',
1295
- shape: 'ring',
1296
- text: 'HUE->KNX On/Off',
1297
- payload: knxMsgPayload.payload
1298
- })
1299
- }
1300
- } catch (error) {
1301
- /* empty */
1302
- }
1303
- }
1304
-
1305
- node.updateKNXLightKelvinPercentageState = function updateKNXLightKelvinPercentageState (_value, _outputtype = 'write') {
1306
- if (config.GALightKelvinPercentageState !== undefined && config.GALightKelvinPercentageState !== '') {
1307
- const knxMsgPayload = {}
1308
- knxMsgPayload.topic = config.GALightKelvinPercentageState
1309
- knxMsgPayload.dpt = config.dptLightKelvinPercentageState
1310
- if (config.dptLightKelvinPercentageState === '5.001') {
1311
- const retPercent = hueColorConverter.ColorConverter.scale(_value, [153, 500], [0, 100])
1312
- knxMsgPayload.payload = 100 - retPercent
1313
- }
1314
- // Send to KNX bus
1315
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1316
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1317
- node.serverKNX.sendKNXTelegramToKNXEngine({
1318
- grpaddr: knxMsgPayload.topic,
1319
- payload: knxMsgPayload.payload,
1320
- dpt: knxMsgPayload.dpt,
1321
- outputtype: _outputtype,
1322
- nodecallerid: node.id
1323
- })
1324
- }
1325
- }
1326
- node.setNodeStatusHue({
1327
- fill: 'blue',
1328
- shape: 'ring',
1329
- text: 'HUE->KNX Tunable White',
1330
- payload: knxMsgPayload.payload
1331
- })
1332
- }
1333
- }
1334
-
1335
- // /**
1336
- // * Update the internal HSV variable status and send the valuge in % to the KNX BUS
1337
- // * @param {number} _value 0-100%
1338
- // * @param {string} _outputtype "write" is the default KNX command
1339
- // * * @returns {}
1340
- // */
1341
- // node.updateKNXLightHSV_H_State = function updateKNXLightHSV_H_State(_value, _outputtype = "write") {
1342
- // if (config.GALightHSV_H_State !== undefined && config.GALightHSV_H_State !== "") {
1343
- // const knxMsgPayload = {};
1344
- // knxMsgPayload.topic = config.GALightHSV_H_State;
1345
- // knxMsgPayload.dpt = config.dptLightHSV_H_State;
1346
- // if (config.dptLightHSV_H_State === "5.001") {
1347
- // knxMsgPayload.payload = 100 - _value;
1348
- // }
1349
- // // Send to KNX bus
1350
- // if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1351
- // if (node.serverKNX !== null && node.serverKNX !== undefined) {
1352
- // node.serverKNX.sendKNXTelegramToKNXEngine({
1353
- // grpaddr: knxMsgPayload.topic,
1354
- // payload: knxMsgPayload.payload,
1355
- // dpt: knxMsgPayload.dpt,
1356
- // outputtype: _outputtype || "write",
1357
- // nodecallerid: node.id,
1358
- // });
1359
- // }
1360
- // }
1361
- // node.setNodeStatusHue({
1362
- // fill: "blue",
1363
- // shape: "ring",
1364
- // text: "HUE->KNX HSV (H)",
1365
- // payload: knxMsgPayload.payload,
1366
- // });
1367
- // }
1368
- // };
1369
-
1370
- // /**
1371
- // * Update the internal HSV variable status and send the valuge in % to the KNX BUS
1372
- // * @param {number} _value 0-100%
1373
- // * @param {string} _outputtype "write" is the default KNX command
1374
- // * @returns {}
1375
- // */
1376
- // node.updateKNXLightHSV_S_State = function updateKNXLightHSV_S_State(_value, _outputtype = "write") {
1377
- // if (config.GALightHSV_S_State !== undefined && config.GALightHSV_S_State !== "") {
1378
- // const knxMsgPayload = {};
1379
- // knxMsgPayload.topic = config.GALightHSV_S_State;
1380
- // knxMsgPayload.dpt = config.dptLightHSV_S_State;
1381
- // if (config.dptLightHSV_S_State === "5.001") {
1382
- // knxMsgPayload.payload = _value;
1383
- // }
1384
- // // Send to KNX bus
1385
- // if (knxMsgPayload.topic !== "" && knxMsgPayload.topic !== undefined) {
1386
- // if (node.serverKNX !== null && node.serverKNX !== undefined) {
1387
- // node.serverKNX.sendKNXTelegramToKNXEngine({
1388
- // grpaddr: knxMsgPayload.topic,
1389
- // payload: knxMsgPayload.payload,
1390
- // dpt: knxMsgPayload.dpt,
1391
- // outputtype: _outputtype || "write",
1392
- // nodecallerid: node.id,
1393
- // });
1394
- // }
1395
- // }
1396
- // node.setNodeStatusHue({
1397
- // fill: "blue",
1398
- // shape: "ring",
1399
- // text: "HUE->KNX HSV (H)",
1400
- // payload: knxMsgPayload.payload,
1401
- // });
1402
- // }
1403
- // };
1404
-
1405
- /**
1406
- * Update the KNC colors and HSV states group addresses
1407
- * @param {object} _value {xy:{x,y}} in 0-1 scale
1408
- * @param {string} _outputtype "write" is the default KNX command
1409
- * @returns {}
1410
- */
1411
- node.updateKNXLightColorState = function updateKNXLightColorState (_value, _outputtype = 'write') {
1412
- if (config.GALightColorState !== undefined && config.GALightColorState !== '') {
1413
- if (_value.xy === undefined || _value.xy.x === undefined) return
1414
- const knxMsgPayload = {}
1415
- knxMsgPayload.topic = config.GALightColorState
1416
- knxMsgPayload.dpt = config.dptLightColorState
1417
- try {
1418
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBriToRgb(
1419
- _value.xy.x,
1420
- _value.xy.y,
1421
- node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100
1422
- )
1423
- knxMsgPayload.payload = { red: knxMsgPayload.payload.r, green: knxMsgPayload.payload.g, blue: knxMsgPayload.payload.b }
1424
- // Send to KNX bus
1425
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1426
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1427
- node.serverKNX.sendKNXTelegramToKNXEngine({
1428
- grpaddr: knxMsgPayload.topic,
1429
- payload: knxMsgPayload.payload,
1430
- dpt: knxMsgPayload.dpt,
1431
- outputtype: _outputtype,
1432
- nodecallerid: node.id
1433
- })
1434
- }
1435
- }
1436
- node.setNodeStatusHue({
1437
- fill: 'blue',
1438
- shape: 'ring',
1439
- text: 'HUE->KNX Color',
1440
- payload: knxMsgPayload.payload
1441
- })
1442
- } catch (error) { }
1443
- }
1444
- if (config.GALightHSV_S_State !== undefined && config.GALightHSV_S_State !== '') {
1445
- const knxMsgPayload = {}
1446
- knxMsgPayload.topic = config.GALightHSV_S_State
1447
- knxMsgPayload.dpt = config.dptLightHSV_S_State
1448
- if (config.dptLightHSV_S_State === '5.001') {
1449
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false)
1450
- knxMsgPayload.payload = knxMsgPayload.payload.s
1451
- }
1452
- // Send to KNX bus
1453
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1454
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1455
- node.serverKNX.sendKNXTelegramToKNXEngine({
1456
- grpaddr: knxMsgPayload.topic,
1457
- payload: knxMsgPayload.payload,
1458
- dpt: knxMsgPayload.dpt,
1459
- outputtype: _outputtype || 'write',
1460
- nodecallerid: node.id
1461
- })
1462
- }
1463
- }
1464
- node.setNodeStatusHue({
1465
- fill: 'blue',
1466
- shape: 'ring',
1467
- text: 'HUE->KNX HSV (S)',
1468
- payload: knxMsgPayload.payload
1469
- })
1470
- }
1471
- if (config.GALightHSV_H_State !== undefined && config.GALightHSV_H_State !== '') {
1472
- const knxMsgPayload = {}
1473
- knxMsgPayload.topic = config.GALightHSV_H_State
1474
- knxMsgPayload.dpt = config.dptLightHSV_H_State
1475
- if (config.dptLightHSV_H_State === '5.001') {
1476
- knxMsgPayload.payload = hueColorConverter.ColorConverter.xyBrightnessToHsv(_value.xy.x, _value.xy.y, node.currentHUEDevice !== undefined && node.currentHUEDevice.dimming !== undefined && node.currentHUEDevice.dimming.brightness === undefined ? node.currentHUEDevice.dimming.brightness : 100, false)
1477
- knxMsgPayload.payload = 100 - knxMsgPayload.payload.h
1478
- }
1479
- // Send to KNX bus
1480
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1481
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1482
- node.serverKNX.sendKNXTelegramToKNXEngine({
1483
- grpaddr: knxMsgPayload.topic,
1484
- payload: knxMsgPayload.payload,
1485
- dpt: knxMsgPayload.dpt,
1486
- outputtype: _outputtype || 'write',
1487
- nodecallerid: node.id
1488
- })
1489
- }
1490
- }
1491
- node.setNodeStatusHue({
1492
- fill: 'blue',
1493
- shape: 'ring',
1494
- text: 'HUE->KNX HSV (H)',
1495
- payload: knxMsgPayload.payload
1496
- })
1497
- }
1498
- }
1499
-
1500
- node.updateKNXLightKelvinState = function updateKNXLightKelvinState (_value, _outputtype = 'write') {
1501
- if (config.GALightKelvinState !== undefined && config.GALightKelvinState !== '') {
1502
- const knxMsgPayload = {}
1503
- const kelvinValue = 0
1504
- knxMsgPayload.topic = config.GALightKelvinState
1505
- knxMsgPayload.dpt = config.dptLightKelvinState
1506
- if (config.dptLightKelvinState === '7.600') {
1507
- knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value)
1508
- // knxMsgPayload.payload = hueColorConverter.ColorConverter.scale(kelvinValue, [2000, 6535], [0, 65535]);
1509
- } else if (config.dptLightKelvinState === '9.002') {
1510
- knxMsgPayload.payload = hueColorConverter.ColorConverter.mirekToKelvin(_value)
1511
- }
1512
- // Send to KNX bus
1513
- if (knxMsgPayload.topic !== '' && knxMsgPayload.topic !== undefined) {
1514
- if (node.serverKNX !== null && node.serverKNX !== undefined) {
1515
- node.serverKNX.sendKNXTelegramToKNXEngine({
1516
- grpaddr: knxMsgPayload.topic,
1517
- payload: knxMsgPayload.payload,
1518
- dpt: knxMsgPayload.dpt,
1519
- outputtype: _outputtype,
1520
- nodecallerid: node.id
1521
- })
1522
- }
1523
-
1524
- node.setNodeStatusHue({
1525
- fill: 'blue',
1526
- shape: 'ring',
1527
- text: 'HUE->KNX Kelvin',
1528
- payload: knxMsgPayload.payload
1529
- })
1530
- }
1531
- }
1532
- }
1533
-
1534
- // On each deploy, unsubscribe+resubscribe
1535
- if (node.serverKNX) {
1536
- node.serverKNX.removeClient(node)
1537
- node.serverKNX.addClient(node)
1538
- }
1539
- if (node.serverHue) {
1540
- try {
1541
- node.serverHue.removeClient(node)
1542
- node.serverHue.addClient(node)
1543
- } catch (error) {
1544
- RED.log.error('knxUltimateHueLight: if (node.serverKNX): ' + error.message)
1545
- }
1546
- }
1547
-
1548
- node.on('input', (msg, send, done) => {
1549
- try {
1550
- const state = RED.util.cloneMessage(msg)
1551
- node.writeHueState(state)
1552
- node.setNodeStatusHue({
1553
- fill: 'green',
1554
- shape: 'dot',
1555
- text: '->HUE',
1556
- payload: 'Flow msg.'
1557
- })
1558
- } catch (error) {
1559
- node.setNodeStatusHue({
1560
- fill: 'red',
1561
- shape: 'dot',
1562
- text: '->HUE',
1563
- payload: error.message
1564
- })
1565
- }
1566
- // Once finished, call 'done'.
1567
- // This call is wrapped in a check that 'done' exists
1568
- // so the node will work in earlier versions of Node-RED (<1.0)
1569
- if (done) {
1570
- done()
1571
- }
1572
- })
1573
-
1574
- node.on('close', (done) => {
1575
- if (node.serverKNX) {
1576
- node.serverKNX.removeClient(node)
1577
- }
1578
- if (node.serverHue) {
1579
- node.serverHue.removeClient(node)
1580
- }
1581
- done()
1582
- })
1583
- }
1584
- RED.nodes.registerType('knxUltimateHueLight', knxUltimateHueLight)
1585
- }