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,302 +0,0 @@
1
- const KNX_AI_CAMERA_REGISTRY_KEY = Symbol.for('node-red.knx-ai.camera-adapters.v1')
2
- const KNX_AI_CAMERA_IMAGE_MAX_BYTES = 6 * 1024 * 1024
3
- const KNX_AI_CAMERA_MAX_ACTIONS = 8
4
-
5
- const clampText = (value, maxChars = 240) => String(value === undefined || value === null ? '' : value)
6
- .trim()
7
- .slice(0, Math.max(0, Number(maxChars) || 0))
8
-
9
- const normalizeSearchText = value => clampText(value, 300)
10
- .normalize('NFKD')
11
- .replace(/[\u0300-\u036f]/g, '')
12
- .toLocaleLowerCase()
13
- .replace(/[^a-z0-9]+/g, ' ')
14
- .trim()
15
-
16
- const uniqueTexts = values => Array.from(new Set((Array.isArray(values) ? values : [])
17
- .map(value => clampText(value, 240))
18
- .filter(Boolean)))
19
-
20
- // Runtime contract for optional camera suites. A package registers one adapter
21
- // manifest and one provider per configured controller. Providers expose:
22
- // listCameras({ force }) -> camera[]
23
- // takeSnapshot({ cameraId, cameraName, highQuality }) -> { data, mediaType, camera }
24
- // subscribe(listener) -> unsubscribe(), with normalized camera event objects.
25
- // The global Symbol lets separately installed Node-RED packages share the same
26
- // in-process registry without either package importing the other one.
27
- const getKnxAiCameraAdapterRegistry = () => {
28
- const existing = globalThis[KNX_AI_CAMERA_REGISTRY_KEY]
29
- if (existing && existing.version === 1 && existing.adapters instanceof Map && existing.providers instanceof Map) return existing
30
- const registry = {
31
- version: 1,
32
- adapters: new Map(),
33
- providers: new Map(),
34
- listeners: new Set(),
35
- registerAdapter (adapter) {
36
- if (!adapter || !adapter.id) return
37
- this.adapters.set(String(adapter.id), Object.freeze(Object.assign({}, adapter)))
38
- this.listeners.forEach(listener => {
39
- try { listener({ type: 'adapter_registered', adapter: this.adapters.get(String(adapter.id)) }) } catch (error) { /* ignore */ }
40
- })
41
- },
42
- registerProvider (provider) {
43
- if (!provider || !provider.id) return
44
- this.providers.set(String(provider.id), provider)
45
- this.listeners.forEach(listener => {
46
- try { listener({ type: 'provider_registered', provider }) } catch (error) { /* ignore */ }
47
- })
48
- },
49
- unregisterProvider (providerId) {
50
- const id = String(providerId || '')
51
- const provider = this.providers.get(id)
52
- if (!provider) return
53
- this.providers.delete(id)
54
- this.listeners.forEach(listener => {
55
- try { listener({ type: 'provider_unregistered', provider }) } catch (error) { /* ignore */ }
56
- })
57
- },
58
- subscribe (listener) {
59
- if (typeof listener !== 'function') return () => {}
60
- this.listeners.add(listener)
61
- return () => this.listeners.delete(listener)
62
- }
63
- }
64
- globalThis[KNX_AI_CAMERA_REGISTRY_KEY] = registry
65
- return registry
66
- }
67
-
68
- const normalizeKnxAiCameraRegistration = (value = {}) => {
69
- const source = value && typeof value === 'object' && !Array.isArray(value) ? value : {}
70
- const id = clampText(source.cameraId || source.id, 160)
71
- const name = clampText(source.cameraName || source.name || id, 240)
72
- const state = clampText(source.state, 80).toUpperCase()
73
- const online = typeof source.online === 'boolean'
74
- ? source.online
75
- : state
76
- ? ['CONNECTED', 'ONLINE'].includes(state)
77
- : null
78
- if (!id && !name) return null
79
- return {
80
- id,
81
- name,
82
- aliases: uniqueTexts([name, id].concat(Array.isArray(source.aliases) ? source.aliases : [])),
83
- source: clampText(source.source || 'camera-adapter', 80),
84
- adapterId: clampText(source.adapterId, 120),
85
- adapterTitle: clampText(source.adapterTitle, 240),
86
- providerId: clampText(source.providerId, 200),
87
- controllerId: clampText(source.controllerId, 160),
88
- controllerName: clampText(source.controllerName, 240),
89
- nativeCameraId: clampText(source.nativeCameraId, 160),
90
- state,
91
- online,
92
- objectTypes: uniqueTexts(source.objectTypes).map(normalizeCameraObjectType).filter(Boolean).slice(0, 24),
93
- lines: (Array.isArray(source.lines) ? source.lines : []).slice(0, 80),
94
- zones: (Array.isArray(source.zones) ? source.zones : []).slice(0, 80),
95
- lastSeenAt: clampText(source.lastSeenAt || new Date().toISOString(), 64)
96
- }
97
- }
98
-
99
- const resolveKnxAiCamera = ({ target, cameras } = {}) => {
100
- const requested = normalizeSearchText(target)
101
- const list = (Array.isArray(cameras) ? cameras : [])
102
- .map(normalizeKnxAiCameraRegistration)
103
- .filter(Boolean)
104
- if (!requested) return { camera: null, ambiguous: false }
105
-
106
- const exact = list.filter(camera => [camera.id, camera.name].concat(camera.aliases)
107
- .some(alias => normalizeSearchText(alias) === requested))
108
- if (exact.length === 1) return { camera: exact[0], ambiguous: false }
109
- if (exact.length > 1) return { camera: null, ambiguous: true }
110
-
111
- const partial = list.filter(camera => [camera.id, camera.name].concat(camera.aliases)
112
- .some(alias => {
113
- const normalizedAlias = normalizeSearchText(alias)
114
- return normalizedAlias && (normalizedAlias.includes(requested) || requested.includes(normalizedAlias))
115
- }))
116
- if (partial.length === 1) return { camera: partial[0], ambiguous: false }
117
- return { camera: null, ambiguous: partial.length > 1 }
118
- }
119
-
120
- const normalizeCameraEventType = value => {
121
- const raw = normalizeSearchText(value).replace(/\s+/g, '')
122
- if (['smartdetect', 'objectdetect', 'objectdetection', 'smartdetection'].includes(raw)) return 'smartDetect'
123
- if (['smartdetectline', 'line', 'linecrossing', 'crossline'].includes(raw)) return 'smartDetectLine'
124
- if (['smartdetectzone', 'zone', 'intrusionzone', 'intrusion'].includes(raw)) return 'smartDetectZone'
125
- if (['smartdetectloiterzone', 'loiter', 'loiterzone'].includes(raw)) return 'smartDetectLoiterZone'
126
- if (['motion', 'movement'].includes(raw)) return 'motion'
127
- if (['ring', 'doorbell'].includes(raw)) return 'ring'
128
- if (['smartaudiodetect', 'audio'].includes(raw)) return 'smartAudioDetect'
129
- return clampText(value, 80)
130
- }
131
-
132
- const normalizeCameraObjectType = value => {
133
- const raw = normalizeSearchText(value).replace(/\s+/g, '')
134
- if (['person', 'people', 'persona', 'persone', 'human', 'someone', 'qualcuno'].includes(raw)) return 'person'
135
- if (['animal', 'animale', 'animali', 'pet', 'pets', 'dog', 'cat', 'cane', 'gatto'].includes(raw)) return 'animal'
136
- if (['vehicle', 'vehicles', 'veicolo', 'veicoli', 'car', 'auto', 'automobile'].includes(raw)) return 'vehicle'
137
- if (['face', 'volto', 'faccia'].includes(raw)) return 'face'
138
- if (['licenseplate', 'numberplate', 'targa'].includes(raw)) return 'licenseplate'
139
- if (['package', 'parcel', 'pacco'].includes(raw)) return 'package'
140
- return normalizeSearchText(value).replace(/\s+/g, '')
141
- }
142
-
143
- const normalizeCameraActionType = value => {
144
- const raw = normalizeSearchText(value).replace(/\s+/g, '_')
145
- if (['snapshot', 'get_snapshot', 'send_snapshot', 'camera_snapshot'].includes(raw)) return 'snapshot'
146
- if (['analyze', 'analyse', 'analyze_snapshot', 'describe_snapshot', 'vision'].includes(raw)) return 'analyze'
147
- if (['watch', 'subscribe', 'notify', 'create_watch'].includes(raw)) return 'watch'
148
- if (['unwatch', 'unsubscribe', 'stop', 'remove_watch', 'delete_watch'].includes(raw)) return 'unwatch'
149
- if (['list', 'list_watches', 'show_watches'].includes(raw)) return 'list_watches'
150
- return ''
151
- }
152
-
153
- const normalizeKnxAiCameraAction = (value, cameras = []) => {
154
- if (!value || typeof value !== 'object' || Array.isArray(value)) return null
155
- const type = normalizeCameraActionType(value.type || value.action || value.operation)
156
- if (!type) return null
157
- const target = clampText(value.cameraId || value.cameraName || value.camera || value.target, 240)
158
- const resolved = resolveKnxAiCamera({ target, cameras })
159
- const camera = resolved.camera
160
- let eventType = normalizeCameraEventType(value.eventType || value.event)
161
- const requestedScope = clampText(value.scopeId || value.scopeName || value.zoneId || value.lineId || value.zone || value.line, 240)
162
- const availableScopes = camera
163
- ? eventType === 'smartDetectLine'
164
- ? camera.lines
165
- : ['smartDetectZone', 'smartDetectLoiterZone'].includes(eventType)
166
- ? camera.zones
167
- : []
168
- : []
169
- const normalizedScopeTarget = normalizeSearchText(requestedScope)
170
- const matchingScopes = normalizedScopeTarget
171
- ? (Array.isArray(availableScopes) ? availableScopes : []).filter(scope => [scope && scope.id, scope && scope.name]
172
- .some(candidate => normalizeSearchText(candidate) === normalizedScopeTarget))
173
- : []
174
- const resolvedScope = matchingScopes.length === 1 ? matchingScopes[0] : null
175
- const objectTypes = uniqueTexts(Array.isArray(value.objectTypes)
176
- ? value.objectTypes
177
- : [value.objectType || value.smartDetectType]).map(normalizeCameraObjectType).filter(Boolean).slice(0, 12)
178
- // A plain motion event has no classified object metadata. Convert requests
179
- // such as "motion caused by a person/animal" to the generic smart-detection
180
- // family so they can match Protect zone, line, or loiter detections.
181
- if (type === 'watch' && eventType === 'motion' && objectTypes.length > 0) eventType = 'smartDetect'
182
- return {
183
- type,
184
- cameraId: camera ? camera.id : clampText(value.cameraId, 160),
185
- cameraName: camera ? camera.name : clampText(value.cameraName || value.camera || value.target, 240),
186
- unresolvedTarget: camera ? '' : target,
187
- unresolved: Boolean(target && !camera),
188
- ambiguous: resolved.ambiguous,
189
- eventType,
190
- scopeId: resolvedScope ? clampText(resolvedScope.id, 160) : clampText(value.scopeId || value.zoneId || value.lineId, 160),
191
- scopeName: resolvedScope ? clampText(resolvedScope.name || resolvedScope.id, 240) : clampText(value.scopeName || value.zone || value.line, 240),
192
- unresolvedScope: Boolean(requestedScope && camera && !resolvedScope),
193
- ambiguousScope: matchingScopes.length > 1,
194
- objectTypes,
195
- cooldownSeconds: Math.max(10, Math.min(86400, Number(value.cooldownSeconds) || 60)),
196
- sendSnapshot: value.sendSnapshot !== false,
197
- reason: clampText(value.reason, 500)
198
- }
199
- }
200
-
201
- const normalizeKnxAiCameraActions = ({ actions, cameras } = {}) => (Array.isArray(actions) ? actions : [])
202
- .slice(0, KNX_AI_CAMERA_MAX_ACTIONS)
203
- .map(action => normalizeKnxAiCameraAction(action, cameras))
204
- .filter(Boolean)
205
-
206
- const normalizeKnxAiCameraEvent = value => {
207
- const meta = value && typeof value === 'object' && !Array.isArray(value) && value.eventType
208
- ? value
209
- : null
210
- if (!meta) return null
211
- return {
212
- cameraId: clampText(meta.cameraId, 160),
213
- cameraName: clampText(meta.cameraName, 240),
214
- eventType: normalizeCameraEventType(meta.eventType),
215
- scopeId: clampText(meta.scopeId, 160),
216
- scopeName: clampText(meta.scopeName, 240),
217
- objectTypes: uniqueTexts(Array.isArray(meta.objectTypes) ? meta.objectTypes : []).map(normalizeSearchText).filter(Boolean),
218
- eventId: clampText(meta.eventId, 160),
219
- active: meta.active !== false,
220
- at: clampText(meta.at || new Date().toISOString(), 64),
221
- raw: meta.raw
222
- }
223
- }
224
-
225
- const cameraWatchMatchesEvent = (watch, event) => {
226
- if (!watch || !event) return false
227
- const watchCameraId = clampText(watch.cameraId, 160)
228
- const eventCameraId = clampText(event.cameraId, 160)
229
- if (watchCameraId && eventCameraId && watchCameraId !== eventCameraId) return false
230
- if ((!watchCameraId || !eventCameraId) && normalizeSearchText(watch.cameraName) !== normalizeSearchText(event.cameraName)) return false
231
- const wantedObjects = (Array.isArray(watch.objectTypes) ? watch.objectTypes : []).map(normalizeCameraObjectType).filter(Boolean)
232
- const watchEventType = normalizeCameraEventType(watch.eventType)
233
- const eventType = normalizeCameraEventType(event.eventType)
234
- const genericSmartDetection = watchEventType === 'smartDetect' ||
235
- (watchEventType === 'motion' && wantedObjects.length > 0)
236
- if (genericSmartDetection) {
237
- if (!['smartDetectZone', 'smartDetectLine', 'smartDetectLoiterZone'].includes(eventType)) return false
238
- } else if (watchEventType && watchEventType !== eventType) return false
239
- const watchScope = normalizeSearchText(watch.scopeId || watch.scopeName)
240
- const eventScopeCandidates = [event.scopeId, event.scopeName].map(normalizeSearchText).filter(Boolean)
241
- if (watchScope && !eventScopeCandidates.some(candidate => candidate === watchScope || candidate.includes(watchScope) || watchScope.includes(candidate))) return false
242
- if (wantedObjects.length) {
243
- const detectedObjects = (Array.isArray(event.objectTypes) ? event.objectTypes : []).map(normalizeCameraObjectType).filter(Boolean)
244
- if (!detectedObjects.some(type => wantedObjects.includes(type))) return false
245
- }
246
- return true
247
- }
248
-
249
- const normalizeKnxAiCameraImage = ({ data, mediaType } = {}) => {
250
- if (!Buffer.isBuffer(data)) throw new Error('The camera snapshot is not binary image data')
251
- if (data.length === 0) throw new Error('The camera snapshot is empty')
252
- if (data.length > KNX_AI_CAMERA_IMAGE_MAX_BYTES) throw new Error(`The camera snapshot exceeds ${KNX_AI_CAMERA_IMAGE_MAX_BYTES} bytes`)
253
- const type = clampText(mediaType || 'image/jpeg', 80).toLocaleLowerCase().split(';')[0]
254
- if (!['image/jpeg', 'image/png', 'image/webp', 'image/gif'].includes(type)) throw new Error(`Unsupported camera image type: ${type}`)
255
- return { data, mediaType: type, bytes: data.length }
256
- }
257
-
258
- const buildKnxAiCameraNotificationText = ({ language, event } = {}) => {
259
- const lang = clampText(language || 'en', 8).toLocaleLowerCase()
260
- const camera = clampText(event && event.cameraName, 240) || clampText(event && event.cameraId, 160) || 'camera'
261
- const eventType = normalizeCameraEventType(event && event.eventType)
262
- const scope = clampText(event && (event.scopeName || event.scopeId), 240)
263
- const objectTypes = uniqueTexts(event && event.objectTypes).join(', ')
264
- const details = [scope, objectTypes].filter(Boolean).join(' — ')
265
- const suffix = details ? ` (${details})` : ''
266
- const labels = {
267
- it: { smartDetectLine: 'un attraversamento di linea', smartDetectZone: 'un ingresso in zona', smartDetectLoiterZone: 'una permanenza in zona', motion: 'un movimento', ring: 'un suono del campanello', smartAudioDetect: 'un evento audio intelligente' },
268
- de: { smartDetectLine: 'eine Linienüberquerung', smartDetectZone: 'einen Zoneneintritt', smartDetectLoiterZone: 'einen längeren Zonenaufenthalt', motion: 'eine Bewegung', ring: 'ein Klingeln', smartAudioDetect: 'ein intelligentes Audioereignis' },
269
- fr: { smartDetectLine: 'un franchissement de ligne', smartDetectZone: 'une entrée dans une zone', smartDetectLoiterZone: 'une présence prolongée dans une zone', motion: 'un mouvement', ring: 'une sonnerie', smartAudioDetect: 'un événement audio intelligent' },
270
- es: { smartDetectLine: 'un cruce de línea', smartDetectZone: 'una entrada en zona', smartDetectLoiterZone: 'una permanencia en zona', motion: 'un movimiento', ring: 'una llamada al timbre', smartAudioDetect: 'un evento de audio inteligente' },
271
- zh: { smartDetectLine: '越线事件', smartDetectZone: '进入区域事件', smartDetectLoiterZone: '区域徘徊事件', motion: '移动事件', ring: '门铃事件', smartAudioDetect: '智能音频事件' },
272
- en: { smartDetectLine: 'a line crossing', smartDetectZone: 'a zone entry', smartDetectLoiterZone: 'loitering in a zone', motion: 'motion', ring: 'a doorbell ring', smartAudioDetect: 'a smart audio event' }
273
- }
274
- const label = (labels[lang] || labels.en)[eventType] || (lang === 'zh' ? '摄像机事件' : lang === 'it' ? 'un evento' : lang === 'de' ? 'ein Ereignis' : lang === 'fr' ? 'un événement' : lang === 'es' ? 'un evento' : 'an event')
275
- const copy = {
276
- it: `La telecamera ${camera} ha rilevato ${label}${suffix}.`,
277
- de: `Die Kamera ${camera} hat ${label} erkannt${suffix}.`,
278
- fr: `La caméra ${camera} a détecté ${label}${suffix}.`,
279
- es: `La cámara ${camera} ha detectado ${label}${suffix}.`,
280
- zh: `摄像机 ${camera} 检测到${label}${suffix}。`,
281
- en: `Camera ${camera} detected ${label}${suffix}.`
282
- }
283
- return copy[lang] || copy.en
284
- }
285
-
286
- module.exports = {
287
- KNX_AI_CAMERA_IMAGE_MAX_BYTES,
288
- KNX_AI_CAMERA_MAX_ACTIONS,
289
- KNX_AI_CAMERA_REGISTRY_KEY,
290
- buildKnxAiCameraNotificationText,
291
- cameraWatchMatchesEvent,
292
- getKnxAiCameraAdapterRegistry,
293
- normalizeCameraEventType,
294
- normalizeCameraObjectType,
295
- normalizeKnxAiCameraAction,
296
- normalizeKnxAiCameraActions,
297
- normalizeKnxAiCameraEvent,
298
- normalizeKnxAiCameraImage,
299
- normalizeKnxAiCameraRegistration,
300
- normalizeSearchText,
301
- resolveKnxAiCamera
302
- }
@@ -1,349 +0,0 @@
1
- const KNX_AI_CATALOG_MAX_RESEARCH_ROUNDS = 1
2
- const KNX_AI_CATALOG_MAX_ACTIONS_PER_ROUND = 4
3
- const KNX_AI_CATALOG_MAX_RESULTS_PER_ACTION = 12
4
- const KNX_AI_CATALOG_MAX_ACCUMULATED_OBJECTS = 24
5
-
6
- const normalizeText = (value) => String(value || '')
7
- .normalize('NFKD')
8
- .replace(/[\u0300-\u036f]/g, '')
9
- .toLowerCase()
10
- .replace(/[^\p{L}\p{N}/]+/gu, ' ')
11
- .replace(/\s+/g, ' ')
12
- .trim()
13
-
14
- const normalizeGa = (value) => String(value || '').trim()
15
-
16
- const clampLimit = (value) => Math.max(1, Math.min(
17
- KNX_AI_CATALOG_MAX_RESULTS_PER_ACTION,
18
- Math.round(Number(value) || 8)
19
- ))
20
-
21
- const normalizeStringList = (value, maxItems = 12) => Array.from(new Set(
22
- (Array.isArray(value) ? value : [])
23
- .map(item => String(item || '').trim())
24
- .filter(Boolean)
25
- )).slice(0, maxItems)
26
-
27
- const normalizeKnxAiCatalogActions = (value, { maxActions = KNX_AI_CATALOG_MAX_ACTIONS_PER_ROUND } = {}) => {
28
- const accepted = []
29
- const allowedOperations = new Set(['search', 'get', 'list_areas', 'browse_area', 'related'])
30
- const allowedAccess = new Set(['any', 'read-only', 'read-write'])
31
- const allowedPurposes = new Set(['any', 'read', 'write', 'inspect'])
32
- ;(Array.isArray(value) ? value : []).slice(0, Math.max(1, Number(maxActions) || 1)).forEach(candidate => {
33
- const source = candidate && typeof candidate === 'object' && !Array.isArray(candidate) ? candidate : {}
34
- const operation = String(source.operation || '').trim().toLowerCase()
35
- if (!allowedOperations.has(operation)) return
36
- const query = String(source.query || '').trim().slice(0, 300)
37
- const destinations = normalizeStringList(source.destinations, 20)
38
- const area = String(source.area || '').trim().slice(0, 300)
39
- if (operation === 'search' && !query) return
40
- if ((operation === 'get' || operation === 'related') && !destinations.length) return
41
- if (operation === 'browse_area' && !area) return
42
- const semanticKinds = normalizeStringList(source.semanticKinds, 12)
43
- .map(kind => normalizeText(kind))
44
- .filter(Boolean)
45
- const requestedAccess = String(source.access || '').trim().toLowerCase()
46
- const requestedPurpose = String(source.purpose || '').trim().toLowerCase()
47
- accepted.push({
48
- operation,
49
- query,
50
- destinations,
51
- area,
52
- semanticKinds,
53
- access: allowedAccess.has(requestedAccess) ? requestedAccess : 'any',
54
- purpose: allowedPurposes.has(requestedPurpose) ? requestedPurpose : 'any',
55
- offset: Math.max(0, Math.min(100000, Math.round(Number(source.offset) || 0))),
56
- limit: clampLimit(source.limit),
57
- reason: String(source.reason || '').trim().slice(0, 1000)
58
- })
59
- })
60
- return accepted
61
- }
62
-
63
- const editDistanceAtMostTwo = (left, right) => {
64
- if (left === right) return 0
65
- if (!left || !right || Math.abs(left.length - right.length) > 2) return 3
66
- let previous = Array.from({ length: right.length + 1 }, (_, index) => index)
67
- for (let i = 1; i <= left.length; i += 1) {
68
- const current = [i]
69
- let rowMinimum = current[0]
70
- for (let j = 1; j <= right.length; j += 1) {
71
- const substitution = previous[j - 1] + (left[i - 1] === right[j - 1] ? 0 : 1)
72
- current[j] = Math.min(previous[j] + 1, current[j - 1] + 1, substitution)
73
- rowMinimum = Math.min(rowMinimum, current[j])
74
- }
75
- if (rowMinimum > 2) return 3
76
- previous = current
77
- }
78
- return previous[right.length]
79
- }
80
-
81
- const tokenQuality = (queryToken, candidateToken) => {
82
- if (queryToken === candidateToken) return 1
83
- const substringMinimum = /[^\u0000-\u007f]/.test(queryToken) ? 2 : 3
84
- if (queryToken.length >= substringMinimum && (candidateToken.includes(queryToken) || queryToken.includes(candidateToken))) return 0.82
85
- if (queryToken.length < 4) return 0
86
- const distance = editDistanceAtMostTwo(queryToken, candidateToken)
87
- if (distance === 1) return 0.68
88
- if (distance === 2 && queryToken.length >= 7) return 0.5
89
- return 0
90
- }
91
-
92
- const buildSearchDocument = (item) => {
93
- const semantic = item && item.semantic && typeof item.semantic === 'object' ? item.semantic : {}
94
- const aliases = Array.isArray(item && item.aliases) ? item.aliases : []
95
- const options = Array.isArray(item && item.valueOptions) ? item.valueOptions : []
96
- const fields = {
97
- ga: normalizeText(item && item.ga),
98
- label: normalizeText(item && item.label),
99
- etsName: normalizeText(item && item.etsName),
100
- hierarchy: normalizeText(item && item.hierarchyPath),
101
- aliases: normalizeText(aliases.join(' ')),
102
- semantic: normalizeText([semantic.kind, semantic.area, item && item.mainGroup, item && item.middleGroup, ...(Array.isArray(item && item.tags) ? item.tags : [])].join(' ')),
103
- values: normalizeText(options.map(option => `${option && option.value} ${option && option.label}`).join(' ')),
104
- dpt: normalizeText(item && item.dpt)
105
- }
106
- const combined = Object.values(fields).join(' ').trim()
107
- return { fields, combined, tokens: Array.from(new Set(combined.split(' ').filter(Boolean))) }
108
- }
109
-
110
- const itemPassesFilters = (item, action) => {
111
- if (action.access === 'read-only' && item && item.readOnly !== true) return false
112
- if (action.access === 'read-write' && item && item.readOnly === true) return false
113
- if (action.purpose === 'write' && item && item.readOnly === true) return false
114
- const semantic = item && item.semantic && typeof item.semantic === 'object' ? item.semantic : {}
115
- if (action.semanticKinds.length && !action.semanticKinds.includes(normalizeText(semantic.kind))) return false
116
- return true
117
- }
118
-
119
- const purposeScore = (item, purpose) => {
120
- const readOnly = item && item.readOnly === true
121
- if (purpose === 'write') return readOnly ? -1000 : 130
122
- if (purpose === 'read') return readOnly ? 90 : 50
123
- if (purpose === 'inspect') return readOnly ? 70 : 55
124
- return 0
125
- }
126
-
127
- const scoreSearchMatch = (item, action) => {
128
- if (!itemPassesFilters(item, action)) return 0
129
- const query = normalizeText(action.query)
130
- if (!query) return 0
131
- const document = buildSearchDocument(item)
132
- const exactGa = normalizeGa(item && item.ga) === normalizeGa(action.query)
133
- if (exactGa) return 2000 + purposeScore(item, action.purpose)
134
- let score = 0
135
- if (document.fields.label === query) score += 900
136
- if (document.fields.etsName === query) score += 850
137
- if (document.fields.aliases.split(' ').includes(query)) score += 800
138
- if (document.fields.hierarchy === query) score += 750
139
- if (document.combined.includes(query)) score += 360
140
- const queryTokens = query.split(' ').filter(Boolean)
141
- let qualityTotal = 0
142
- let matchedTokens = 0
143
- let strongMatches = 0
144
- for (const queryToken of queryTokens) {
145
- let best = 0
146
- for (const candidateToken of document.tokens) {
147
- best = Math.max(best, tokenQuality(queryToken, candidateToken))
148
- if (best === 1) break
149
- }
150
- if (best >= 0.5) {
151
- matchedTokens += 1
152
- qualityTotal += best
153
- if (best >= 0.68) strongMatches += 1
154
- }
155
- }
156
- if (strongMatches === 0) return 0
157
- const missingTokens = Math.max(0, queryTokens.length - matchedTokens)
158
- const coverage = queryTokens.length > 0 ? matchedTokens / queryTokens.length : 0
159
- score += qualityTotal * 120
160
- score += coverage * 200
161
- score += Math.max(0, matchedTokens - 1) * 50
162
- score -= missingTokens * 18
163
- score += purposeScore(item, action.purpose)
164
- if (action.area) {
165
- const area = normalizeText(action.area)
166
- const itemArea = normalizeText([
167
- item && item.hierarchyPath,
168
- item && item.mainGroup,
169
- item && item.middleGroup,
170
- item && item.semantic && item.semantic.area
171
- ].join(' '))
172
- if (!itemArea.includes(area)) return 0
173
- score += 120
174
- }
175
- return score
176
- }
177
-
178
- const sortScoredItems = (scored) => scored
179
- .sort((left, right) => right.score - left.score || String(left.item && left.item.hierarchyPath || left.item && left.item.label || left.item && left.item.ga || '').localeCompare(String(right.item && right.item.hierarchyPath || right.item && right.item.label || right.item && right.item.ga || '')))
180
- .map(entry => entry.item)
181
-
182
- const findSearchItems = (catalog, action) => sortScoredItems(
183
- catalog.map(item => ({ item, score: scoreSearchMatch(item, action) })).filter(entry => entry.score > 0)
184
- )
185
-
186
- const buildAreaRows = (catalog) => {
187
- const areas = new Map()
188
- catalog.forEach(item => {
189
- const semantic = item && item.semantic && typeof item.semantic === 'object' ? item.semantic : {}
190
- const candidates = [semantic.area, item && item.hierarchyPath, item && item.middleGroup, item && item.mainGroup]
191
- .map(value => String(value || '').trim())
192
- .filter(Boolean)
193
- const area = candidates[0] || 'Unclassified'
194
- const key = normalizeText(area)
195
- if (!key) return
196
- if (!areas.has(key)) areas.set(key, { area, count: 0, sampleLabels: [] })
197
- const row = areas.get(key)
198
- row.count += 1
199
- const label = String(item && item.label || item && item.ga || '').trim()
200
- if (label && row.sampleLabels.length < 3 && !row.sampleLabels.includes(label)) row.sampleLabels.push(label)
201
- })
202
- return Array.from(areas.values()).sort((left, right) => right.count - left.count || left.area.localeCompare(right.area))
203
- }
204
-
205
- const findAreaItems = (catalog, action) => {
206
- const requestedArea = normalizeText(action.area)
207
- return sortScoredItems(catalog
208
- .filter(item => itemPassesFilters(item, action))
209
- .map(item => {
210
- const semantic = item && item.semantic && typeof item.semantic === 'object' ? item.semantic : {}
211
- const areaText = normalizeText([semantic.area, item && item.hierarchyPath, item && item.middleGroup, item && item.mainGroup].join(' '))
212
- if (!areaText.includes(requestedArea)) return { item, score: 0 }
213
- return { item, score: 400 + purposeScore(item, action.purpose) }
214
- })
215
- .filter(entry => entry.score > 0))
216
- }
217
-
218
- const findRelatedItems = (catalog, action) => {
219
- const requested = new Set(action.destinations.map(normalizeGa))
220
- const seeds = catalog.filter(item => requested.has(normalizeGa(item && item.ga)))
221
- if (!seeds.length) return []
222
- const seedDocuments = seeds.map(seed => ({ seed, tokens: new Set(buildSearchDocument(seed).tokens) }))
223
- const scored = catalog.map(item => {
224
- if (!itemPassesFilters(item, action)) return { item, score: 0 }
225
- let best = requested.has(normalizeGa(item && item.ga)) ? 1000 : 0
226
- const itemTokens = buildSearchDocument(item).tokens
227
- seedDocuments.forEach(({ seed, tokens: seedTokens }) => {
228
- if (seed === item) return
229
- const seedSemantic = seed && seed.semantic && typeof seed.semantic === 'object' ? seed.semantic : {}
230
- const itemSemantic = item && item.semantic && typeof item.semantic === 'object' ? item.semantic : {}
231
- let relationScore = 0
232
- if (normalizeText(seed.hierarchyPath) && normalizeText(seed.hierarchyPath) === normalizeText(item.hierarchyPath)) relationScore += 260
233
- if (normalizeText(seedSemantic.area) && normalizeText(seedSemantic.area) === normalizeText(itemSemantic.area)) relationScore += 180
234
- if (normalizeText(seed.middleGroup) && normalizeText(seed.middleGroup) === normalizeText(item.middleGroup)) relationScore += 100
235
- if (normalizeText(seed.mainGroup) && normalizeText(seed.mainGroup) === normalizeText(item.mainGroup)) relationScore += 45
236
- if (normalizeText(seedSemantic.kind) && normalizeText(seedSemantic.kind) === normalizeText(itemSemantic.kind)) relationScore += 65
237
- const overlap = itemTokens.filter(token => token.length >= 4 && seedTokens.has(token)).length
238
- relationScore += Math.min(100, overlap * 20)
239
- if (relationScore <= 0) return
240
- const score = relationScore + purposeScore(item, action.purpose)
241
- best = Math.max(best, score)
242
- })
243
- return { item, score: best }
244
- }).filter(entry => entry.score > 0)
245
- return sortScoredItems(scored)
246
- }
247
-
248
- const actionFingerprint = (action) => JSON.stringify({
249
- operation: action.operation,
250
- query: normalizeText(action.query),
251
- destinations: action.destinations.map(normalizeGa).sort(),
252
- area: normalizeText(action.area),
253
- semanticKinds: action.semanticKinds.slice().sort(),
254
- access: action.access,
255
- purpose: action.purpose,
256
- offset: action.offset,
257
- limit: action.limit
258
- })
259
-
260
- const executeKnxAiCatalogActions = ({ actions, catalog, priorResults = [] } = {}) => {
261
- const safeCatalog = Array.isArray(catalog) ? catalog : []
262
- const normalized = normalizeKnxAiCatalogActions(actions)
263
- const seen = new Set((Array.isArray(priorResults) ? priorResults : []).map(result => String(result && result.fingerprint || '')).filter(Boolean))
264
- const results = []
265
- normalized.forEach(action => {
266
- const fingerprint = actionFingerprint(action)
267
- if (seen.has(fingerprint)) return
268
- seen.add(fingerprint)
269
- if (action.operation === 'list_areas') {
270
- const allAreas = buildAreaRows(safeCatalog.filter(item => itemPassesFilters(item, action)))
271
- results.push({
272
- action,
273
- fingerprint,
274
- ok: true,
275
- totalMatches: allAreas.length,
276
- truncated: allAreas.length > action.offset + action.limit,
277
- areas: allAreas.slice(action.offset, action.offset + action.limit),
278
- items: []
279
- })
280
- return
281
- }
282
- let matched = []
283
- if (action.operation === 'get') {
284
- const requested = new Set(action.destinations.map(normalizeGa))
285
- matched = safeCatalog.filter(item => requested.has(normalizeGa(item && item.ga)) && itemPassesFilters(item, action))
286
- } else if (action.operation === 'search') {
287
- matched = findSearchItems(safeCatalog, action)
288
- } else if (action.operation === 'browse_area') {
289
- matched = findAreaItems(safeCatalog, action)
290
- } else if (action.operation === 'related') {
291
- matched = findRelatedItems(safeCatalog, action)
292
- }
293
- results.push({
294
- action,
295
- fingerprint,
296
- ok: true,
297
- totalMatches: matched.length,
298
- truncated: matched.length > action.offset + action.limit,
299
- items: matched.slice(action.offset, action.offset + action.limit),
300
- areas: []
301
- })
302
- })
303
- return results
304
- }
305
-
306
- const collectKnxAiCatalogObjects = (results, maxItems = KNX_AI_CATALOG_MAX_ACCUMULATED_OBJECTS) => {
307
- const byGa = new Map()
308
- ;(Array.isArray(results) ? results.slice().reverse() : []).forEach(result => {
309
- ;(Array.isArray(result && result.items) ? result.items : []).forEach(item => {
310
- const ga = normalizeGa(item && item.ga)
311
- if (!ga || byGa.has(ga) || byGa.size >= maxItems) return
312
- byGa.set(ga, item)
313
- })
314
- })
315
- return Array.from(byGa.values())
316
- }
317
-
318
- const buildKnxAiCatalogResearchContext = (results) => {
319
- const source = Array.isArray(results) ? results : []
320
- if (!source.length) return ''
321
- const lines = ['LOCAL ETS CATALOG RETRIEVAL RESULTS:']
322
- source.forEach((result, index) => {
323
- const action = result && result.action ? result.action : {}
324
- const target = action.operation === 'search'
325
- ? ` query=${JSON.stringify(action.query)}`
326
- : action.operation === 'browse_area'
327
- ? ` area=${JSON.stringify(action.area)}`
328
- : (action.operation === 'get' || action.operation === 'related')
329
- ? ` destinations=${JSON.stringify(action.destinations)}`
330
- : ''
331
- lines.push(`[C${index + 1}] ${action.operation || 'unknown'}${target}: ${Number(result && result.totalMatches) || 0} match(es); page offset=${Math.max(0, Number(action.offset) || 0)}, limit=${Math.max(1, Number(action.limit) || 1)}${result && result.truncated ? '; more matches are available with a larger offset' : ''}.`)
332
- ;(Array.isArray(result && result.areas) ? result.areas : []).forEach(area => {
333
- lines.push(`- area ${JSON.stringify(area.area)} | ${area.count} objects | examples ${area.sampleLabels.join(', ') || '?'}`)
334
- })
335
- })
336
- lines.push('END LOCAL ETS CATALOG RETRIEVAL RESULTS')
337
- return lines.join('\n')
338
- }
339
-
340
- module.exports = {
341
- KNX_AI_CATALOG_MAX_ACCUMULATED_OBJECTS,
342
- KNX_AI_CATALOG_MAX_ACTIONS_PER_ROUND,
343
- KNX_AI_CATALOG_MAX_RESEARCH_ROUNDS,
344
- KNX_AI_CATALOG_MAX_RESULTS_PER_ACTION,
345
- buildKnxAiCatalogResearchContext,
346
- collectKnxAiCatalogObjects,
347
- executeKnxAiCatalogActions,
348
- normalizeKnxAiCatalogActions
349
- }