@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,223 +1,41 @@
1
- import type { IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
1
+ import type * as plugins from '../../plugins.js';
2
2
 
3
3
  export const wizDefaultPort = 38899;
4
4
 
5
- export type TWizBulbType = 'rgb' | 'tw' | 'dw' | 'socket' | 'fan' | 'unknown' | string;
6
- export type TWizDiscoveryProtocol = 'mdns' | 'udp' | 'manual';
7
-
8
5
  export interface IWizConfig {
9
- host?: string;
6
+ homeId: string;
7
+ host: string;
8
+ macAddress: string;
10
9
  port?: number;
11
- mac?: string;
12
10
  name?: string;
13
- deviceInfo?: IWizDeviceInfo;
14
- pilot?: IWizPilotState;
15
- snapshot?: IWizSnapshot;
16
- devices?: IWizSnapshotDevice[];
17
- manualEntries?: IWizManualEntry[];
18
- events?: IWizEvent[];
19
11
  timeoutMs?: number;
20
- commandExecutor?: TWizCommandExecutor;
21
- [key: string]: unknown;
12
+ /** Zero disables subscription polling; explicit reads still deliver observations. */
13
+ pollIntervalMs?: number;
14
+ maxPendingOperations?: number;
15
+ maxExchanges?: number;
22
16
  }
23
17
 
24
18
  export interface IHomeAssistantWizConfig extends IWizConfig {}
25
19
 
26
- export interface IWizDeviceFeatures {
27
- light?: boolean;
28
- switch?: boolean;
29
- brightness?: boolean;
30
- color?: boolean;
31
- colorTemp?: boolean;
32
- effect?: boolean;
33
- fan?: boolean;
34
- fanReverse?: boolean;
35
- fanBreezeMode?: boolean;
36
- power?: boolean;
37
- occupancy?: boolean;
38
- button?: boolean;
39
- dualHead?: boolean;
40
- [key: string]: unknown;
41
- }
42
-
43
- export interface IWizKelvinRange {
44
- min?: number;
45
- max?: number;
46
- }
47
-
48
- export interface IWizDeviceInfo {
49
- id?: string;
50
- mac?: string;
51
- host?: string;
52
- port?: number;
53
- name?: string;
54
- manufacturer?: string;
55
- model?: string;
56
- moduleName?: string;
57
- fwVersion?: string;
58
- typeId?: number | string;
59
- bulbType?: TWizBulbType;
60
- isSocket?: boolean;
61
- whiteChannels?: number;
62
- kelvinRange?: IWizKelvinRange;
63
- fanSpeedRange?: number;
64
- powerMonitoring?: boolean;
65
- features?: IWizDeviceFeatures;
66
- [key: string]: unknown;
67
- }
68
-
69
- export interface IWizPilotState {
70
- mac?: string;
71
- rssi?: number;
72
- src?: string;
73
- state?: boolean;
74
- sceneId?: number;
75
- schdPsetId?: number;
76
- temp?: number;
77
- dimming?: number;
78
- r?: number;
79
- g?: number;
80
- b?: number;
81
- c?: number;
82
- w?: number;
83
- speed?: number;
84
- ratio?: number;
85
- pc?: number;
86
- fanState?: number;
87
- fanMode?: number;
88
- fanSpeed?: number;
89
- fanRevrs?: number;
90
- [key: string]: unknown;
91
- }
92
-
93
- export interface IWizPilotPatch {
94
- state?: boolean;
95
- sceneId?: number;
96
- temp?: number;
97
- dimming?: number;
98
- r?: number;
99
- g?: number;
100
- b?: number;
101
- c?: number;
102
- w?: number;
103
- speed?: number;
104
- ratio?: number;
105
- fanState?: number;
106
- fanMode?: number;
107
- fanSpeed?: number;
108
- fanRevrs?: number;
109
- [key: string]: unknown;
110
- }
111
-
112
- export interface IWizSensorRecord {
113
- key: string;
114
- name?: string;
115
- platform?: 'sensor' | 'binary_sensor';
116
- value?: unknown;
117
- unit?: string;
118
- deviceClass?: string;
119
- writable?: boolean;
120
- available?: boolean;
121
- [key: string]: unknown;
122
- }
123
-
124
- export interface IWizButtonRecord {
125
- key: string;
126
- name?: string;
127
- value?: unknown;
128
- lastPressedAt?: string | number;
129
- available?: boolean;
130
- [key: string]: unknown;
131
- }
132
-
133
- export interface IWizEntityRecord {
134
- platform: TEntityPlatform;
135
- key?: string;
136
- entityId?: string;
137
- uniqueId?: string;
138
- name?: string;
139
- state?: unknown;
140
- attributes?: Record<string, unknown>;
141
- available?: boolean;
142
- writable?: boolean;
143
- [key: string]: unknown;
144
- }
145
-
146
- export interface IWizSnapshotDevice {
147
- id?: string;
148
- host?: string;
149
- port?: number;
150
- mac?: string;
151
- name?: string;
152
- available?: boolean;
153
- deviceInfo?: IWizDeviceInfo;
154
- pilot?: IWizPilotState;
155
- sensors?: IWizSensorRecord[];
156
- buttons?: IWizButtonRecord[];
157
- entities?: IWizEntityRecord[];
158
- metadata?: Record<string, unknown>;
159
- [key: string]: unknown;
160
- }
20
+ export type TWizControl =
21
+ | { readonly feature: 'power'; readonly value: boolean }
22
+ | { readonly feature: 'brightness'; readonly value: number }
23
+ | { readonly feature: 'rgb'; readonly value: Readonly<plugins.ecobridgeDeviceManager.IWizRgb> };
161
24
 
162
25
  export interface IWizSnapshot {
163
- connected: boolean;
164
- host?: string;
165
- port?: number;
166
- devices: IWizSnapshotDevice[];
167
- events: IWizEvent[];
26
+ readonly homeId: string;
27
+ readonly host: string;
28
+ readonly port: number;
29
+ readonly name?: string;
30
+ readonly info: plugins.ecobridgeDeviceManager.IWizDeviceInfo;
31
+ readonly observedAt: string;
168
32
  }
169
33
 
170
- export interface IWizEvent {
171
- type: 'pilot' | 'command_mapped' | 'command_failed' | 'udp_response' | 'error' | string;
172
- timestamp?: number;
173
- deviceId?: string;
174
- entityId?: string;
175
- command?: IWizClientCommand;
176
- data?: unknown;
177
- [key: string]: unknown;
178
- }
179
-
180
- export interface IWizClientCommand {
181
- type: string;
182
- service: string;
183
- deviceId?: string;
184
- entityId?: string;
185
- payload: IWizPilotPatch;
186
- target?: IServiceCallRequest['target'];
187
- [key: string]: unknown;
188
- }
189
-
190
- export interface IWizCommandResult {
191
- success: boolean;
192
- error?: string;
193
- data?: unknown;
194
- }
195
-
196
- export type TWizCommandExecutor = (
197
- commandArg: IWizClientCommand
198
- ) => Promise<IWizCommandResult | unknown> | IWizCommandResult | unknown;
199
-
200
- export interface IWizUdpCommand<TParams extends Record<string, unknown> = Record<string, unknown>> {
201
- method: string;
202
- params?: TParams;
203
- id?: number | string;
204
- env?: string;
205
- }
206
-
207
- export interface IWizUdpError {
208
- code?: number;
209
- message?: string;
210
- data?: unknown;
211
- }
212
-
213
- export interface IWizUdpResponse<TResult = unknown> {
214
- method?: string;
215
- env?: string;
216
- id?: number | string;
217
- result?: TResult;
218
- params?: TResult;
219
- error?: IWizUdpError;
220
- [key: string]: unknown;
34
+ export interface IWizWriteResult {
35
+ readonly outcome: plugins.ecobridgeDeviceManager.TWizEffectOutcome;
36
+ readonly physicalStateConfirmed: false;
37
+ readonly observedState?: plugins.ecobridgeDeviceManager.IWizPilotState;
38
+ readonly errorCode?: plugins.ecobridgeDeviceManager.TWizErrorCode;
221
39
  }
222
40
 
223
41
  export interface IWizMdnsRecord {
@@ -229,37 +47,19 @@ export interface IWizMdnsRecord {
229
47
  port?: number;
230
48
  txt?: Record<string, string | undefined>;
231
49
  properties?: Record<string, string | undefined>;
232
- [key: string]: unknown;
233
50
  }
234
51
 
235
52
  export interface IWizUdpDiscoveryRecord {
236
53
  host?: string;
237
- address?: string;
238
- ip?: string;
239
- ip_address?: string;
240
54
  port?: number;
241
- mac?: string;
242
- mac_address?: string;
243
- name?: string;
244
55
  method?: string;
245
56
  result?: Record<string, unknown>;
246
- response?: IWizUdpResponse<Record<string, unknown>>;
247
- metadata?: Record<string, unknown>;
248
- [key: string]: unknown;
57
+ response?: { method?: string; result?: Record<string, unknown> };
249
58
  }
250
59
 
251
60
  export interface IWizManualEntry {
252
61
  host?: string;
253
62
  port?: number;
254
- id?: string;
255
- mac?: string;
256
63
  macAddress?: string;
257
64
  name?: string;
258
- manufacturer?: string;
259
- model?: string;
260
- deviceInfo?: IWizDeviceInfo;
261
- pilot?: IWizPilotState;
262
- snapshot?: IWizSnapshot;
263
- metadata?: Record<string, unknown>;
264
- [key: string]: unknown;
265
65
  }
@@ -0,0 +1,73 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { IWizConfig, TWizControl } from './wiz.types.js';
3
+
4
+ export function wizRecord(valueArg: unknown, allowedArg?: readonly string[]): Record<string, unknown> {
5
+ if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg) || Object.getPrototypeOf(valueArg) !== Object.prototype) {
6
+ throw new TypeError('WiZ inputs must be plain data objects.');
7
+ }
8
+ const result: Record<string, unknown> = {};
9
+ for (const key of Reflect.ownKeys(valueArg)) {
10
+ const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
11
+ if (typeof key !== 'string' || allowedArg && !allowedArg.includes(key) || !descriptor || !('value' in descriptor) || !descriptor.enumerable) {
12
+ throw new TypeError('WiZ inputs may not contain accessors, symbols, hidden or unsupported fields.');
13
+ }
14
+ Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
15
+ }
16
+ return result;
17
+ }
18
+
19
+ export function wizText(valueArg: unknown, nameArg: string, maximumArg = 256): string {
20
+ if (typeof valueArg !== 'string' || !valueArg.length || valueArg.length > maximumArg || valueArg !== valueArg.trim() || /[\p{Cc}\p{Cs}]/u.test(valueArg)) {
21
+ throw new TypeError(`WiZ ${nameArg} must be bounded nonempty text without control characters.`);
22
+ }
23
+ return valueArg;
24
+ }
25
+
26
+ export function wizMac(valueArg: unknown): string {
27
+ if (typeof valueArg !== 'string' || !/^(?:[a-fA-F0-9]{12}|(?:[a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})$/.test(valueArg)) {
28
+ throw new TypeError('WiZ macAddress requires exactly six hexadecimal bytes.');
29
+ }
30
+ const mac = valueArg.replaceAll(':', '').toLowerCase();
31
+ if (mac === '000000000000' || (Number.parseInt(mac.slice(0, 2), 16) & 1) !== 0) throw new TypeError('WiZ requires a unicast device MAC.');
32
+ return mac;
33
+ }
34
+
35
+ export function wizAddress(valueArg: unknown): string {
36
+ if (typeof valueArg !== 'string' || plugins.net.isIP(valueArg) !== 4) throw new TypeError('WiZ requires an explicit local unicast IPv4 address.');
37
+ const parts = valueArg.split('.').map(Number);
38
+ const local = parts[0] === 10 || parts[0] === 127 || parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31 ||
39
+ parts[0] === 192 && parts[1] === 168 || parts[0] === 169 && parts[1] === 254;
40
+ if (!local || parts[3] === 0 || parts[3] === 255) throw new TypeError('WiZ requires a private, link-local or loopback unicast IPv4 address.');
41
+ return valueArg;
42
+ }
43
+
44
+ export function wizInteger(valueArg: unknown, fallbackArg: number, minimumArg: number, maximumArg: number): number {
45
+ const value = valueArg === undefined ? fallbackArg : valueArg;
46
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < minimumArg || value > maximumArg) {
47
+ throw new TypeError(`WiZ value must be an integer from ${minimumArg} through ${maximumArg}.`);
48
+ }
49
+ return value;
50
+ }
51
+
52
+ export function normalizeWizConfig(valueArg: unknown): Readonly<Required<Omit<IWizConfig, 'name'>> & Pick<IWizConfig, 'name'>> {
53
+ const value = wizRecord(valueArg, ['homeId', 'host', 'macAddress', 'port', 'name', 'timeoutMs', 'pollIntervalMs', 'maxPendingOperations', 'maxExchanges']);
54
+ const pollIntervalMs = wizInteger(value.pollIntervalMs, 30000, 0, 3600000);
55
+ if (pollIntervalMs > 0 && pollIntervalMs < 100) throw new TypeError('WiZ subscription polling must be disabled or at least 100 milliseconds.');
56
+ return Object.freeze({
57
+ homeId: wizText(value.homeId, 'homeId'), host: wizAddress(value.host), macAddress: wizMac(value.macAddress),
58
+ port: wizInteger(value.port, 38899, 1, 65535), ...(value.name === undefined ? {} : { name: wizText(value.name, 'name', 128) }),
59
+ timeoutMs: wizInteger(value.timeoutMs, 5000, 1, 60000), pollIntervalMs,
60
+ maxPendingOperations: wizInteger(value.maxPendingOperations, 16, 1, 128), maxExchanges: wizInteger(value.maxExchanges, 4096, 1, 16384),
61
+ });
62
+ }
63
+
64
+ export function wizControl(valueArg: unknown): TWizControl {
65
+ const value = wizRecord(valueArg, ['feature', 'value']);
66
+ if (value.feature === 'power' && typeof value.value === 'boolean') return Object.freeze({ feature: 'power', value: value.value });
67
+ if (value.feature === 'brightness') return Object.freeze({ feature: 'brightness', value: wizInteger(value.value, 0, 1, 100) });
68
+ if (value.feature === 'rgb') {
69
+ const rgb = wizRecord(value.value, ['red', 'green', 'blue']);
70
+ return Object.freeze({ feature: 'rgb', value: Object.freeze({ red: wizInteger(rgb.red, -1, 0, 255), green: wizInteger(rgb.green, -1, 0, 255), blue: wizInteger(rgb.blue, -1, 0, 255) }) });
71
+ }
72
+ throw new TypeError('WiZ supports one exact power, brightness or RGB control per operation.');
73
+ }
@@ -4,3 +4,4 @@ export * from './yamaha.classes.integration.js';
4
4
  export * from './yamaha.discovery.js';
5
5
  export * from './yamaha.mapper.js';
6
6
  export * from './yamaha.types.js';
7
+ export * from './yamaha.validation.js';
@@ -1,9 +1,153 @@
1
- import { SimpleLocalClient } from '../../core/index.js';
2
- import type { IYamahaConfig } from './yamaha.types.js';
3
- import { yamahaProfile } from './yamaha.types.js';
1
+ import * as plugins from '../../plugins.js';
2
+ import { NativeHomeAdmission, type INativeAdmissionContext } from '../../core/classes.nativehomeadmission.js';
3
+ import type { INativeIntegrationSetupContext } from '../../core/types.js';
4
+ import type { IYamahaConfig, IYamahaEffectResult, IYamahaSnapshot, TYamahaControl } from './yamaha.types.js';
5
+ import { assertYamahaScope, normalizeYamahaConfig, validateYamahaControl } from './yamaha.validation.js';
4
6
 
5
- export class YamahaClient extends SimpleLocalClient<IYamahaConfig> {
6
- constructor(configArg: IYamahaConfig) {
7
- super(yamahaProfile, configArg);
7
+ /** The published protocol owns wire behavior; this facade owns exact home admission and caller work. */
8
+ export class YamahaClient {
9
+ public readonly config: ReturnType<typeof normalizeYamahaConfig>;
10
+ private readonly context: INativeAdmissionContext;
11
+ private readonly protocol: plugins.ecobridgeDeviceManager.YamahaProtocol;
12
+ private readonly lifetime = new AbortController();
13
+ private operationTail: Promise<void> = Promise.resolve();
14
+ private pendingOperations = 0;
15
+ private startPromise?: Promise<IYamahaSnapshot>;
16
+ private snapshot?: IYamahaSnapshot;
17
+ private healthy = false;
18
+ private closePromise?: Promise<void>;
19
+ private retryPromise?: Promise<void>;
20
+
21
+ public constructor(config: IYamahaConfig, context: INativeIntegrationSetupContext) {
22
+ this.config = normalizeYamahaConfig(config);
23
+ this.context = new NativeHomeAdmission('yamaha').admit(context, this.config.homeId);
24
+ this.protocol = new plugins.ecobridgeDeviceManager.YamahaProtocol({ origin: this.config.origin,
25
+ expectedDeviceId: this.config.expectedDeviceId, expectedModel: this.config.model,
26
+ allowUnencryptedHttp: this.config.allowUnencryptedHttp, maxVolume: this.config.maxVolume,
27
+ timeoutMs: this.config.timeoutMs, maxResponseBytes: this.config.maxResponseBytes, maxPendingOperations: this.config.maxPendingOperations });
28
+ }
29
+
30
+ public isHealthy(): boolean { return !this.lifetime.signal.aborted && !this.context.abortSignal?.aborted && this.healthy && this.protocol.isStarted; }
31
+
32
+ public start(signal?: AbortSignal): Promise<IYamahaSnapshot> {
33
+ try { this.assertOpen(); } catch (error) { return Promise.reject(error); }
34
+ if (!this.startPromise) {
35
+ this.startPromise = this.run(async (operationSignal, timeoutMs) => this.observe(await this.protocol.start({ signal: operationSignal, timeoutMs })),
36
+ signal, false).catch(async (error: unknown) => {
37
+ this.lifetime.abort(error);
38
+ try { await this.protocol.close(); }
39
+ catch (cleanupError) { throw new AggregateError([error, cleanupError], 'Yamaha startup and cleanup failed.'); }
40
+ throw error;
41
+ });
42
+ }
43
+ return this.startPromise;
44
+ }
45
+
46
+ public getObservedSnapshot(): IYamahaSnapshot {
47
+ this.assertOpen();
48
+ if (!this.snapshot) throw new Error('Yamaha has no admitted observation.');
49
+ return this.snapshot;
50
+ }
51
+
52
+ public getSnapshot(signal?: AbortSignal): Promise<IYamahaSnapshot> {
53
+ return this.run(async (operationSignal, timeoutMs) => this.observe(await this.protocol.readState({ signal: operationSignal, timeoutMs })), signal);
54
+ }
55
+
56
+ public setControl(value: TYamahaControl, signal?: AbortSignal): Promise<IYamahaEffectResult> {
57
+ const control = validateYamahaControl(value);
58
+ if (control.feature === 'volume_raw' && control.value > this.config.maxVolume) throw new RangeError('Yamaha volume exceeds the owner ceiling.');
59
+ return this.run(async (operationSignal, timeoutMs) => {
60
+ const options = { signal: operationSignal, timeoutMs };
61
+ const result = control.feature === 'power' ? await this.protocol.setPower(control.value, options)
62
+ : control.feature === 'muted' ? await this.protocol.setMute(control.value, options)
63
+ : control.feature === 'volume_raw' ? await this.protocol.setVolume(control.value, options)
64
+ : await this.protocol.setInput(control.value, options);
65
+ try { return Object.freeze({ dispatch: result.dispatch, outcome: result.outcome, snapshot: this.observe(result.observation) }); }
66
+ catch { throw new plugins.ecobridgeDeviceManager.YamahaProtocolError('Yamaha observation could not be admitted after dispatch.', 'identity-mismatch', 'indeterminate'); }
67
+ }, signal);
68
+ }
69
+
70
+ public destroy(): Promise<void> {
71
+ if (!this.closePromise) {
72
+ this.healthy = false;
73
+ this.closePromise = Promise.resolve().then(() => this.drain());
74
+ this.lifetime.abort(new Error('Yamaha client is closed.'));
75
+ }
76
+ return this.closePromise;
77
+ }
78
+
79
+ /** Explicitly retries cleanup of this terminal client, without replaying receiver work. */
80
+ public retryCleanup(): Promise<void> {
81
+ if (!this.closePromise) return Promise.reject(new Error('Yamaha cleanup retry requires a closed client.'));
82
+ if (!this.retryPromise) {
83
+ const retry = Promise.resolve().then(() => this.drain());
84
+ this.retryPromise = retry;
85
+ const settled = (): void => { this.retryPromise = undefined; };
86
+ void retry.then(settled, settled);
87
+ }
88
+ return this.retryPromise;
89
+ }
90
+
91
+ private async drain(): Promise<void> {
92
+ const results = await Promise.allSettled([
93
+ Promise.resolve().then(() => this.protocol.close()), this.operationTail, this.startPromise,
94
+ ]);
95
+ this.snapshot = undefined;
96
+ const closure = results[0];
97
+ if (closure.status === 'rejected') throw closure.reason;
98
+ }
99
+
100
+ private observe(state: plugins.ecobridgeDeviceManager.IYamahaState): IYamahaSnapshot {
101
+ this.assertOpen();
102
+ this.snapshot = Object.freeze({ homeId: this.context.homeId, origin: this.config.origin,
103
+ name: this.config.name ?? 'Yamaha RX-V485 main zone', identity: Object.freeze({ ...state.identity }),
104
+ power: state.power, muted: state.muted, volume: state.volume, receiverMaxVolume: state.maxVolume,
105
+ ownerMaxVolume: this.config.maxVolume, input: state.input, inputs: Object.freeze([...state.capabilities.inputs]),
106
+ volumeRange: Object.freeze({ ...state.capabilities.volumeRange }), observedAt: state.observedAt });
107
+ this.healthy = true;
108
+ return this.snapshot;
109
+ }
110
+
111
+ private assertOpen(): void {
112
+ this.lifetime.signal.throwIfAborted();
113
+ if (this.context.abortSignal) AbortSignal.prototype.throwIfAborted.call(this.context.abortSignal);
114
+ assertYamahaScope(this.context.configStore, this.context.homeId);
115
+ }
116
+
117
+ /** Validate scope when adapter work runs; its single deadline includes waiting for earlier calls. */
118
+ private run<TResult>(execute: (signal: AbortSignal, timeoutMs: number) => Promise<TResult>, signal?: AbortSignal, started = true): Promise<TResult> {
119
+ try {
120
+ this.assertOpen();
121
+ if (signal !== undefined && !(signal instanceof AbortSignal)) throw new TypeError('Yamaha cancellation requires an AbortSignal.');
122
+ signal?.throwIfAborted();
123
+ if (started && !this.protocol.isStarted) throw new Error('Yamaha client has not started.');
124
+ if (this.pendingOperations >= this.config.maxPendingOperations) throw new Error('Yamaha operation capacity reached.');
125
+ } catch (error) { return Promise.reject(error); }
126
+ const deadline = performance.now() + this.config.timeoutMs;
127
+ const controller = new AbortController();
128
+ const combined = AbortSignal.any([this.lifetime.signal, controller.signal,
129
+ ...(this.context.abortSignal ? [this.context.abortSignal] : []), ...(signal ? [signal] : [])]);
130
+ const timer = setTimeout(() => controller.abort(new plugins.ecobridgeDeviceManager.YamahaProtocolError('Yamaha operation deadline expired.', 'timeout')), this.config.timeoutMs);
131
+ this.pendingOperations++;
132
+ let rejectWaiting: () => void = () => {};
133
+ const waitingCancelled = new Promise<never>((_resolve, reject) => {
134
+ rejectWaiting = () => reject(combined.reason);
135
+ combined.addEventListener('abort', rejectWaiting, { once: true });
136
+ });
137
+ const operation = this.operationTail.then(async () => {
138
+ combined.removeEventListener('abort', rejectWaiting);
139
+ combined.throwIfAborted();
140
+ this.assertOpen();
141
+ const remaining = Math.floor(deadline - performance.now());
142
+ if (remaining < 1) throw new plugins.ecobridgeDeviceManager.YamahaProtocolError('Yamaha queued operation expired.', 'timeout');
143
+ return execute(combined, remaining);
144
+ }).catch((error: unknown) => { this.healthy = false; throw error; }).finally(() => {
145
+ combined.removeEventListener('abort', rejectWaiting);
146
+ clearTimeout(timer);
147
+ this.pendingOperations--;
148
+ });
149
+ this.operationTail = operation.then(() => {}, () => {});
150
+ if (combined.aborted) rejectWaiting();
151
+ return Promise.race([operation, waitingCancelled]);
8
152
  }
9
153
  }
@@ -1,9 +1,104 @@
1
- import { SimpleLocalConfigFlow } from '../../core/index.js';
1
+ import * as plugins from '../../plugins.js';
2
+ import { NativeIntegrationOwner, NativeIntegrationScope } from '../../core/classes.nativeintegrationowner.js';
3
+ import type { IConfigFlow, INativeConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
2
4
  import type { IYamahaConfig } from './yamaha.types.js';
3
- import { yamahaProfile } from './yamaha.types.js';
5
+ import { YamahaClient } from './yamaha.classes.client.js';
6
+ import { normalizeYamahaConfig, yamahaRecord } from './yamaha.validation.js';
4
7
 
5
- export class YamahaConfigFlow extends SimpleLocalConfigFlow<IYamahaConfig> {
6
- constructor() {
7
- super(yamahaProfile);
8
+ interface IYamahaConfigWrite {
9
+ readonly promise: Promise<void>;
10
+ accepted: boolean;
11
+ }
12
+
13
+ export class YamahaConfigFlow implements IConfigFlow<IYamahaConfig> {
14
+ private readonly scope: NativeIntegrationScope;
15
+ private readonly writes = new Set<IYamahaConfigWrite>();
16
+ private closePromise?: Promise<void>;
17
+
18
+ public constructor(scope: NativeIntegrationScope = new NativeIntegrationOwner('yamaha').createFlowScope()) {
19
+ this.scope = scope;
20
+ }
21
+
22
+ public async start(input: IDiscoveryCandidate, context: INativeConfigFlowContext): Promise<IConfigFlowStep<IYamahaConfig>> {
23
+ const candidate = yamahaRecord(input);
24
+ if (candidate.integrationDomain !== 'yamaha') return { kind: 'error', error: 'Candidate does not belong to Yamaha.' };
25
+ const metadata = candidate.metadata === undefined ? {} : yamahaRecord(candidate.metadata);
26
+ const hints = { origin: metadata.origin, expectedDeviceId: candidate.id, model: candidate.model };
27
+ const captured = this.scope.admit(context);
28
+ let pending = false;
29
+ let completed = false;
30
+ return {
31
+ kind: 'form', title: 'Connect selected Yamaha RX-V485 main zone',
32
+ description: 'Confirm selected literal private HTTP origin, expected device_id, plaintext LAN trust and an owner ceiling in vendor raw integer volume units. The embedding host selects the home. No percentage or dB conversion is inferred.',
33
+ fields: [
34
+ { name: 'origin', label: 'Selected receiver HTTP origin', type: 'text', required: true },
35
+ { name: 'expectedDeviceId', label: 'Expected 12-character device_id', type: 'text', required: true },
36
+ { name: 'model', label: 'Documented model', type: 'select', required: true, options: [{ label: 'RX-V485', value: 'RX-V485' }] },
37
+ { name: 'allowUnencryptedHttp', label: 'Allow unauthenticated plaintext LAN HTTP', type: 'boolean', required: true },
38
+ { name: 'maxVolume', label: 'Owner maximum volume (vendor raw integer units)', type: 'number', required: true },
39
+ { name: 'name', label: 'Display name', type: 'text' },
40
+ ],
41
+ submit: (inputValues) => {
42
+ if (pending || completed) return Promise.reject(new Error('Yamaha config flow submission is unavailable.'));
43
+ try {
44
+ const values = yamahaRecord(inputValues, ['homeId', 'origin', 'expectedDeviceId', 'model', 'allowUnencryptedHttp', 'maxVolume', 'name', 'timeoutMs', 'maxResponseBytes', 'maxPendingOperations']);
45
+ if (values.homeId !== undefined && values.homeId !== captured.homeId) throw new Error('Yamaha submitted home conflicts with the selected host home.');
46
+ const config = normalizeYamahaConfig({ ...hints, ...values, homeId: captured.homeId });
47
+ const submission = this.scope.run(captured, config.homeId, async (lease): Promise<IConfigFlowStep<IYamahaConfig>> => {
48
+ const client = new YamahaClient(config, lease.context);
49
+ let cleanupStarted = false;
50
+ lease.own(() => {
51
+ const retry = cleanupStarted;
52
+ cleanupStarted = true;
53
+ return retry ? client.retryCleanup() : client.destroy();
54
+ });
55
+ try { await client.start(lease.signal); }
56
+ catch (error) {
57
+ if (!lease.signal.aborted && error instanceof plugins.ecobridgeDeviceManager.YamahaProtocolError) {
58
+ return { kind: 'error', title: 'Receiver admission failed', error: error.message };
59
+ }
60
+ throw error;
61
+ }
62
+ lease.assertOpen();
63
+ const store = lease.context.configStore;
64
+ if (store) {
65
+ // Ownership precedes a synchronous caller callback; accepted writes drain during close.
66
+ const write: IYamahaConfigWrite = { accepted: false, promise: Promise.resolve().then(async () => {
67
+ lease.assertOpen();
68
+ write.accepted = true;
69
+ await store.set(`receiver.${encodeURIComponent(config.expectedDeviceId)}`, config);
70
+ }) };
71
+ this.writes.add(write);
72
+ try { await write.promise; } finally { this.writes.delete(write); }
73
+ }
74
+ completed = true;
75
+ return { kind: 'done', title: 'Selected receiver admitted', config };
76
+ });
77
+ pending = true;
78
+ const settled = (): void => { pending = false; };
79
+ void submission.then(settled, settled);
80
+ return submission;
81
+ } catch (error) { return Promise.reject(error); }
82
+ },
83
+ };
84
+ }
85
+
86
+ public destroy(): Promise<void> {
87
+ if (!this.closePromise) {
88
+ const writes = [...this.writes];
89
+ this.closePromise = Promise.resolve().then(async () => {
90
+ const [cleanup, results] = await Promise.all([
91
+ Promise.allSettled([this.scope.close()]), Promise.allSettled(writes.map((write) => write.promise)),
92
+ ]);
93
+ const failures = cleanup.filter((entry): entry is PromiseRejectedResult => entry.status === 'rejected').map((entry) => entry.reason as unknown);
94
+ results.forEach((entry, index) => { if (entry.status === 'rejected' && writes[index].accepted) failures.push(entry.reason); });
95
+ if (failures.length) throw new AggregateError(failures, 'Yamaha config flow cleanup failed.');
96
+ });
97
+ // Terminal admission is immediate; close owns all accepted submissions and borrowed-store writes.
98
+ void this.scope.close().catch(() => undefined);
99
+ }
100
+ return this.closePromise;
8
101
  }
102
+
103
+ public retryCleanup(): Promise<void> { return this.scope.retryCleanup(); }
9
104
  }