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