@smarthome.exchange/integrations 1.0.0 → 3.0.0

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 (529) hide show
  1. package/changelog.md +84 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/core/classes.configstore.d.ts +2 -0
  4. package/dist_ts/core/classes.configstore.js +84 -27
  5. package/dist_ts/core/classes.nativehomeadmission.d.ts +19 -0
  6. package/dist_ts/core/classes.nativehomeadmission.js +84 -0
  7. package/dist_ts/core/classes.nativeintegrationowner.d.ts +81 -0
  8. package/dist_ts/core/classes.nativeintegrationowner.js +273 -0
  9. package/dist_ts/core/classes.runtimemanager.d.ts +2 -0
  10. package/dist_ts/core/classes.runtimemanager.js +11 -3
  11. package/dist_ts/core/index.d.ts +2 -0
  12. package/dist_ts/core/index.js +3 -1
  13. package/dist_ts/core/types.d.ts +16 -0
  14. package/dist_ts/integrations/braviatv/braviatv.classes.client.d.ts +23 -72
  15. package/dist_ts/integrations/braviatv/braviatv.classes.client.js +265 -625
  16. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.d.ts +7 -7
  17. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.js +51 -68
  18. package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +8 -11
  19. package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +186 -135
  20. package/dist_ts/integrations/braviatv/braviatv.discovery.js +12 -11
  21. package/dist_ts/integrations/braviatv/braviatv.mapper.d.ts +6 -14
  22. package/dist_ts/integrations/braviatv/braviatv.mapper.js +37 -131
  23. package/dist_ts/integrations/braviatv/braviatv.types.d.ts +55 -133
  24. package/dist_ts/integrations/braviatv/braviatv.validation.d.ts +7 -0
  25. package/dist_ts/integrations/braviatv/braviatv.validation.js +72 -0
  26. package/dist_ts/integrations/broadlink/broadlink.actions.d.ts +2 -0
  27. package/dist_ts/integrations/broadlink/broadlink.actions.js +36 -0
  28. package/dist_ts/integrations/broadlink/broadlink.classes.client.d.ts +21 -19
  29. package/dist_ts/integrations/broadlink/broadlink.classes.client.js +185 -124
  30. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.d.ts +5 -4
  31. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.js +64 -83
  32. package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +16 -19
  33. package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +114 -59
  34. package/dist_ts/integrations/broadlink/broadlink.mapper.d.ts +3 -2
  35. package/dist_ts/integrations/broadlink/broadlink.mapper.js +2 -1
  36. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.d.ts +10 -0
  37. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.js +41 -0
  38. package/dist_ts/integrations/broadlink/broadlink.types.d.ts +43 -7
  39. package/dist_ts/integrations/broadlink/broadlink.validation.d.ts +7 -0
  40. package/dist_ts/integrations/broadlink/broadlink.validation.js +63 -0
  41. package/dist_ts/integrations/daikin/daikin.classes.client.d.ts +10 -52
  42. package/dist_ts/integrations/daikin/daikin.classes.client.js +55 -614
  43. package/dist_ts/integrations/daikin/daikin.classes.configflow.d.ts +8 -12
  44. package/dist_ts/integrations/daikin/daikin.classes.configflow.js +77 -138
  45. package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +7 -24
  46. package/dist_ts/integrations/daikin/daikin.classes.integration.js +175 -67
  47. package/dist_ts/integrations/daikin/daikin.discovery.d.ts +11 -24
  48. package/dist_ts/integrations/daikin/daikin.discovery.js +98 -305
  49. package/dist_ts/integrations/daikin/daikin.mapper.d.ts +6 -7
  50. package/dist_ts/integrations/daikin/daikin.mapper.js +95 -155
  51. package/dist_ts/integrations/daikin/daikin.types.d.ts +24 -44
  52. package/dist_ts/integrations/daikin/daikin.types.js +1 -1
  53. package/dist_ts/integrations/daikin/daikin.validation.d.ts +5 -0
  54. package/dist_ts/integrations/daikin/daikin.validation.js +53 -0
  55. package/dist_ts/integrations/deconz/deconz.classes.client.d.ts +37 -29
  56. package/dist_ts/integrations/deconz/deconz.classes.client.js +521 -294
  57. package/dist_ts/integrations/deconz/deconz.classes.configflow.d.ts +6 -1
  58. package/dist_ts/integrations/deconz/deconz.classes.configflow.js +63 -33
  59. package/dist_ts/integrations/deconz/deconz.classes.integration.d.ts +4 -3
  60. package/dist_ts/integrations/deconz/deconz.classes.integration.js +85 -40
  61. package/dist_ts/integrations/deconz/deconz.mapper.d.ts +1 -0
  62. package/dist_ts/integrations/deconz/deconz.mapper.js +24 -6
  63. package/dist_ts/integrations/deconz/deconz.types.d.ts +43 -6
  64. package/dist_ts/integrations/deconz/deconz.validation.d.ts +7 -1
  65. package/dist_ts/integrations/deconz/deconz.validation.js +215 -4
  66. package/dist_ts/integrations/denonavr/denonavr.classes.client.d.ts +31 -40
  67. package/dist_ts/integrations/denonavr/denonavr.classes.client.js +149 -404
  68. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.d.ts +7 -2
  69. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.js +44 -36
  70. package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +6 -11
  71. package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +192 -113
  72. package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +10 -18
  73. package/dist_ts/integrations/denonavr/denonavr.discovery.js +71 -193
  74. package/dist_ts/integrations/denonavr/denonavr.mapper.d.ts +5 -13
  75. package/dist_ts/integrations/denonavr/denonavr.mapper.js +35 -159
  76. package/dist_ts/integrations/denonavr/denonavr.types.d.ts +55 -90
  77. package/dist_ts/integrations/denonavr/denonavr.validation.d.ts +10 -0
  78. package/dist_ts/integrations/denonavr/denonavr.validation.js +86 -0
  79. package/dist_ts/integrations/esphome/esphome.classes.client.d.ts +19 -7
  80. package/dist_ts/integrations/esphome/esphome.classes.client.js +183 -89
  81. package/dist_ts/integrations/esphome/esphome.classes.configflow.d.ts +5 -2
  82. package/dist_ts/integrations/esphome/esphome.classes.configflow.js +43 -33
  83. package/dist_ts/integrations/esphome/esphome.classes.integration.d.ts +8 -6
  84. package/dist_ts/integrations/esphome/esphome.classes.integration.js +71 -43
  85. package/dist_ts/integrations/esphome/esphome.discovery.js +4 -12
  86. package/dist_ts/integrations/esphome/esphome.mapper.d.ts +2 -2
  87. package/dist_ts/integrations/esphome/esphome.mapper.js +6 -4
  88. package/dist_ts/integrations/esphome/esphome.types.d.ts +31 -6
  89. package/dist_ts/integrations/esphome/esphome.types.js +1 -1
  90. package/dist_ts/integrations/esphome/esphome.validation.d.ts +7 -0
  91. package/dist_ts/integrations/esphome/esphome.validation.js +66 -0
  92. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.d.ts +32 -4
  93. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.js +345 -116
  94. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.d.ts +8 -5
  95. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.js +34 -8
  96. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.d.ts +7 -4
  97. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.js +44 -56
  98. package/dist_ts/integrations/homeassistant/homeassistant.types.d.ts +12 -1
  99. package/dist_ts/integrations/hue/hue.classes.client.d.ts +6 -1
  100. package/dist_ts/integrations/hue/hue.classes.client.js +120 -45
  101. package/dist_ts/integrations/hue/hue.classes.configflow.js +16 -7
  102. package/dist_ts/integrations/hue/hue.classes.integration.d.ts +2 -0
  103. package/dist_ts/integrations/hue/hue.classes.integration.js +103 -30
  104. package/dist_ts/integrations/hue/hue.validation.d.ts +1 -0
  105. package/dist_ts/integrations/hue/hue.validation.js +14 -4
  106. package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +11 -45
  107. package/dist_ts/integrations/kodi/kodi.classes.client.js +84 -310
  108. package/dist_ts/integrations/kodi/kodi.classes.configflow.d.ts +9 -8
  109. package/dist_ts/integrations/kodi/kodi.classes.configflow.js +53 -48
  110. package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +11 -11
  111. package/dist_ts/integrations/kodi/kodi.classes.integration.js +114 -171
  112. package/dist_ts/integrations/kodi/kodi.discovery.js +53 -29
  113. package/dist_ts/integrations/kodi/kodi.mapper.d.ts +7 -2
  114. package/dist_ts/integrations/kodi/kodi.mapper.js +48 -10
  115. package/dist_ts/integrations/kodi/kodi.types.d.ts +32 -28
  116. package/dist_ts/integrations/kodi/kodi.validation.d.ts +9 -0
  117. package/dist_ts/integrations/kodi/kodi.validation.js +62 -0
  118. package/dist_ts/integrations/modbus/modbus.classes.client.d.ts +15 -61
  119. package/dist_ts/integrations/modbus/modbus.classes.client.js +117 -776
  120. package/dist_ts/integrations/modbus/modbus.classes.configflow.d.ts +9 -5
  121. package/dist_ts/integrations/modbus/modbus.classes.configflow.js +70 -38
  122. package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +6 -17
  123. package/dist_ts/integrations/modbus/modbus.classes.integration.js +133 -57
  124. package/dist_ts/integrations/modbus/modbus.discovery.d.ts +5 -8
  125. package/dist_ts/integrations/modbus/modbus.discovery.js +38 -93
  126. package/dist_ts/integrations/modbus/modbus.mapper.d.ts +8 -32
  127. package/dist_ts/integrations/modbus/modbus.mapper.js +71 -431
  128. package/dist_ts/integrations/modbus/modbus.types.d.ts +82 -332
  129. package/dist_ts/integrations/modbus/modbus.validation.d.ts +10 -0
  130. package/dist_ts/integrations/modbus/modbus.validation.js +128 -0
  131. package/dist_ts/integrations/mqtt/mqtt.classes.client.d.ts +15 -2
  132. package/dist_ts/integrations/mqtt/mqtt.classes.client.js +173 -23
  133. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.d.ts +5 -1
  134. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.js +53 -33
  135. package/dist_ts/integrations/mqtt/mqtt.classes.integration.d.ts +4 -1
  136. package/dist_ts/integrations/mqtt/mqtt.classes.integration.js +127 -56
  137. package/dist_ts/integrations/mqtt/mqtt.classes.session.d.ts +13 -0
  138. package/dist_ts/integrations/mqtt/mqtt.classes.session.js +130 -0
  139. package/dist_ts/integrations/mqtt/mqtt.mapper.d.ts +3 -0
  140. package/dist_ts/integrations/mqtt/mqtt.mapper.js +44 -1
  141. package/dist_ts/integrations/mqtt/mqtt.types.d.ts +46 -0
  142. package/dist_ts/integrations/mqtt/mqtt.validation.d.ts +7 -0
  143. package/dist_ts/integrations/mqtt/mqtt.validation.js +180 -0
  144. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.d.ts +12 -34
  145. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +143 -231
  146. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.d.ts +6 -1
  147. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.js +105 -18
  148. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +8 -8
  149. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +141 -155
  150. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.d.ts +9 -0
  151. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.js +35 -0
  152. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.d.ts +6 -18
  153. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.js +45 -220
  154. package/dist_ts/integrations/nanoleaf/nanoleaf.types.d.ts +33 -147
  155. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.d.ts +6 -0
  156. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.js +82 -0
  157. package/dist_ts/integrations/onkyo/onkyo.classes.client.d.ts +15 -20
  158. package/dist_ts/integrations/onkyo/onkyo.classes.client.js +161 -404
  159. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.d.ts +9 -4
  160. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.js +51 -6
  161. package/dist_ts/integrations/onkyo/onkyo.classes.integration.d.ts +22 -6
  162. package/dist_ts/integrations/onkyo/onkyo.classes.integration.js +144 -11
  163. package/dist_ts/integrations/onkyo/onkyo.discovery.d.ts +6 -1
  164. package/dist_ts/integrations/onkyo/onkyo.discovery.js +40 -4
  165. package/dist_ts/integrations/onkyo/onkyo.mapper.d.ts +7 -8
  166. package/dist_ts/integrations/onkyo/onkyo.mapper.js +45 -12
  167. package/dist_ts/integrations/onkyo/onkyo.types.d.ts +58 -8
  168. package/dist_ts/integrations/onkyo/onkyo.types.js +13 -102
  169. package/dist_ts/integrations/onkyo/onkyo.validation.d.ts +16 -0
  170. package/dist_ts/integrations/onkyo/onkyo.validation.js +77 -0
  171. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.d.ts +25 -25
  172. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +116 -360
  173. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.d.ts +11 -3
  174. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.js +76 -6
  175. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.d.ts +26 -4
  176. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.js +142 -9
  177. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.d.ts +2 -1
  178. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.js +31 -4
  179. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.d.ts +9 -9
  180. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.js +31 -149
  181. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.d.ts +51 -11
  182. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.js +22 -87
  183. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.d.ts +6 -0
  184. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.js +56 -0
  185. package/dist_ts/integrations/pioneer/pioneer.classes.client.d.ts +31 -16
  186. package/dist_ts/integrations/pioneer/pioneer.classes.client.js +167 -409
  187. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.d.ts +10 -3
  188. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.js +66 -6
  189. package/dist_ts/integrations/pioneer/pioneer.classes.integration.d.ts +13 -5
  190. package/dist_ts/integrations/pioneer/pioneer.classes.integration.js +239 -11
  191. package/dist_ts/integrations/pioneer/pioneer.discovery.d.ts +14 -1
  192. package/dist_ts/integrations/pioneer/pioneer.discovery.js +51 -4
  193. package/dist_ts/integrations/pioneer/pioneer.mapper.d.ts +14 -8
  194. package/dist_ts/integrations/pioneer/pioneer.mapper.js +54 -12
  195. package/dist_ts/integrations/pioneer/pioneer.types.d.ts +79 -12
  196. package/dist_ts/integrations/pioneer/pioneer.types.js +12 -76
  197. package/dist_ts/integrations/pioneer/pioneer.validation.d.ts +10 -0
  198. package/dist_ts/integrations/pioneer/pioneer.validation.js +85 -0
  199. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.d.ts +4 -2
  200. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.js +41 -16
  201. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.d.ts +5 -0
  202. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.js +20 -7
  203. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.d.ts +1 -0
  204. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.js +53 -50
  205. package/dist_ts/integrations/samsungtv/samsungtv.types.d.ts +4 -1
  206. package/dist_ts/integrations/shelly/shelly.classes.client.d.ts +26 -30
  207. package/dist_ts/integrations/shelly/shelly.classes.client.js +504 -276
  208. package/dist_ts/integrations/shelly/shelly.classes.configflow.d.ts +8 -3
  209. package/dist_ts/integrations/shelly/shelly.classes.configflow.js +43 -38
  210. package/dist_ts/integrations/shelly/shelly.classes.integration.d.ts +6 -6
  211. package/dist_ts/integrations/shelly/shelly.classes.integration.js +103 -101
  212. package/dist_ts/integrations/shelly/shelly.classes.subscription.d.ts +4 -0
  213. package/dist_ts/integrations/shelly/shelly.classes.subscription.js +24 -2
  214. package/dist_ts/integrations/shelly/shelly.mapper.d.ts +1 -2
  215. package/dist_ts/integrations/shelly/shelly.mapper.js +21 -20
  216. package/dist_ts/integrations/shelly/shelly.rpc.js +4 -1
  217. package/dist_ts/integrations/shelly/shelly.types.d.ts +42 -2
  218. package/dist_ts/integrations/shelly/shelly.types.js +11 -2
  219. package/dist_ts/integrations/shelly/shelly.validation.d.ts +7 -0
  220. package/dist_ts/integrations/shelly/shelly.validation.js +79 -0
  221. package/dist_ts/integrations/sonos/sonos.classes.client.d.ts +79 -22
  222. package/dist_ts/integrations/sonos/sonos.classes.client.js +427 -139
  223. package/dist_ts/integrations/sonos/sonos.classes.configflow.d.ts +9 -2
  224. package/dist_ts/integrations/sonos/sonos.classes.configflow.js +26 -28
  225. package/dist_ts/integrations/sonos/sonos.classes.integration.d.ts +7 -6
  226. package/dist_ts/integrations/sonos/sonos.classes.integration.js +289 -224
  227. package/dist_ts/integrations/sonos/sonos.config.d.ts +6 -1
  228. package/dist_ts/integrations/sonos/sonos.config.js +23 -2
  229. package/dist_ts/integrations/sonos/sonos.mapper.d.ts +1 -1
  230. package/dist_ts/integrations/sonos/sonos.mapper.js +14 -9
  231. package/dist_ts/integrations/sonos/sonos.matchers.js +3 -3
  232. package/dist_ts/integrations/sonos/sonos.types.d.ts +26 -1
  233. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.d.ts +13 -36
  234. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +179 -502
  235. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.d.ts +6 -1
  236. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.js +50 -40
  237. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +14 -15
  238. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +108 -128
  239. package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -20
  240. package/dist_ts/integrations/soundtouch/soundtouch.discovery.js +23 -113
  241. package/dist_ts/integrations/soundtouch/soundtouch.mapper.d.ts +3 -12
  242. package/dist_ts/integrations/soundtouch/soundtouch.mapper.js +35 -189
  243. package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +57 -142
  244. package/dist_ts/integrations/soundtouch/soundtouch.types.js +18 -3
  245. package/dist_ts/integrations/soundtouch/soundtouch.validation.d.ts +22 -0
  246. package/dist_ts/integrations/soundtouch/soundtouch.validation.js +65 -0
  247. package/dist_ts/integrations/tasmota/tasmota.classes.integration.d.ts +5 -0
  248. package/dist_ts/integrations/tasmota/tasmota.classes.integration.js +23 -7
  249. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.d.ts +19 -5
  250. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.js +115 -41
  251. package/dist_ts/integrations/tasmota/tasmota.config.js +23 -1
  252. package/dist_ts/integrations/tasmota/tasmota.credentials.d.ts +11 -0
  253. package/dist_ts/integrations/tasmota/tasmota.credentials.js +97 -0
  254. package/dist_ts/integrations/tasmota/tasmota.discovery.d.ts +7 -1
  255. package/dist_ts/integrations/tasmota/tasmota.discovery.js +108 -30
  256. package/dist_ts/integrations/tasmota/tasmota.mapper.d.ts +2 -2
  257. package/dist_ts/integrations/tasmota/tasmota.mapper.js +7 -7
  258. package/dist_ts/integrations/tasmota/tasmota.types.d.ts +41 -2
  259. package/dist_ts/integrations/tuya/tuya.classes.integration.d.ts +4 -1
  260. package/dist_ts/integrations/tuya/tuya.classes.integration.js +79 -110
  261. package/dist_ts/integrations/tuya/tuya.classes.runtime.d.ts +5 -2
  262. package/dist_ts/integrations/tuya/tuya.classes.runtime.js +73 -26
  263. package/dist_ts/integrations/tuya/tuya.mapper.js +2 -2
  264. package/dist_ts/integrations/tuya/tuya.types.d.ts +3 -0
  265. package/dist_ts/integrations/tuya/tuya.validation.d.ts +2 -2
  266. package/dist_ts/integrations/tuya/tuya.validation.js +6 -11
  267. package/dist_ts/integrations/webostv/webostv.classes.client.d.ts +6 -5
  268. package/dist_ts/integrations/webostv/webostv.classes.client.js +147 -76
  269. package/dist_ts/integrations/webostv/webostv.classes.configflow.d.ts +7 -2
  270. package/dist_ts/integrations/webostv/webostv.classes.configflow.js +36 -20
  271. package/dist_ts/integrations/webostv/webostv.classes.integration.d.ts +4 -4
  272. package/dist_ts/integrations/webostv/webostv.classes.integration.js +46 -54
  273. package/dist_ts/integrations/webostv/webostv.mapper.js +5 -5
  274. package/dist_ts/integrations/webostv/webostv.types.d.ts +16 -3
  275. package/dist_ts/integrations/webostv/webostv.types.js +1 -1
  276. package/dist_ts/integrations/webostv/webostv.validation.d.ts +3 -1
  277. package/dist_ts/integrations/webostv/webostv.validation.js +23 -1
  278. package/dist_ts/integrations/wiz/index.d.ts +1 -0
  279. package/dist_ts/integrations/wiz/index.js +2 -1
  280. package/dist_ts/integrations/wiz/wiz.classes.client.d.ts +14 -28
  281. package/dist_ts/integrations/wiz/wiz.classes.client.js +93 -229
  282. package/dist_ts/integrations/wiz/wiz.classes.configflow.d.ts +6 -4
  283. package/dist_ts/integrations/wiz/wiz.classes.configflow.js +38 -67
  284. package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +10 -21
  285. package/dist_ts/integrations/wiz/wiz.classes.integration.js +204 -44
  286. package/dist_ts/integrations/wiz/wiz.discovery.d.ts +10 -31
  287. package/dist_ts/integrations/wiz/wiz.discovery.js +48 -249
  288. package/dist_ts/integrations/wiz/wiz.mapper.d.ts +7 -51
  289. package/dist_ts/integrations/wiz/wiz.mapper.js +82 -668
  290. package/dist_ts/integrations/wiz/wiz.types.d.ts +34 -208
  291. package/dist_ts/integrations/wiz/wiz.validation.d.ts +8 -0
  292. package/dist_ts/integrations/wiz/wiz.validation.js +72 -0
  293. package/dist_ts/integrations/yamaha/index.d.ts +1 -0
  294. package/dist_ts/integrations/yamaha/index.js +2 -1
  295. package/dist_ts/integrations/yamaha/yamaha.classes.client.d.ts +30 -4
  296. package/dist_ts/integrations/yamaha/yamaha.classes.client.js +162 -6
  297. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.d.ts +10 -3
  298. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.js +106 -6
  299. package/dist_ts/integrations/yamaha/yamaha.classes.integration.d.ts +22 -4
  300. package/dist_ts/integrations/yamaha/yamaha.classes.integration.js +243 -8
  301. package/dist_ts/integrations/yamaha/yamaha.discovery.d.ts +13 -1
  302. package/dist_ts/integrations/yamaha/yamaha.discovery.js +57 -4
  303. package/dist_ts/integrations/yamaha/yamaha.mapper.d.ts +16 -8
  304. package/dist_ts/integrations/yamaha/yamaha.mapper.js +58 -12
  305. package/dist_ts/integrations/yamaha/yamaha.types.d.ts +73 -6
  306. package/dist_ts/integrations/yamaha/yamaha.types.js +8 -94
  307. package/dist_ts/integrations/yamaha/yamaha.validation.d.ts +12 -0
  308. package/dist_ts/integrations/yamaha/yamaha.validation.js +89 -0
  309. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.d.ts +6 -1
  310. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.js +18 -8
  311. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.d.ts +4 -1
  312. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.js +54 -6
  313. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.d.ts +12 -6
  314. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.js +73 -59
  315. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.d.ts +3 -2
  316. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.js +17 -12
  317. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.d.ts +31 -2
  318. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.d.ts +9 -1
  319. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.js +57 -7
  320. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.d.ts +10 -4
  321. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.js +167 -31
  322. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.d.ts +6 -1
  323. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.js +57 -35
  324. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.d.ts +3 -1
  325. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.js +59 -37
  326. package/dist_ts/integrations/zwave_js/zwave_js.discovery.js +3 -3
  327. package/dist_ts/integrations/zwave_js/zwave_js.mapper.js +41 -24
  328. package/dist_ts/integrations/zwave_js/zwave_js.types.d.ts +25 -3
  329. package/dist_ts/integrations/zwave_js/zwave_js.validation.d.ts +6 -2
  330. package/dist_ts/integrations/zwave_js/zwave_js.validation.js +52 -17
  331. package/dist_ts/plugins.d.ts +2 -1
  332. package/dist_ts/plugins.js +3 -2
  333. package/package.json +9 -9
  334. package/readme.md +539 -8
  335. package/ts/00_commitinfo_data.ts +1 -1
  336. package/ts/core/classes.configstore.ts +84 -27
  337. package/ts/core/classes.nativehomeadmission.ts +96 -0
  338. package/ts/core/classes.nativeintegrationowner.ts +302 -0
  339. package/ts/core/classes.runtimemanager.ts +11 -2
  340. package/ts/core/index.ts +2 -0
  341. package/ts/core/types.ts +18 -0
  342. package/ts/integrations/braviatv/braviatv.classes.client.ts +245 -709
  343. package/ts/integrations/braviatv/braviatv.classes.configflow.ts +47 -76
  344. package/ts/integrations/braviatv/braviatv.classes.integration.ts +167 -147
  345. package/ts/integrations/braviatv/braviatv.discovery.ts +11 -10
  346. package/ts/integrations/braviatv/braviatv.mapper.ts +39 -142
  347. package/ts/integrations/braviatv/braviatv.types.ts +53 -173
  348. package/ts/integrations/braviatv/braviatv.validation.ts +68 -0
  349. package/ts/integrations/broadlink/broadlink.actions.ts +31 -0
  350. package/ts/integrations/broadlink/broadlink.classes.client.ts +170 -144
  351. package/ts/integrations/broadlink/broadlink.classes.configflow.ts +59 -89
  352. package/ts/integrations/broadlink/broadlink.classes.integration.ts +110 -64
  353. package/ts/integrations/broadlink/broadlink.mapper.ts +5 -4
  354. package/ts/integrations/broadlink/broadlink.selected.mapper.ts +46 -0
  355. package/ts/integrations/broadlink/broadlink.types.ts +48 -8
  356. package/ts/integrations/broadlink/broadlink.validation.ts +66 -0
  357. package/ts/integrations/daikin/daikin.classes.client.ts +52 -661
  358. package/ts/integrations/daikin/daikin.classes.configflow.ts +72 -152
  359. package/ts/integrations/daikin/daikin.classes.integration.ts +166 -71
  360. package/ts/integrations/daikin/daikin.discovery.ts +94 -346
  361. package/ts/integrations/daikin/daikin.mapper.ts +83 -166
  362. package/ts/integrations/daikin/daikin.types.ts +27 -48
  363. package/ts/integrations/daikin/daikin.validation.ts +51 -0
  364. package/ts/integrations/daikin/readme.md +83 -0
  365. package/ts/integrations/deconz/deconz.classes.client.ts +348 -252
  366. package/ts/integrations/deconz/deconz.classes.configflow.ts +57 -29
  367. package/ts/integrations/deconz/deconz.classes.integration.ts +69 -37
  368. package/ts/integrations/deconz/deconz.mapper.ts +22 -5
  369. package/ts/integrations/deconz/deconz.types.ts +49 -6
  370. package/ts/integrations/deconz/deconz.validation.ts +177 -4
  371. package/ts/integrations/deconz/readme.md +15 -1
  372. package/ts/integrations/denonavr/denonavr.classes.client.ts +132 -421
  373. package/ts/integrations/denonavr/denonavr.classes.configflow.ts +44 -37
  374. package/ts/integrations/denonavr/denonavr.classes.integration.ts +171 -117
  375. package/ts/integrations/denonavr/denonavr.discovery.ts +67 -220
  376. package/ts/integrations/denonavr/denonavr.mapper.ts +36 -182
  377. package/ts/integrations/denonavr/denonavr.types.ts +48 -111
  378. package/ts/integrations/denonavr/denonavr.validation.ts +87 -0
  379. package/ts/integrations/esphome/esphome.classes.client.ts +179 -94
  380. package/ts/integrations/esphome/esphome.classes.configflow.ts +40 -33
  381. package/ts/integrations/esphome/esphome.classes.integration.ts +63 -36
  382. package/ts/integrations/esphome/esphome.discovery.ts +3 -12
  383. package/ts/integrations/esphome/esphome.mapper.ts +9 -7
  384. package/ts/integrations/esphome/esphome.types.ts +35 -6
  385. package/ts/integrations/esphome/esphome.validation.ts +66 -0
  386. package/ts/integrations/esphome/readme.md +20 -6
  387. package/ts/integrations/homeassistant/homeassistant.classes.client.ts +353 -125
  388. package/ts/integrations/homeassistant/homeassistant.classes.integration.ts +35 -18
  389. package/ts/integrations/homeassistant/homeassistant.classes.runtime.ts +50 -63
  390. package/ts/integrations/homeassistant/homeassistant.types.ts +17 -1
  391. package/ts/integrations/homeassistant/readme.md +22 -6
  392. package/ts/integrations/hue/hue.classes.client.ts +110 -41
  393. package/ts/integrations/hue/hue.classes.configflow.ts +12 -6
  394. package/ts/integrations/hue/hue.classes.integration.ts +92 -26
  395. package/ts/integrations/hue/hue.validation.ts +13 -3
  396. package/ts/integrations/hue/readme.md +3 -3
  397. package/ts/integrations/kodi/kodi.classes.client.ts +72 -352
  398. package/ts/integrations/kodi/kodi.classes.configflow.ts +52 -55
  399. package/ts/integrations/kodi/kodi.classes.integration.ts +97 -178
  400. package/ts/integrations/kodi/kodi.discovery.ts +49 -28
  401. package/ts/integrations/kodi/kodi.mapper.ts +52 -10
  402. package/ts/integrations/kodi/kodi.types.ts +33 -58
  403. package/ts/integrations/kodi/kodi.validation.ts +60 -0
  404. package/ts/integrations/modbus/modbus.classes.client.ts +100 -842
  405. package/ts/integrations/modbus/modbus.classes.configflow.ts +70 -41
  406. package/ts/integrations/modbus/modbus.classes.integration.ts +115 -60
  407. package/ts/integrations/modbus/modbus.discovery.ts +38 -106
  408. package/ts/integrations/modbus/modbus.mapper.ts +64 -467
  409. package/ts/integrations/modbus/modbus.types.ts +64 -381
  410. package/ts/integrations/modbus/modbus.validation.ts +119 -0
  411. package/ts/integrations/mqtt/mqtt.classes.client.ts +136 -19
  412. package/ts/integrations/mqtt/mqtt.classes.configflow.ts +45 -32
  413. package/ts/integrations/mqtt/mqtt.classes.integration.ts +99 -38
  414. package/ts/integrations/mqtt/mqtt.classes.session.ts +118 -0
  415. package/ts/integrations/mqtt/mqtt.mapper.ts +43 -1
  416. package/ts/integrations/mqtt/mqtt.types.ts +52 -0
  417. package/ts/integrations/mqtt/mqtt.validation.ts +157 -0
  418. package/ts/integrations/mqtt/readme.md +12 -3
  419. package/ts/integrations/nanoleaf/nanoleaf.classes.client.ts +115 -249
  420. package/ts/integrations/nanoleaf/nanoleaf.classes.configflow.ts +90 -19
  421. package/ts/integrations/nanoleaf/nanoleaf.classes.integration.ts +130 -181
  422. package/ts/integrations/nanoleaf/nanoleaf.credentials.ts +39 -0
  423. package/ts/integrations/nanoleaf/nanoleaf.mapper.ts +47 -260
  424. package/ts/integrations/nanoleaf/nanoleaf.types.ts +29 -147
  425. package/ts/integrations/nanoleaf/nanoleaf.validation.ts +77 -0
  426. package/ts/integrations/onkyo/onkyo.classes.client.ts +148 -457
  427. package/ts/integrations/onkyo/onkyo.classes.configflow.ts +52 -6
  428. package/ts/integrations/onkyo/onkyo.classes.integration.ts +121 -12
  429. package/ts/integrations/onkyo/onkyo.discovery.ts +41 -3
  430. package/ts/integrations/onkyo/onkyo.mapper.ts +46 -19
  431. package/ts/integrations/onkyo/onkyo.types.ts +55 -110
  432. package/ts/integrations/onkyo/onkyo.validation.ts +85 -0
  433. package/ts/integrations/onkyo/readme.md +126 -0
  434. package/ts/integrations/panasonic_viera/panasonic_viera.classes.client.ts +101 -398
  435. package/ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.ts +69 -5
  436. package/ts/integrations/panasonic_viera/panasonic_viera.classes.integration.ts +141 -9
  437. package/ts/integrations/panasonic_viera/panasonic_viera.discovery.ts +32 -3
  438. package/ts/integrations/panasonic_viera/panasonic_viera.mapper.ts +34 -161
  439. package/ts/integrations/panasonic_viera/panasonic_viera.types.ts +52 -96
  440. package/ts/integrations/panasonic_viera/panasonic_viera.validation.ts +56 -0
  441. package/ts/integrations/pioneer/pioneer.classes.client.ts +132 -428
  442. package/ts/integrations/pioneer/pioneer.classes.configflow.ts +67 -5
  443. package/ts/integrations/pioneer/pioneer.classes.integration.ts +225 -11
  444. package/ts/integrations/pioneer/pioneer.discovery.ts +45 -3
  445. package/ts/integrations/pioneer/pioneer.mapper.ts +57 -13
  446. package/ts/integrations/pioneer/pioneer.types.ts +87 -85
  447. package/ts/integrations/pioneer/pioneer.validation.ts +84 -0
  448. package/ts/integrations/samsungtv/readme.md +11 -5
  449. package/ts/integrations/samsungtv/samsungtv.classes.client.ts +40 -15
  450. package/ts/integrations/samsungtv/samsungtv.classes.configflow.ts +21 -6
  451. package/ts/integrations/samsungtv/samsungtv.classes.integration.ts +53 -38
  452. package/ts/integrations/samsungtv/samsungtv.types.ts +4 -1
  453. package/ts/integrations/shelly/readme.md +22 -7
  454. package/ts/integrations/shelly/shelly.classes.client.ts +386 -269
  455. package/ts/integrations/shelly/shelly.classes.configflow.ts +43 -38
  456. package/ts/integrations/shelly/shelly.classes.integration.ts +92 -111
  457. package/ts/integrations/shelly/shelly.classes.subscription.ts +24 -1
  458. package/ts/integrations/shelly/shelly.mapper.ts +19 -20
  459. package/ts/integrations/shelly/shelly.rpc.ts +2 -0
  460. package/ts/integrations/shelly/shelly.types.ts +50 -2
  461. package/ts/integrations/shelly/shelly.validation.ts +76 -0
  462. package/ts/integrations/sonos/readme.md +117 -38
  463. package/ts/integrations/sonos/sonos.classes.client.ts +392 -123
  464. package/ts/integrations/sonos/sonos.classes.configflow.ts +25 -28
  465. package/ts/integrations/sonos/sonos.classes.integration.ts +211 -186
  466. package/ts/integrations/sonos/sonos.config.ts +24 -2
  467. package/ts/integrations/sonos/sonos.mapper.ts +13 -8
  468. package/ts/integrations/sonos/sonos.matchers.ts +2 -2
  469. package/ts/integrations/sonos/sonos.types.ts +30 -1
  470. package/ts/integrations/soundtouch/soundtouch.classes.client.ts +152 -571
  471. package/ts/integrations/soundtouch/soundtouch.classes.configflow.ts +47 -42
  472. package/ts/integrations/soundtouch/soundtouch.classes.integration.ts +95 -150
  473. package/ts/integrations/soundtouch/soundtouch.discovery.ts +21 -133
  474. package/ts/integrations/soundtouch/soundtouch.mapper.ts +36 -207
  475. package/ts/integrations/soundtouch/soundtouch.types.ts +50 -195
  476. package/ts/integrations/soundtouch/soundtouch.validation.ts +60 -0
  477. package/ts/integrations/tasmota/readme.md +16 -5
  478. package/ts/integrations/tasmota/tasmota.classes.integration.ts +24 -6
  479. package/ts/integrations/tasmota/tasmota.classes.runtime.ts +112 -43
  480. package/ts/integrations/tasmota/tasmota.config.ts +17 -0
  481. package/ts/integrations/tasmota/tasmota.credentials.ts +92 -0
  482. package/ts/integrations/tasmota/tasmota.discovery.ts +87 -24
  483. package/ts/integrations/tasmota/tasmota.mapper.ts +6 -6
  484. package/ts/integrations/tasmota/tasmota.types.ts +43 -2
  485. package/ts/integrations/tuya/readme.md +52 -10
  486. package/ts/integrations/tuya/tuya.classes.integration.ts +69 -98
  487. package/ts/integrations/tuya/tuya.classes.runtime.ts +70 -24
  488. package/ts/integrations/tuya/tuya.mapper.ts +1 -1
  489. package/ts/integrations/tuya/tuya.types.ts +4 -0
  490. package/ts/integrations/tuya/tuya.validation.ts +5 -8
  491. package/ts/integrations/webostv/readme.md +115 -22
  492. package/ts/integrations/webostv/webostv.classes.client.ts +123 -50
  493. package/ts/integrations/webostv/webostv.classes.configflow.ts +35 -15
  494. package/ts/integrations/webostv/webostv.classes.integration.ts +44 -37
  495. package/ts/integrations/webostv/webostv.mapper.ts +4 -4
  496. package/ts/integrations/webostv/webostv.types.ts +18 -3
  497. package/ts/integrations/webostv/webostv.validation.ts +22 -1
  498. package/ts/integrations/wiz/index.ts +1 -0
  499. package/ts/integrations/wiz/wiz.classes.client.ts +84 -254
  500. package/ts/integrations/wiz/wiz.classes.configflow.ts +39 -70
  501. package/ts/integrations/wiz/wiz.classes.integration.ts +189 -45
  502. package/ts/integrations/wiz/wiz.discovery.ts +48 -291
  503. package/ts/integrations/wiz/wiz.mapper.ts +81 -754
  504. package/ts/integrations/wiz/wiz.types.ts +24 -224
  505. package/ts/integrations/wiz/wiz.validation.ts +73 -0
  506. package/ts/integrations/yamaha/index.ts +1 -0
  507. package/ts/integrations/yamaha/yamaha.classes.client.ts +150 -6
  508. package/ts/integrations/yamaha/yamaha.classes.configflow.ts +100 -5
  509. package/ts/integrations/yamaha/yamaha.classes.integration.ts +236 -8
  510. package/ts/integrations/yamaha/yamaha.discovery.ts +52 -3
  511. package/ts/integrations/yamaha/yamaha.mapper.ts +65 -13
  512. package/ts/integrations/yamaha/yamaha.types.ts +77 -97
  513. package/ts/integrations/yamaha/yamaha.validation.ts +86 -0
  514. package/ts/integrations/zigbee2mqtt/readme.md +22 -27
  515. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.ts +16 -7
  516. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.ts +53 -6
  517. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.ts +62 -49
  518. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.ts +17 -11
  519. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.types.ts +35 -2
  520. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.ts +53 -7
  521. package/ts/integrations/zwave_js/readme.md +42 -9
  522. package/ts/integrations/zwave_js/zwave_js.classes.client.ts +155 -31
  523. package/ts/integrations/zwave_js/zwave_js.classes.configflow.ts +55 -31
  524. package/ts/integrations/zwave_js/zwave_js.classes.integration.ts +57 -35
  525. package/ts/integrations/zwave_js/zwave_js.discovery.ts +2 -2
  526. package/ts/integrations/zwave_js/zwave_js.mapper.ts +37 -23
  527. package/ts/integrations/zwave_js/zwave_js.types.ts +26 -3
  528. package/ts/integrations/zwave_js/zwave_js.validation.ts +52 -18
  529. package/ts/plugins.ts +2 -1
@@ -1,167 +1,193 @@
1
- import type {
2
- IBroadlinkCommand,
3
- IBroadlinkCommandResult,
4
- IBroadlinkConfig,
5
- IBroadlinkEvent,
6
- IBroadlinkPacket,
7
- IBroadlinkSnapshot,
8
- } from './broadlink.types.js';
9
- import { BroadlinkMapper } from './broadlink.mapper.js';
10
- import {
11
- broadlinkIrPacketFromTimings,
12
- broadlinkPacketFromBase64,
13
- broadlinkPacketFromHex,
14
- broadlinkRfPacketFromTimings,
15
- } from './broadlink.packet.js';
16
-
17
- type TBroadlinkEventHandler = (eventArg: IBroadlinkEvent) => void;
1
+ import * as plugins from '../../plugins.js';
2
+ import type { NoSqlConfigStore } from '../../core/classes.configstore.js';
3
+ import { NativeHomeAdmission } from '../../core/classes.nativehomeadmission.js';
4
+ import type { INativeIntegrationSetupContext } from '../../core/types.js';
5
+ import { readBroadlinkActions } from './broadlink.actions.js';
6
+ import { broadlinkConfigKey, broadlinkRecord, readBroadlinkSelection,
7
+ sameBroadlinkSelection } from './broadlink.validation.js';
8
+ import { broadlinkIrPacketFromTimings, broadlinkPacketFromBase64, broadlinkPacketFromHex,
9
+ broadlinkRfPacketFromTimings } from './broadlink.packet.js';
10
+ import type { IBroadlinkConfig, IBroadlinkIrAction, IBroadlinkPacket, IBroadlinkSelectedSnapshot,
11
+ IBroadlinkSelection } from './broadlink.types.js';
18
12
 
19
13
  export class BroadlinkClient {
20
- private snapshot?: IBroadlinkSnapshot;
21
- private readonly events: IBroadlinkEvent[] = [];
22
- private readonly eventHandlers = new Set<TBroadlinkEventHandler>();
23
-
24
- constructor(private readonly config: IBroadlinkConfig) {}
25
-
26
- public async getSnapshot(): Promise<IBroadlinkSnapshot> {
27
- this.snapshot = BroadlinkMapper.toSnapshot(this.config, undefined, this.events);
28
- return this.cloneSnapshot(this.snapshot);
29
- }
30
-
31
- public onEvent(handlerArg: TBroadlinkEventHandler): () => void {
32
- this.eventHandlers.add(handlerArg);
33
- return () => this.eventHandlers.delete(handlerArg);
34
- }
35
-
36
- public async refresh(): Promise<IBroadlinkSnapshot> {
37
- this.snapshot = BroadlinkMapper.toSnapshot(this.config, this.config.connected, this.events);
38
- this.emit({ type: 'snapshot_refreshed', data: this.cloneSnapshot(this.snapshot), timestamp: Date.now() });
39
- return this.cloneSnapshot(this.snapshot);
40
- }
41
-
42
- public async sendCommand(commandArg: IBroadlinkCommand): Promise<IBroadlinkCommandResult> {
43
- this.emit({ type: 'command_mapped', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, timestamp: Date.now() });
44
-
45
- if (commandArg.type === 'delete_command') {
46
- const result = this.deleteCommand(commandArg);
47
- this.emit({ type: result.success ? 'command_deleted' : 'command_failed', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, data: result, timestamp: Date.now() });
48
- return result;
14
+ readonly #selection: IBroadlinkSelection;
15
+ readonly #store?: NoSqlConfigStore;
16
+ readonly #protocol: plugins.ecobridgeDeviceManager.BroadlinkProtocol;
17
+ readonly #lifetime = new AbortController();
18
+ readonly #pending = new Set<Promise<unknown>>();
19
+ readonly #packets = new Map<string, Buffer>();
20
+ readonly #setupSignal?: AbortSignal;
21
+ #actions?: ReadonlyArray<Readonly<IBroadlinkIrAction>>;
22
+ #snapshot?: IBroadlinkSelectedSnapshot;
23
+ #initialization?: Promise<void>;
24
+ #closePromise?: Promise<void>;
25
+ #retryPromise?: Promise<void>;
26
+
27
+ constructor(configArg: IBroadlinkConfig, contextArg: INativeIntegrationSetupContext) {
28
+ const config = broadlinkRecord(configArg, ['homeId', 'host', 'macAddress', 'deviceType', 'port',
29
+ 'localAddress', 'timeoutMs', 'maxPendingOperations', 'name', 'actions']);
30
+ this.#selection = readBroadlinkSelection(config);
31
+ this.#actions = config.actions === undefined ? undefined : readBroadlinkActions(config.actions);
32
+ const context = new NativeHomeAdmission('broadlink').admit(contextArg, this.#selection.homeId);
33
+ this.#store = context.configStore;
34
+ if (!this.#actions && !this.#store) {
35
+ throw new TypeError('Broadlink action restoration requires an initialized encrypted NoSqlConfigStore.');
49
36
  }
50
-
51
- if (commandArg.type === 'remote_turn_on' || commandArg.type === 'remote_turn_off') {
52
- const result: IBroadlinkCommandResult = { success: true, transmitted: false, data: { command: commandArg, reason: 'Remote entity enable state is local runtime state only.' } };
53
- this.emit({ type: 'command_executed', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, data: result, timestamp: Date.now() });
54
- return result;
55
- }
56
-
57
- const executor = this.config.commandExecutor || this.config.transport?.execute.bind(this.config.transport);
58
- if (!executor) {
59
- const result: IBroadlinkCommandResult = {
60
- success: false,
61
- transmitted: false,
62
- error: this.unsupportedLiveControlMessage(),
63
- data: { command: commandArg },
64
- };
65
- this.emit({ type: 'command_failed', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, data: result, timestamp: Date.now() });
66
- return result;
67
- }
68
-
69
- try {
70
- const result = this.commandResult(await executor(commandArg), commandArg);
71
- if (result.success) {
72
- this.patchSnapshot(commandArg);
37
+ this.#setupSignal = context.abortSignal;
38
+ this.#setupSignal?.throwIfAborted();
39
+ this.#protocol = new plugins.ecobridgeDeviceManager.BroadlinkProtocol({
40
+ host: this.#selection.host, port: this.#selection.port, macAddress: this.#selection.macAddress,
41
+ deviceType: this.#selection.deviceType, localAddress: this.#selection.localAddress,
42
+ timeoutMs: this.#selection.timeoutMs, maxPendingOperations: this.#selection.maxPendingOperations,
43
+ });
44
+ }
45
+
46
+ public get selection(): IBroadlinkSelection { return this.#selection; }
47
+ public get currentSnapshot(): IBroadlinkSelectedSnapshot {
48
+ if (!this.#snapshot) throw new Error('Broadlink has no verified bridge observation.');
49
+ return this.#snapshot;
50
+ }
51
+ public isHealthy(): boolean { return !this.#lifetime.signal.aborted && this.#protocol.isReady && this.#snapshot?.available === true; }
52
+
53
+ public initialize(): Promise<void> {
54
+ if (!this.#initialization) this.#initialization = this.initializeSelected();
55
+ return this.#initialization;
56
+ }
57
+
58
+ private async initializeSelected(): Promise<void> {
59
+ try { await this.track(() => this.loadAndStart()); }
60
+ catch (error) {
61
+ this.#lifetime.abort(new Error('Broadlink setup failed.'));
62
+ if (this.#snapshot) this.#snapshot = Object.freeze({ ...this.#snapshot, available: false });
63
+ try { await this.closeAndDrain(); }
64
+ catch (cleanupError) {
65
+ throw new AggregateError([error, cleanupError], 'Broadlink setup and cleanup failed.', { cause: error });
73
66
  }
74
- this.emit({ type: result.success ? 'command_executed' : 'command_failed', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, data: result, timestamp: Date.now() });
75
- return result;
76
- } catch (errorArg) {
77
- const result: IBroadlinkCommandResult = {
78
- success: false,
79
- transmitted: false,
80
- error: errorArg instanceof Error ? errorArg.message : String(errorArg),
81
- data: { command: commandArg },
82
- };
83
- this.emit({ type: 'command_failed', command: commandArg, deviceId: commandArg.deviceId, entityId: commandArg.entityId, data: result, timestamp: Date.now() });
84
- return result;
67
+ throw error;
85
68
  }
86
69
  }
87
70
 
88
- public async destroy(): Promise<void> {
89
- this.eventHandlers.clear();
90
- }
91
-
92
- public static packetFromBase64(valueArg: string): IBroadlinkPacket {
93
- return broadlinkPacketFromBase64(valueArg);
94
- }
95
-
96
- public static packetFromHex(valueArg: string): IBroadlinkPacket {
97
- return broadlinkPacketFromHex(valueArg);
98
- }
99
-
100
- public static irPacketFromTimings(timingsArg: number[]): IBroadlinkPacket {
101
- return broadlinkIrPacketFromTimings(timingsArg);
102
- }
103
-
104
- public static rfPacketFromTimings(optionsArg: { frequency: number; timings: number[]; repeatCount?: number }): IBroadlinkPacket {
105
- return broadlinkRfPacketFromTimings(optionsArg);
106
- }
107
-
108
- private emit(eventArg: IBroadlinkEvent): void {
109
- this.events.push(eventArg);
110
- for (const handler of this.eventHandlers) {
111
- handler(eventArg);
71
+ private async loadAndStart(): Promise<void> {
72
+ const signal = this.operationSignal(this.#setupSignal);
73
+ signal.throwIfAborted();
74
+ const supplied = this.#actions !== undefined;
75
+ if (!supplied) {
76
+ if (!this.#store) throw new TypeError('Broadlink action restoration requires an initialized encrypted NoSqlConfigStore.');
77
+ const value = await this.#store.get<unknown>(broadlinkConfigKey(this.#selection));
78
+ if (value === undefined) throw new Error('Broadlink has no encrypted owner action configuration for this bridge.');
79
+ const stored = broadlinkRecord(value, ['version', 'selection', 'actions']);
80
+ if (stored.version !== 1 || !sameBroadlinkSelection(this.#selection, readBroadlinkSelection(stored.selection))) {
81
+ throw new Error('Stored Broadlink configuration does not match the selected home and bridge.');
82
+ }
83
+ this.#actions = readBroadlinkActions(stored.actions);
112
84
  }
85
+ signal.throwIfAborted();
86
+ for (const action of this.#actions!) this.#packets.set(action.id, Buffer.from(action.packetBase64, 'base64'));
87
+ await this.#protocol.start({ signal });
88
+ const firmware = await this.#protocol.readFirmware({ signal });
89
+ signal.throwIfAborted();
90
+ this.#snapshot = Object.freeze({ selection: this.#selection, available: true, firmwareVersion: firmware.version,
91
+ observedAt: new Date().toISOString(), actions: Object.freeze(this.#actions!.map((actionArg) =>
92
+ Object.freeze({ id: actionArg.id, name: actionArg.name }))) });
93
+ if (supplied && this.#store) await this.#store.set(broadlinkConfigKey(this.#selection), {
94
+ version: 1, selection: this.#selection, actions: this.#actions,
95
+ });
96
+ signal.throwIfAborted();
97
+ this.#actions = undefined;
98
+ }
99
+
100
+ public getSnapshot(signalArg?: AbortSignal): Promise<IBroadlinkSelectedSnapshot> {
101
+ return this.track(async () => {
102
+ const signal = this.operationSignal(signalArg);
103
+ signal.throwIfAborted();
104
+ try {
105
+ const firmware = await this.#protocol.readFirmware({ signal });
106
+ signal.throwIfAborted();
107
+ this.#snapshot = Object.freeze({ ...this.currentSnapshot, firmwareVersion: firmware.version,
108
+ available: true, observedAt: new Date().toISOString() });
109
+ return this.#snapshot;
110
+ } catch (error) {
111
+ if (this.#snapshot) this.#snapshot = Object.freeze({ ...this.#snapshot, available: false });
112
+ throw error;
113
+ }
114
+ });
115
+ }
116
+
117
+ public sendAction(actionIdArg: string, signalArg?: AbortSignal): Promise<plugins.ecobridgeDeviceManager.IBroadlinkIrReceipt> {
118
+ return this.track(async () => {
119
+ const signal = this.operationSignal(signalArg);
120
+ if (signal.aborted) throw new plugins.ecobridgeDeviceManager.BroadlinkProtocolError('ABORTED', 'Broadlink action was aborted.');
121
+ const packet = this.#packets.get(actionIdArg);
122
+ if (!packet || !this.isHealthy()) throw new plugins.ecobridgeDeviceManager.BroadlinkProtocolError('NOT_STARTED',
123
+ 'Broadlink action is unknown or the selected bridge is unavailable.');
124
+ try { return await this.#protocol.sendIr(packet, { signal }); }
125
+ catch (error) {
126
+ if (this.#protocol.isClosed && this.#snapshot) this.#snapshot = Object.freeze({ ...this.#snapshot, available: false });
127
+ throw error;
128
+ }
129
+ });
130
+ }
131
+
132
+ /** Terminal and memoized. The caller owns its store/database. */
133
+ public destroy(): Promise<void> {
134
+ if (!this.#closePromise) {
135
+ const closing = Promise.withResolvers<void>();
136
+ this.#closePromise = closing.promise;
137
+ this.#lifetime.abort(new Error('Broadlink client is closed.'));
138
+ if (this.#snapshot) this.#snapshot = Object.freeze({ ...this.#snapshot, available: false });
139
+ void (async () => {
140
+ const [closed] = await Promise.allSettled([this.closeAndDrain(), this.#initialization]);
141
+ if (closed.status === 'rejected') throw closed.reason;
142
+ })().then(closing.resolve, closing.reject);
143
+ }
144
+ return this.#closePromise;
113
145
  }
114
146
 
115
- private commandResult(resultArg: unknown, commandArg: IBroadlinkCommand): IBroadlinkCommandResult {
116
- if (this.isCommandResult(resultArg)) {
117
- return { transmitted: true, ...resultArg };
147
+ /** Explicitly retries retained cleanup without reopening or replaying bridge operations. */
148
+ public retryCleanup(): Promise<void> {
149
+ if (!this.#closePromise) return this.destroy();
150
+ if (!this.#retryPromise) {
151
+ const retry = this.#closePromise.then(() => undefined, () => this.closeAndDrain());
152
+ this.#retryPromise = retry;
153
+ void retry.then(() => {}, () => { if (this.#retryPromise === retry) this.#retryPromise = undefined; });
118
154
  }
119
- return { success: true, transmitted: true, data: resultArg ?? { command: commandArg } };
155
+ return this.#retryPromise;
120
156
  }
121
157
 
122
- private isCommandResult(valueArg: unknown): valueArg is IBroadlinkCommandResult {
123
- return typeof valueArg === 'object' && valueArg !== null && 'success' in valueArg;
158
+ private async closeAndDrain(): Promise<void> {
159
+ // Startup tracks only its admitted work, so its cleanup cannot join itself.
160
+ const [closed] = await Promise.allSettled([
161
+ Promise.resolve().then(() => this.#protocol.close()),
162
+ ...this.#pending,
163
+ ]);
164
+ this.releasePackets();
165
+ this.#actions = undefined;
166
+ if (closed.status === 'rejected') throw closed.reason;
124
167
  }
125
168
 
126
- private deleteCommand(commandArg: IBroadlinkCommand): IBroadlinkCommandResult {
127
- const remoteDevice = commandArg.remoteDevice;
128
- if (!remoteDevice || !commandArg.commandNames?.length) {
129
- return { success: false, transmitted: false, error: 'Broadlink delete_command requires data.device and data.command.' };
130
- }
131
- const devices = this.config.snapshot?.devices || this.config.devices || [];
132
- const targetDevice = devices.find((deviceArg) => BroadlinkMapper.deviceId(deviceArg) === commandArg.deviceId || deviceArg.id === commandArg.deviceId) || devices[0];
133
- const codes = targetDevice?.codes || this.config.codes;
134
- if (!codes?.[remoteDevice]) {
135
- return { success: false, transmitted: false, error: `Broadlink learned-code device not found: ${remoteDevice}.` };
136
- }
137
- for (const command of commandArg.commandNames) {
138
- delete codes[remoteDevice][command];
139
- }
140
- if (!Object.keys(codes[remoteDevice]).length) {
141
- delete codes[remoteDevice];
142
- }
143
- return { success: true, transmitted: false, data: { command: commandArg } };
169
+ private operationSignal(signalArg?: AbortSignal): AbortSignal {
170
+ if (signalArg !== undefined && !(signalArg instanceof AbortSignal)) throw new TypeError('Broadlink cancellation requires an AbortSignal.');
171
+ return signalArg ? AbortSignal.any([signalArg, this.#lifetime.signal]) : this.#lifetime.signal;
144
172
  }
145
173
 
146
- private patchSnapshot(commandArg: IBroadlinkCommand): void {
147
- const snapshot = this.snapshot;
148
- if (!snapshot || !commandArg.deviceId || !commandArg.payload) {
149
- return;
150
- }
151
- const device = snapshot.devices.find((deviceArg) => BroadlinkMapper.deviceId(deviceArg) === commandArg.deviceId || deviceArg.id === commandArg.deviceId);
152
- if (!device) {
153
- return;
154
- }
155
- device.state = { ...(device.state || {}), ...commandArg.payload };
156
- device.available = true;
157
- device.updatedAt = new Date().toISOString();
174
+ private releasePackets(): void {
175
+ for (const packet of this.#packets.values()) packet.fill(0);
176
+ this.#packets.clear();
158
177
  }
159
178
 
160
- private cloneSnapshot(snapshotArg: IBroadlinkSnapshot): IBroadlinkSnapshot {
161
- return JSON.parse(JSON.stringify(snapshotArg)) as IBroadlinkSnapshot;
179
+ private track<TValue>(operationArg: () => Promise<TValue>): Promise<TValue> {
180
+ const operation = Promise.resolve().then(operationArg);
181
+ this.#pending.add(operation);
182
+ void operation.then(() => this.#pending.delete(operation), () => this.#pending.delete(operation));
183
+ return operation;
162
184
  }
163
185
 
164
- private unsupportedLiveControlMessage(): string {
165
- return 'Broadlink live UDP/auth transport is not implemented in this dependency-free TypeScript port. Commands are mapped explicitly but not transmitted unless commandExecutor or transport.execute is provided.';
186
+ /** These pure helpers do not validate a packet for native runtime admission. */
187
+ public static packetFromBase64(valueArg: string): IBroadlinkPacket { return broadlinkPacketFromBase64(valueArg); }
188
+ public static packetFromHex(valueArg: string): IBroadlinkPacket { return broadlinkPacketFromHex(valueArg); }
189
+ public static irPacketFromTimings(timingsArg: number[]): IBroadlinkPacket { return broadlinkIrPacketFromTimings(timingsArg); }
190
+ public static rfPacketFromTimings(optionsArg: { frequency: number; timings: number[]; repeatCount?: number }): IBroadlinkPacket {
191
+ return broadlinkRfPacketFromTimings(optionsArg);
166
192
  }
167
193
  }
@@ -1,99 +1,69 @@
1
+ import { NativeIntegrationOwner, type NativeIntegrationScope } from '../../core/classes.nativeintegrationowner.js';
1
2
  import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
2
- import { broadlinkDefaultPort, broadlinkDefaultTimeoutSeconds } from './broadlink.constants.js';
3
- import type { IBroadlinkConfig, IBroadlinkSnapshot, TBroadlinkDeviceType } from './broadlink.types.js';
3
+ import { readBroadlinkActions } from './broadlink.actions.js';
4
+ import { broadlinkConfigKey, broadlinkRecord, readBroadlinkSelection } from './broadlink.validation.js';
5
+ import type { IBroadlinkConfig } from './broadlink.types.js';
4
6
 
5
7
  export class BroadlinkConfigFlow implements IConfigFlow<IBroadlinkConfig> {
6
- public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IBroadlinkConfig>> {
7
- void contextArg;
8
- const metadata = candidateArg.metadata || {};
9
- const host = candidateArg.host || this.stringValue(metadata.host) || '';
10
- const deviceType = candidateArg.model || this.stringValue(metadata.deviceType) || '';
11
- const name = candidateArg.name || this.stringValue(metadata.name) || '';
12
-
13
- return {
14
- kind: 'form',
15
- title: 'Connect Broadlink device',
16
- description: 'Provide the local host and device identity. This TypeScript port maps snapshots and commands, and requires an injected executor for live Broadlink UDP/auth traffic.',
17
- fields: [
18
- { name: 'host', label: host ? `Host (${host})` : 'Host', type: 'text', required: true },
19
- { name: 'port', label: `Port (${candidateArg.port || broadlinkDefaultPort})`, type: 'number' },
20
- { name: 'timeout', label: `Timeout seconds (${broadlinkDefaultTimeoutSeconds})`, type: 'number' },
21
- { name: 'name', label: name ? `Name (${name})` : 'Name', type: 'text' },
22
- { name: 'type', label: deviceType ? `Device type (${deviceType})` : 'Device type', type: 'text' },
23
- { name: 'macAddress', label: candidateArg.macAddress ? `MAC (${candidateArg.macAddress})` : 'MAC address', type: 'text' },
24
- { name: 'snapshotJson', label: 'Snapshot JSON', type: 'text' },
25
- ],
26
- submit: async (valuesArg) => this.submit(candidateArg, valuesArg),
27
- };
28
- }
29
-
30
- private async submit(candidateArg: IDiscoveryCandidate, valuesArg: Record<string, unknown>): Promise<IConfigFlowStep<IBroadlinkConfig>> {
31
- const snapshot = this.snapshotFromInput(valuesArg.snapshotJson);
32
- if (snapshot instanceof Error) {
33
- return { kind: 'error', title: 'Invalid snapshot', error: snapshot.message };
34
- }
35
-
36
- const host = this.stringValue(valuesArg.host) || candidateArg.host || snapshot?.host;
37
- if (!host && !snapshot) {
38
- return { kind: 'error', title: 'Host required', error: 'Broadlink setup requires a host unless a config is created directly from a snapshot.' };
39
- }
8
+ readonly #scope: NativeIntegrationScope;
40
9
 
41
- const metadata = candidateArg.metadata || {};
42
- const config: IBroadlinkConfig = {
43
- host,
44
- port: this.numberValue(valuesArg.port) || candidateArg.port || snapshot?.port || broadlinkDefaultPort,
45
- timeout: this.numberValue(valuesArg.timeout) || this.numberValue(metadata.timeout) || broadlinkDefaultTimeoutSeconds,
46
- name: this.stringValue(valuesArg.name) || candidateArg.name,
47
- macAddress: this.stringValue(valuesArg.macAddress) || candidateArg.macAddress,
48
- deviceId: candidateArg.id,
49
- type: (this.stringValue(valuesArg.type) || this.stringValue(metadata.deviceType) || candidateArg.model) as TBroadlinkDeviceType | undefined,
50
- devtype: this.numberValue(metadata.devtype),
51
- model: candidateArg.model,
52
- manufacturer: candidateArg.manufacturer || 'Broadlink',
53
- isLocked: metadata.isLocked === true,
54
- snapshot,
55
- metadata: {
56
- discoverySource: candidateArg.source,
57
- discoveryMetadata: metadata,
58
- liveUdpAuthImplemented: false,
59
- },
60
- };
61
-
62
- return {
63
- kind: 'done',
64
- title: 'Broadlink device configured',
65
- config,
66
- };
10
+ constructor(scopeArg?: NativeIntegrationScope) {
11
+ this.#scope = scopeArg ?? new NativeIntegrationOwner('broadlink').createFlowScope();
67
12
  }
68
13
 
69
- private snapshotFromInput(valueArg: unknown): IBroadlinkSnapshot | undefined | Error {
70
- const text = this.stringValue(valueArg);
71
- if (!text) {
72
- return undefined;
73
- }
14
+ public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IBroadlinkConfig>> {
74
15
  try {
75
- const parsed = JSON.parse(text) as IBroadlinkSnapshot;
76
- if (!parsed || !Array.isArray(parsed.devices)) {
77
- return new Error('Snapshot JSON must include a devices array.');
78
- }
79
- return parsed;
80
- } catch (errorArg) {
81
- return errorArg instanceof Error ? errorArg : new Error(String(errorArg));
82
- }
16
+ const context = this.#scope.admit(contextArg);
17
+ return await this.#scope.run<IConfigFlowStep<IBroadlinkConfig>>(context, undefined, async (leaseArg) => {
18
+ leaseArg.assertOpen();
19
+ const host = candidateArg.host;
20
+ const macAddress = candidateArg.macAddress;
21
+ const candidateType = candidateArg.metadata?.devtype;
22
+ const name = candidateArg.name;
23
+ return {
24
+ kind: 'form', title: 'Select Broadlink IR bridge',
25
+ description: 'Select one RM mini 3 or RM4 mini on a trusted local network and provide owner-approved native IR action packets. Bridge acceptance cannot confirm appliance effects.',
26
+ fields: [
27
+ { name: 'host', label: host ? `Private IPv4 (${host})` : 'Private IPv4', type: 'text', required: true },
28
+ { name: 'macAddress', label: macAddress ? `MAC (${macAddress})` : 'Exact MAC', type: 'text', required: true },
29
+ { name: 'deviceType', label: 'Exact bridge type', type: 'select', required: true,
30
+ options: [{ label: 'RM mini 3 (0x2737)', value: '0x2737' }, { label: 'RM4 mini (0x51da)', value: '0x51da' }] },
31
+ { name: 'name', label: name ? `Name (${name})` : 'Bridge name', type: 'text' },
32
+ { name: 'port', label: 'UDP port (80)', type: 'number' },
33
+ { name: 'localAddress', label: 'Local private IPv4 interface (optional)', type: 'text' },
34
+ { name: 'timeoutMs', label: 'Operation timeout milliseconds (5000)', type: 'number' },
35
+ { name: 'maxPendingOperations', label: 'Pending operation limit (32)', type: 'number' },
36
+ { name: 'actionsJson', label: 'Owner IR actions JSON: id, name, packetBase64', type: 'text', required: true },
37
+ ],
38
+ submit: async (valuesArg) => {
39
+ try {
40
+ const values = broadlinkRecord(valuesArg, ['host', 'macAddress', 'deviceType', 'name', 'port', 'localAddress',
41
+ 'timeoutMs', 'maxPendingOperations', 'actionsJson']);
42
+ const deviceType = values.deviceType === '0x2737' ? 0x2737 : values.deviceType === '0x51da' ? 0x51da
43
+ : values.deviceType ?? candidateType;
44
+ return await this.#scope.run<IConfigFlowStep<IBroadlinkConfig>>(context, context.homeId, async (submissionArg) => {
45
+ const selection = readBroadlinkSelection({ homeId: context.homeId, host: values.host ?? host,
46
+ macAddress: values.macAddress ?? macAddress, deviceType, name: values.name ?? name,
47
+ port: values.port, localAddress: values.localAddress, timeoutMs: values.timeoutMs,
48
+ maxPendingOperations: values.maxPendingOperations });
49
+ if (typeof values.actionsJson !== 'string' || values.actionsJson.length > 60000) throw new TypeError('Owner IR actions require bounded JSON.');
50
+ const actions = readBroadlinkActions(JSON.parse(values.actionsJson) as unknown);
51
+ submissionArg.assertOpen();
52
+ if (submissionArg.context.configStore) {
53
+ await submissionArg.context.configStore.set(broadlinkConfigKey(selection), { version: 1, selection, actions });
54
+ }
55
+ return { kind: 'done', title: 'Broadlink selection configured', config: { ...selection,
56
+ ...(submissionArg.context.configStore ? {} : { actions: actions.map((actionArg) => ({ ...actionArg })) }) } };
57
+ });
58
+ } catch (error) { return { kind: 'error', title: 'Invalid Broadlink selection',
59
+ error: error instanceof Error ? error.message : 'Broadlink configuration failed.' }; }
60
+ },
61
+ };
62
+ });
63
+ } catch (error) { return { kind: 'error', title: 'Broadlink home admission failed',
64
+ error: error instanceof Error ? error.message : 'Provide an explicit authorized host home.' }; }
83
65
  }
84
66
 
85
- private stringValue(valueArg: unknown): string | undefined {
86
- return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
87
- }
88
-
89
- private numberValue(valueArg: unknown): number | undefined {
90
- if (typeof valueArg === 'number' && Number.isFinite(valueArg)) {
91
- return valueArg;
92
- }
93
- if (typeof valueArg === 'string' && valueArg.trim()) {
94
- const value = Number(valueArg);
95
- return Number.isFinite(value) ? value : undefined;
96
- }
97
- return undefined;
98
- }
67
+ public destroy(): Promise<void> { return this.#scope.close(); }
68
+ public retryCleanup(): Promise<void> { return this.#scope.retryCleanup(); }
99
69
  }