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,462 +0,0 @@
1
- 'use strict'
2
-
3
- const UNIVERSAL_NODE_ID = '__UNIVERSAL__'
4
- const POWER_SOURCE_FEATURE_BATTERY = 0x02
5
-
6
- const setupUniversalProfile = (RED, node, config) => {
7
- node.name = config.name || node.matterDeviceName || 'Matter Universal Controller'
8
- node.topic = node.name
9
- node.matterProfile = 'universal'
10
- node.notifyreadrequest = true
11
- node.notifyresponse = false
12
- node.notifywrite = true
13
- node.listenallga = true
14
- node.outputtype = 'write'
15
- node.outputRBE = 'false'
16
- node.inputRBE = 'false'
17
- node.passthrough = 'no'
18
- const universalService = config.universalService || 'batteryMonitor'
19
- const lowBatteryGa = String(config.universalLowBatteryGA || '').trim()
20
- const lowBatteryTextGa = String(config.universalLowBatteryTextGA || '').trim()
21
- node.knxUltimateAcceptedGAs = [lowBatteryGa, lowBatteryTextGa].filter((ga) => ga !== '')
22
- const enabledUnlessFalse = (value) => value !== false && value !== 'false'
23
- const batteryOnlyLow = enabledUnlessFalse(config.universalBatteryOnlyLow)
24
- const emitInitialState = enabledUnlessFalse(config.universalEmitInitialState)
25
- const includeRawEvent = enabledUnlessFalse(config.universalIncludeRawEvent)
26
- const configuredBatteryThreshold = Number(config.universalBatteryThreshold ?? 20)
27
- const batteryThreshold = Number.isFinite(configuredBatteryThreshold)
28
- ? Math.min(100, Math.max(0, configuredBatteryThreshold))
29
- : 20
30
- const batteryStates = new Map()
31
- const lastEmittedBatteryStates = new Map()
32
- const deviceNames = new Map()
33
- const endpointNames = new Map()
34
- let lastKnxAlarm
35
- let lastLowKeys = ''
36
- let lowBatteryCycleTimer
37
- let lowBatteryCycleIndex = 0
38
- let currentLowBatteryText = ''
39
-
40
- const status = (fill, shape, text) => node.status({ fill, shape, text })
41
- const manager = () => node.serverMatter?.matterManager
42
- const valueFrom = (msg, key) => msg[key] !== undefined ? msg[key] : msg.matter?.[key]
43
- const batteryKey = (nodeId, endpointId) => `${String(nodeId)}/${Number(endpointId)}`
44
- const chargeLevelName = (value) => ['ok', 'warning', 'critical'][Number(value)] || value
45
- const replaceabilityName = (value) => ['unspecified', 'notReplaceable', 'userReplaceable', 'factoryReplaceable'][Number(value)] || value
46
- const isBatteryPowerSource = (state) => {
47
- const featureMap = Number(state.attributes.featureMap)
48
- return Number.isFinite(featureMap) && (featureMap & POWER_SOURCE_FEATURE_BATTERY) !== 0
49
- }
50
-
51
- const normalizedBattery = (state) => {
52
- const attributes = state.attributes
53
- const rawPercentRemaining = attributes.batPercentRemaining
54
- const percent = Number.isFinite(Number(rawPercentRemaining)) ? Number(rawPercentRemaining) / 2 : undefined
55
- const chargeLevel = attributes.batChargeLevel
56
- const replacementNeeded = attributes.batReplacementNeeded === true
57
- const lowBattery = (percent !== undefined && percent <= batteryThreshold) ||
58
- [1, 2, 'warning', 'critical'].includes(chargeLevel) ||
59
- replacementNeeded
60
- return {
61
- percent,
62
- rawPercentRemaining,
63
- chargeLevel: chargeLevel === undefined ? undefined : chargeLevelName(chargeLevel),
64
- replacementNeeded: attributes.batReplacementNeeded,
65
- replaceability: attributes.batReplaceability === undefined ? undefined : replaceabilityName(attributes.batReplaceability),
66
- voltageMv: attributes.batVoltage,
67
- status: attributes.status,
68
- lowBattery,
69
- threshold: batteryThreshold
70
- }
71
- }
72
-
73
- const batteryList = () => [...batteryStates.values()]
74
- .filter(isBatteryPowerSource)
75
- .map((state) => ({
76
- nodeId: state.nodeId,
77
- deviceName: state.deviceName,
78
- endpointId: state.endpointId,
79
- battery: normalizedBattery(state),
80
- lastSeen: state.lastSeen
81
- }))
82
-
83
- const sendKnx = (ga, payload, dpt, outputtype = 'write') => {
84
- if (ga === '' || !node.serverKNX?.sendKNXTelegramToKNXEngine) return
85
- node.serverKNX.sendKNXTelegramToKNXEngine({ grpaddr: ga, payload, dpt, outputtype, nodecallerid: node.id })
86
- }
87
-
88
- const lowBatteries = () => batteryList().filter((entry) => entry.battery.lowBattery)
89
- const batteryDisplayName = (entry) => String(entry.deviceName || `Matter ${entry.nodeId}/${entry.endpointId}`).slice(0, 14)
90
- const stopBatteryCycle = () => {
91
- if (lowBatteryCycleTimer) clearInterval(lowBatteryCycleTimer)
92
- lowBatteryCycleTimer = undefined
93
- }
94
- const sendNextLowBatteryName = () => {
95
- const entries = lowBatteries()
96
- if (entries.length === 0) return
97
- const entry = entries[lowBatteryCycleIndex % entries.length]
98
- lowBatteryCycleIndex = (lowBatteryCycleIndex + 1) % entries.length
99
- currentLowBatteryText = batteryDisplayName(entry)
100
- sendKnx(lowBatteryTextGa, currentLowBatteryText, '16.001')
101
- }
102
- const syncKnxBatteryOutputs = () => {
103
- const entries = lowBatteries()
104
- const alarm = entries.length > 0
105
- if (lastKnxAlarm !== alarm) {
106
- sendKnx(lowBatteryGa, alarm, '1.005')
107
- lastKnxAlarm = alarm
108
- }
109
- const lowKeys = entries.map((entry) => batteryKey(entry.nodeId, entry.endpointId)).sort().join(',')
110
- if (lowKeys === lastLowKeys) return
111
- lastLowKeys = lowKeys
112
- stopBatteryCycle()
113
- lowBatteryCycleIndex = 0
114
- if (!alarm) {
115
- currentLowBatteryText = ''
116
- sendKnx(lowBatteryTextGa, '', '16.001')
117
- return
118
- }
119
- sendNextLowBatteryName()
120
- lowBatteryCycleTimer = setInterval(sendNextLowBatteryName, 2000)
121
- lowBatteryCycleTimer.unref?.()
122
- }
123
-
124
- const refreshBatteryStatus = () => {
125
- const batteries = batteryList()
126
- const lowCount = batteries.filter((entry) => entry.battery.lowBattery).length
127
- status(lowCount > 0 ? 'yellow' : 'green', 'dot',
128
- lowCount > 0 ? `Batteries: ${batteries.length} (${lowCount} low)` : `Batteries: ${batteries.length}`)
129
- }
130
-
131
- const emitBatteryState = (state, source, rawEvent) => {
132
- const key = batteryKey(state.nodeId, state.endpointId)
133
- if (!isBatteryPowerSource(state)) {
134
- lastEmittedBatteryStates.delete(key)
135
- return
136
- }
137
- const battery = normalizedBattery(state)
138
- if (batteryOnlyLow && !battery.lowBattery) {
139
- lastEmittedBatteryStates.delete(key)
140
- return
141
- }
142
- const signature = JSON.stringify(battery)
143
- if (lastEmittedBatteryStates.get(key) === signature) return
144
- lastEmittedBatteryStates.set(key, signature)
145
- const timestamp = new Date().toISOString()
146
- node.send({
147
- topic: `matter/battery/${state.nodeId}/${state.endpointId}`,
148
- payload: {
149
- nodeId: state.nodeId,
150
- deviceName: state.deviceName,
151
- endpointId: state.endpointId,
152
- battery,
153
- timestamp
154
- },
155
- matter: {
156
- source,
157
- nodeId: state.nodeId,
158
- endpointId: state.endpointId,
159
- clusterId: 47,
160
- clusterName: rawEvent?.clusterName || 'PowerSource',
161
- attributeId: rawEvent?.attributeId,
162
- attributeName: rawEvent?.attributeName,
163
- value: rawEvent?.value,
164
- raw: includeRawEvent ? rawEvent : undefined
165
- }
166
- })
167
- syncKnxBatteryOutputs()
168
- refreshBatteryStatus()
169
- }
170
-
171
- const updateBatteryState = (event, source = 'batteryReport', emit = true) => {
172
- if (Number(event?.clusterId) !== 47 || event.attributeName === undefined) return
173
- const key = batteryKey(event.nodeId, event.endpointId)
174
- const state = batteryStates.get(key) || {
175
- nodeId: String(event.nodeId),
176
- deviceName: endpointNames.get(key) || deviceNames.get(String(event.nodeId)) || '',
177
- endpointId: Number(event.endpointId),
178
- attributes: {}
179
- }
180
- state.deviceName = endpointNames.get(key) || deviceNames.get(state.nodeId) || state.deviceName
181
- state.attributes[event.attributeName] = event.value
182
- state.lastSeen = new Date().toISOString()
183
- if (event.attributeName === 'featureMap' && !isBatteryPowerSource(state)) {
184
- batteryStates.delete(key)
185
- lastEmittedBatteryStates.delete(key)
186
- syncKnxBatteryOutputs()
187
- return
188
- }
189
- batteryStates.set(key, state)
190
- if (emit) {
191
- emitBatteryState(state, source, event)
192
- syncKnxBatteryOutputs()
193
- }
194
- }
195
-
196
- const scanBatterySnapshot = (nodeId) => {
197
- if (!node.serverMatter || !emitInitialState) return
198
- const details = node.serverMatter.getCommissionedNodesDetails?.() || []
199
- details.forEach((detail) => deviceNames.set(String(detail.nodeId), detail.name || ''))
200
- const selected = nodeId === undefined
201
- ? details
202
- : details.filter((detail) => String(detail.nodeId) === String(nodeId))
203
- selected.forEach((detail) => {
204
- try {
205
- const structure = node.serverMatter.getNodeStructure(String(detail.nodeId))
206
- ;(structure?.endpoints || []).forEach((endpoint) => {
207
- endpointNames.set(batteryKey(detail.nodeId, endpoint.endpointId), endpoint.name || detail.name || '')
208
- ;(endpoint.clusters || []).filter((cluster) => Number(cluster.id) === 47).forEach((cluster) => {
209
- const events = (cluster.attributes || [])
210
- .filter((attribute) => attribute.value !== undefined)
211
- .map((attribute) => ({
212
- nodeId: String(detail.nodeId),
213
- endpointId: Number(endpoint.endpointId),
214
- clusterId: 47,
215
- clusterName: cluster.name,
216
- attributeId: attribute.id,
217
- attributeName: attribute.name,
218
- value: attribute.value
219
- }))
220
- events.forEach((event) => updateBatteryState(event, 'batterySnapshot', false))
221
- const state = batteryStates.get(batteryKey(detail.nodeId, endpoint.endpointId))
222
- if (state) emitBatteryState(state, 'batterySnapshot', events.at(-1))
223
- })
224
- })
225
- } catch (error) {
226
- RED.log.debug(`knxUltimateMatterControllerDevice Universal battery snapshot: ${error.message}`)
227
- }
228
- })
229
- syncKnxBatteryOutputs()
230
- refreshBatteryStatus()
231
- }
232
-
233
- node.setNodeStatus = ({ fill = 'grey', shape = 'ring', text = '' } = {}) => {
234
- if (/disconnected|waiting|error/i.test(text)) status(fill, shape, text)
235
- }
236
-
237
- node.handleSend = (msg) => {
238
- if (msg?.knx?.event !== 'GroupValue_Read') return
239
- const destination = String(msg.knx.destination || '')
240
- if (destination === lowBatteryGa) sendKnx(lowBatteryGa, lowBatteries().length > 0, '1.005', 'response')
241
- if (destination === lowBatteryTextGa) sendKnx(lowBatteryTextGa, currentLowBatteryText, '16.001', 'response')
242
- }
243
-
244
- node.setNodeStatusMatter = (value) => {
245
- if (!value?.text) return
246
- if (/^(matter disconnected|waiting for matter controller)$/i.test(value.text)) {
247
- status(value.fill || 'red', value.shape || 'ring', value.text)
248
- return
249
- }
250
- if (universalService === 'batteryMonitor') {
251
- refreshBatteryStatus()
252
- return
253
- }
254
- status('green', 'dot', 'Universal Matter mode')
255
- }
256
-
257
- node.handleSendMatter = (event) => {
258
- try {
259
- if (!event || event.nodeId === undefined || event.endpointId === undefined || event.clusterId === undefined) return
260
- const attributeName = event.attributeName ?? event.attributeId ?? 'attribute'
261
- if (universalService === 'batteryMonitor') {
262
- updateBatteryState(event)
263
- return
264
- }
265
- const matter = {
266
- ...event,
267
- source: 'attributeReport',
268
- nodeId: String(event.nodeId),
269
- endpointId: Number(event.endpointId),
270
- clusterId: Number(event.clusterId),
271
- attributeName,
272
- value: event.value,
273
- timestamp: Date.now(),
274
- raw: event
275
- }
276
- node.send({
277
- topic: `matter/${matter.nodeId}/${matter.endpointId}/${matter.clusterId}/${attributeName}`,
278
- payload: event.value,
279
- matter
280
- })
281
- status('blue', 'dot', `Attribute: ${attributeName}`)
282
- } catch (error) {
283
- RED.log.error(`knxUltimateMatterControllerDevice Universal attribute: ${error.message}`)
284
- status('red', 'ring', error.message)
285
- }
286
- }
287
-
288
- node.handleMatterClusterEvent = (event) => {
289
- try {
290
- if (universalService === 'batteryMonitor') return
291
- if (!event || event.nodeId === undefined || event.endpointId === undefined || event.clusterId === undefined) return
292
- const eventName = event.eventName ?? event.eventId ?? 'event'
293
- const matter = {
294
- ...event,
295
- source: 'clusterEvent',
296
- nodeId: String(event.nodeId),
297
- endpointId: Number(event.endpointId),
298
- clusterId: Number(event.clusterId),
299
- eventName,
300
- timestamp: Date.now(),
301
- raw: event
302
- }
303
- node.send({
304
- topic: `matter/${matter.nodeId}/${matter.endpointId}/${matter.clusterId}/event/${eventName}`,
305
- payload: event.events !== undefined ? event.events : event.value,
306
- matter
307
- })
308
- status('blue', 'ring', `Event: ${eventName}`)
309
- } catch (error) {
310
- RED.log.error(`knxUltimateMatterControllerDevice Universal cluster event: ${error.message}`)
311
- status('red', 'ring', error.message)
312
- }
313
- }
314
-
315
- node.handleMatterNodeInitialized = (event) => {
316
- try {
317
- const nodeId = event && typeof event === 'object' ? event.nodeId : event
318
- if (universalService === 'batteryMonitor') {
319
- scanBatterySnapshot(nodeId)
320
- return
321
- }
322
- if (nodeId === undefined || nodeId === null || String(nodeId) === '') return
323
- node.send({
324
- topic: `matter/${String(nodeId)}/initialized`,
325
- payload: true,
326
- matter: {
327
- source: 'nodeInitialized',
328
- nodeId: String(nodeId),
329
- timestamp: Date.now(),
330
- raw: event
331
- }
332
- })
333
- status('green', 'dot', `Universal: node ${String(nodeId)}`)
334
- } catch (error) {
335
- RED.log.error(`knxUltimateMatterControllerDevice Universal initialization: ${error.message}`)
336
- status('red', 'ring', error.message)
337
- }
338
- }
339
-
340
- if (node.serverMatter) {
341
- node.serverMatter.removeClient(node)
342
- node.serverMatter.addClient(node)
343
- if (universalService === 'batteryMonitor') {
344
- Promise.resolve().then(() => scanBatterySnapshot()).catch((error) => {
345
- RED.log.error(`knxUltimateMatterControllerDevice Universal battery startup: ${error.message}`)
346
- })
347
- }
348
- } else {
349
- status('yellow', 'ring', 'Matter controller not ready')
350
- }
351
- if (node.serverKNX) {
352
- node.serverKNX.removeClient(node)
353
- node.serverKNX.addClient(node)
354
- }
355
-
356
- node.on('input', (msg, send, done) => {
357
- const output = typeof send === 'function' ? send : node.send.bind(node)
358
- Promise.resolve().then(async () => {
359
- const action = msg.action ?? msg.payload?.action ?? msg.matter?.action
360
- if (action === 'getAllBatteries') {
361
- output({
362
- ...msg,
363
- payload: batteryList(),
364
- matter: {
365
- ...(msg.matter || {}),
366
- source: 'getAllBatteries',
367
- timestamp: Date.now()
368
- }
369
- })
370
- refreshBatteryStatus()
371
- if (done) done()
372
- return
373
- }
374
- const nodeIdValue = valueFrom(msg, 'nodeId')
375
- const endpointIdValue = valueFrom(msg, 'endpointId')
376
- const clusterIdValue = valueFrom(msg, 'clusterId')
377
- const command = valueFrom(msg, 'command')
378
- const attribute = valueFrom(msg, 'attribute')
379
- if (nodeIdValue === undefined || nodeIdValue === null || String(nodeIdValue) === '' ||
380
- endpointIdValue === undefined || endpointIdValue === null || String(endpointIdValue).trim() === '' ||
381
- clusterIdValue === undefined || clusterIdValue === null || String(clusterIdValue).trim() === '') {
382
- throw new Error('Matter input requires nodeId, endpointId and clusterId')
383
- }
384
- if ((command === undefined || command === null || command === '') &&
385
- (attribute === undefined || attribute === null || attribute === '')) {
386
- throw new Error('Matter input requires command or attribute')
387
- }
388
- const currentManager = manager()
389
- if (!currentManager) throw new Error('Matter controller not ready')
390
- const nodeId = String(nodeIdValue)
391
- const endpointId = Number(endpointIdValue)
392
- const clusterId = Number(clusterIdValue)
393
- if (!Number.isFinite(endpointId) || !Number.isFinite(clusterId)) {
394
- throw new Error('Matter input requires nodeId, endpointId and clusterId')
395
- }
396
-
397
- if (command !== undefined && command !== null && command !== '') {
398
- await currentManager.writeMatterQueueAdd({
399
- nodeId,
400
- endpointId,
401
- clusterId,
402
- kind: 'command',
403
- name: command,
404
- args: valueFrom(msg, 'args') ?? {}
405
- })
406
- status('green', 'dot', `Matter command: ${command}`)
407
- if (done) done()
408
- return
409
- }
410
-
411
- const value = valueFrom(msg, 'value')
412
- if (value !== undefined) {
413
- await currentManager.writeMatterQueueAdd({
414
- nodeId,
415
- endpointId,
416
- clusterId,
417
- kind: 'attributeWrite',
418
- name: attribute,
419
- args: value
420
- })
421
- status('green', 'dot', `Matter write: ${attribute}`)
422
- if (done) done()
423
- return
424
- }
425
-
426
- const readValue = await currentManager.readAttribute(
427
- nodeId,
428
- endpointId,
429
- clusterId,
430
- attribute,
431
- valueFrom(msg, 'requestFromRemote') === true
432
- )
433
- output({
434
- ...msg,
435
- payload: readValue,
436
- matter: {
437
- ...(msg.matter || {}),
438
- source: 'inputRead',
439
- nodeId,
440
- endpointId,
441
- clusterId,
442
- attribute
443
- }
444
- })
445
- status('blue', 'dot', `Matter read: ${attribute}`)
446
- if (done) done()
447
- }).catch((error) => {
448
- status('red', 'ring', error.message)
449
- if (typeof done === 'function') done(error)
450
- else node.error(error, msg)
451
- })
452
- })
453
-
454
- node.on('close', (done) => {
455
- stopBatteryCycle()
456
- try { if (node.serverKNX) node.serverKNX.removeClient(node) } catch (error) { /* empty */ }
457
- try { if (node.serverMatter) node.serverMatter.removeClient(node) } catch (error) { /* empty */ }
458
- done()
459
- })
460
- }
461
-
462
- module.exports = { UNIVERSAL_NODE_ID, setupUniversalProfile }
@@ -1,19 +0,0 @@
1
- 'use strict'
2
-
3
- const { setupMappedEndpointProfile } = require('./mappedEndpoint')
4
-
5
- const WINDOW_COVERING_CLUSTER_ID = 0x0102
6
-
7
- const setupWindowCoveringProfile = (RED, node, config) => setupMappedEndpointProfile(RED, node, config, {
8
- profileName: 'windowCovering',
9
- eventClusterId: WINDOW_COVERING_CLUSTER_ID,
10
- formatAttributeStatus: (event) => {
11
- if (event.attributeName === 'currentPositionLiftPercent100ths' && event.value !== null && event.value !== undefined) {
12
- return `Matter cover: ${Math.round(Number(event.value) / 100)}%`
13
- }
14
- if (event.attributeName === 'operationalStatus') return 'Matter cover: operational status updated'
15
- return ''
16
- }
17
- })
18
-
19
- module.exports = { WINDOW_COVERING_CLUSTER_ID, setupWindowCoveringProfile }
@@ -1,212 +0,0 @@
1
- 'use strict'
2
-
3
- const { CLUSTER } = require('./matterKnxConverter')
4
-
5
- const normalizeToken = (value) => String(value || '').trim().toLowerCase().replace(/[^a-z0-9]/g, '')
6
-
7
- const requireNumber = (value, functionName, min, max) => {
8
- const numeric = Number(value)
9
- if (!Number.isFinite(numeric)) throw new Error(`Matter function "${functionName}" requires a numeric value`)
10
- if (min !== undefined && numeric < min) throw new Error(`Matter function "${functionName}" requires a value >= ${min}`)
11
- if (max !== undefined && numeric > max) throw new Error(`Matter function "${functionName}" requires a value <= ${max}`)
12
- return numeric
13
- }
14
-
15
- const requireBoolean = (value, functionName) => {
16
- if (value === true || value === 1 || value === '1' || normalizeToken(value) === 'true' || normalizeToken(value) === 'on') return true
17
- if (value === false || value === 0 || value === '0' || normalizeToken(value) === 'false' || normalizeToken(value) === 'off') return false
18
- throw new Error(`Matter function "${functionName}" requires true/false`)
19
- }
20
-
21
- const command = (clusterId, names, value) => ({
22
- clusterId,
23
- targetKind: 'command',
24
- names: Array.isArray(names) ? names : [names],
25
- value
26
- })
27
-
28
- const attribute = (clusterId, names, value, writableOnly = false) => ({
29
- clusterId,
30
- targetKind: 'attribute',
31
- names: Array.isArray(names) ? names : [names],
32
- value,
33
- writableOnly
34
- })
35
-
36
- // Friendly functions deliberately use the same names as the Matter Bridge where
37
- // the concepts overlap. Values use human units (percent, °C, lux, W and kWh).
38
- const SEMANTIC_FUNCTIONS = {
39
- onoff: {
40
- read: attribute(CLUSTER.ON_OFF, 'onOff'),
41
- write: (value) => {
42
- if (normalizeToken(value) === 'toggle') return command(CLUSTER.ON_OFF, 'toggle', false)
43
- const on = requireBoolean(value, 'onoff')
44
- return command(CLUSTER.ON_OFF, on ? 'on' : 'off', on)
45
- }
46
- },
47
- level: {
48
- read: attribute(CLUSTER.LEVEL_CONTROL, 'currentLevel'),
49
- write: (value) => command(CLUSTER.LEVEL_CONTROL, ['moveToLevelWithOnOff', 'moveToLevel'], requireNumber(value, 'level', 0, 100))
50
- },
51
- position: {
52
- read: attribute(CLUSTER.WINDOW_COVERING, ['currentPositionLiftPercent100ths', 'currentPositionLiftPercentage']),
53
- write: (value) => command(CLUSTER.WINDOW_COVERING, 'goToLiftPercentage', requireNumber(value, 'position', 0, 100))
54
- },
55
- tiltposition: {
56
- read: attribute(CLUSTER.WINDOW_COVERING, ['currentPositionTiltPercent100ths', 'currentPositionTiltPercentage']),
57
- write: (value) => command(CLUSTER.WINDOW_COVERING, 'goToTiltPercentage', requireNumber(value, 'tiltposition', 0, 100))
58
- },
59
- open: {
60
- write: () => command(CLUSTER.WINDOW_COVERING, 'upOrOpen', false)
61
- },
62
- close: {
63
- write: () => command(CLUSTER.WINDOW_COVERING, 'downOrClose', true)
64
- },
65
- stop: {
66
- write: () => command(CLUSTER.WINDOW_COVERING, 'stopMotion', undefined)
67
- },
68
- setpoint: {
69
- read: attribute(CLUSTER.THERMOSTAT, 'occupiedHeatingSetpoint'),
70
- write: (value) => attribute(CLUSTER.THERMOSTAT, 'occupiedHeatingSetpoint', requireNumber(value, 'setpoint'), true)
71
- },
72
- coolingsetpoint: {
73
- read: attribute(CLUSTER.THERMOSTAT, 'occupiedCoolingSetpoint'),
74
- write: (value) => attribute(CLUSTER.THERMOSTAT, 'occupiedCoolingSetpoint', requireNumber(value, 'coolingsetpoint'), true)
75
- },
76
- currenttemp: {
77
- read: attribute(CLUSTER.THERMOSTAT, 'localTemperature')
78
- },
79
- fanspeed: {
80
- read: attribute(CLUSTER.FAN_CONTROL, ['percentCurrent', 'percentSetting']),
81
- write: (value) => attribute(CLUSTER.FAN_CONTROL, 'percentSetting', requireNumber(value, 'fanspeed', 0, 100), true)
82
- },
83
- temperature: {
84
- read: attribute(CLUSTER.TEMPERATURE, 'measuredValue')
85
- },
86
- humidity: {
87
- read: attribute(CLUSTER.HUMIDITY, 'measuredValue')
88
- },
89
- illuminance: {
90
- read: attribute(CLUSTER.ILLUMINANCE, 'measuredValue')
91
- },
92
- occupancy: {
93
- read: attribute(CLUSTER.OCCUPANCY, 'occupancy')
94
- },
95
- contact: {
96
- read: attribute(CLUSTER.BOOLEAN_STATE, 'stateValue')
97
- },
98
- battery: {
99
- read: attribute(CLUSTER.POWER_SOURCE, 'batPercentRemaining')
100
- },
101
- activepower: {
102
- read: attribute(CLUSTER.ELECTRICAL_POWER, 'activePower')
103
- },
104
- importedenergy: {
105
- read: attribute(CLUSTER.ELECTRICAL_ENERGY, 'cumulativeEnergyImported')
106
- },
107
- identify: {
108
- write: () => command(CLUSTER.IDENTIFY, 'identify', undefined)
109
- }
110
- }
111
-
112
- const getInputStructure = (capabilities) => {
113
- if (!capabilities || typeof capabilities !== 'object') return undefined
114
- const structure = capabilities.inputStructure
115
- return structure && Array.isArray(structure.clusters) ? structure : undefined
116
- }
117
-
118
- const targetSupported = (capabilities, candidate) => {
119
- const structure = getInputStructure(capabilities)
120
- if (!structure) return true
121
- const cluster = structure.clusters.find((item) => Number(item.id) === Number(candidate.clusterId))
122
- if (!cluster) return false
123
- const collection = candidate.targetKind === 'command' ? cluster.commands : cluster.attributes
124
- if (!Array.isArray(collection)) return false
125
- return candidate.names.some((name) => collection.some((item) =>
126
- normalizeToken(item.name) === normalizeToken(name) &&
127
- (!candidate.writableOnly || item.writable === true)
128
- ))
129
- }
130
-
131
- const materializeTarget = (capabilities, candidate) => {
132
- if (!candidate) return undefined
133
- const structure = getInputStructure(capabilities)
134
- if (!structure) return { ...candidate, target: candidate.names[0] }
135
- const cluster = structure.clusters.find((item) => Number(item.id) === Number(candidate.clusterId))
136
- const collection = candidate.targetKind === 'command' ? cluster?.commands : cluster?.attributes
137
- if (!Array.isArray(collection)) return undefined
138
- for (const name of candidate.names) {
139
- const found = collection.find((item) =>
140
- normalizeToken(item.name) === normalizeToken(name) &&
141
- (!candidate.writableOnly || item.writable === true)
142
- )
143
- if (found) return { ...candidate, target: found.name }
144
- }
145
- return undefined
146
- }
147
-
148
- const semanticPayload = (msg) => {
149
- const payload = msg?.payload
150
- if (!payload || typeof payload !== 'object' || Array.isArray(payload) || Buffer.isBuffer(payload)) return undefined
151
- const rawFunction = payload.function ?? payload.fn
152
- if (rawFunction === undefined || rawFunction === null || String(rawFunction).trim() === '') return undefined
153
- return {
154
- functionName: normalizeToken(rawFunction),
155
- value: payload.value,
156
- requestFromRemote: payload.requestFromRemote === true || payload.remote === true
157
- }
158
- }
159
-
160
- const supportedSemanticFunctions = (capabilities) => Object.entries(SEMANTIC_FUNCTIONS)
161
- .filter(([, definition]) => {
162
- const readSupported = definition.read && targetSupported(capabilities, definition.read)
163
- const writeSupported = definition.write && [undefined, 0, true, false, 'toggle'].some((value) => {
164
- try {
165
- return targetSupported(capabilities, definition.write(value))
166
- } catch (error) {
167
- return false
168
- }
169
- })
170
- return readSupported || writeSupported
171
- })
172
- .map(([name]) => name)
173
-
174
- const resolveSemanticInput = (msg, capabilities) => {
175
- const input = semanticPayload(msg)
176
- if (!input) return undefined
177
- const definition = SEMANTIC_FUNCTIONS[input.functionName]
178
- if (!definition) {
179
- const supported = supportedSemanticFunctions(capabilities)
180
- throw new Error(`Unsupported Matter function "${input.functionName}"${supported.length ? `. Supported: ${supported.join(', ')}` : ''}`)
181
- }
182
- const wantsWrite = input.value !== undefined || !definition.read
183
- let candidate
184
- if (wantsWrite) {
185
- if (!definition.write) throw new Error(`Matter function "${input.functionName}" is read-only`)
186
- candidate = definition.write(input.value)
187
- } else {
188
- candidate = definition.read
189
- }
190
- const resolved = materializeTarget(capabilities, candidate)
191
- if (!resolved) throw new Error(`Matter endpoint does not support function "${input.functionName}"`)
192
- return {
193
- functionName: input.functionName,
194
- requestFromRemote: input.requestFromRemote,
195
- operation: wantsWrite ? 'write' : 'read',
196
- value: resolved.value,
197
- mapping: {
198
- endpointId: msg.endpointId,
199
- clusterId: resolved.clusterId,
200
- targetKind: resolved.targetKind,
201
- target: resolved.target
202
- }
203
- }
204
- }
205
-
206
- module.exports = {
207
- SEMANTIC_FUNCTIONS,
208
- normalizeToken,
209
- resolveSemanticInput,
210
- semanticPayload,
211
- supportedSemanticFunctions
212
- }