@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,84 +1,55 @@
1
1
  import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
2
- import type { IBraviatvConfig } from './braviatv.types.js';
2
+ import { NativeIntegrationOwner, type NativeIntegrationScope } from '../../core/classes.nativeintegrationowner.js';
3
+ import type { IBraviatvConfig, IBraviatvIntegrationOptions } from './braviatv.types.js';
4
+ import { BraviatvClient } from './braviatv.classes.client.js';
5
+ import { braviatvRecord, normalizeBraviatvConfig, normalizeBraviatvOptions } from './braviatv.validation.js';
3
6
 
4
7
  export class BraviatvConfigFlow implements IConfigFlow<IBraviatvConfig> {
5
- public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IBraviatvConfig>> {
6
- void contextArg;
7
- return {
8
- kind: 'form',
9
- title: 'Connect Sony Bravia TV',
10
- description: 'Configure the local Sony Bravia REST/IRCC endpoint. This native port supports PSK authentication for live control; PIN pairing/cookie auth is reported as unsupported.',
8
+ readonly #options?: Readonly<IBraviatvIntegrationOptions>;
9
+ readonly #scope: NativeIntegrationScope;
10
+ public constructor(options?: IBraviatvIntegrationOptions, scope?: NativeIntegrationScope) {
11
+ this.#options = options === undefined ? undefined : normalizeBraviatvOptions(options);
12
+ this.#scope = scope ?? new NativeIntegrationOwner('braviatv', { homeId: this.#options?.homeId, capacity: this.#options?.capacity }).createFlowScope();
13
+ }
14
+ public async start(input: IDiscoveryCandidate, context: IConfigFlowContext): Promise<IConfigFlowStep<IBraviatvConfig>> {
15
+ const candidate = braviatvRecord(input);
16
+ if (candidate.integrationDomain !== 'braviatv') return { kind: 'error', error: 'Candidate does not belong to BRAVIA.' };
17
+ if (!this.#options) return { kind: 'error', error: 'BRAVIA admission requires caller-owned PSK resolver options.' };
18
+ const options = this.#options;
19
+ const hints = { host: candidate.host };
20
+ const admitted = this.#scope.admit(context);
21
+ return { kind: 'form', title: 'Select BRAVIA Professional display',
22
+ description: 'Confirm private IPv4, model and active-network MAC for the host-selected home. Caller provides a private-level PSK reference. LAN HTTP is unencrypted and PSK access does not prove peer identity. Speaker volume uses integer raw levels.',
11
23
  fields: [
12
- { name: 'host', label: 'Host', type: 'text', required: true },
13
- { name: 'port', label: 'HTTP port', type: 'number' },
14
- { name: 'useSsl', label: 'Use HTTPS', type: 'boolean' },
15
- { name: 'psk', label: 'Pre-shared key (PSK)', type: 'password' },
16
- { name: 'pin', label: 'PIN (pairing not implemented)', type: 'password' },
17
- { name: 'name', label: 'Name', type: 'text' },
18
- { name: 'model', label: 'Model', type: 'text' },
24
+ { name: 'host', label: 'Selected display IPv4', type: 'text', required: true },
25
+ { name: 'expectedModel', label: 'Exact observed model', type: 'text', required: true },
26
+ { name: 'expectedMacAddress', label: 'Exact active-network MAC', type: 'text', required: true },
27
+ { name: 'expectedSerial', label: 'Exact serial (optional)', type: 'text' },
28
+ { name: 'credentialRef', label: 'Caller private-level PSK reference', type: 'text', required: true },
29
+ { name: 'allowUnencryptedLan', label: 'Allow unencrypted selected LAN HTTP', type: 'boolean', required: true },
30
+ { name: 'volumeLimitRaw', label: 'Owner speaker ceiling (integer raw level 0..100)', type: 'number', required: true },
31
+ { name: 'name', label: 'Display name', type: 'text' },
19
32
  ],
20
- submit: async (valuesArg) => {
21
- const host = this.stringValue(valuesArg.host) || candidateArg.host;
22
- if (!host) {
23
- return { kind: 'error', error: 'Sony Bravia TV host is required.' };
24
- }
25
-
26
- const psk = this.stringValue(valuesArg.psk) || this.stringMetadata(candidateArg, 'psk');
27
- const pin = this.stringValue(valuesArg.pin);
28
- if (pin && !psk) {
29
- return { kind: 'error', error: 'Sony Bravia TV PIN pairing/cookie authentication is not implemented in this native TypeScript port. Configure a PSK instead.' };
33
+ submit: async (inputValues) => {
34
+ try {
35
+ const values = braviatvRecord(inputValues, ['homeId', 'host', 'expectedModel', 'expectedMacAddress', 'expectedSerial',
36
+ 'credentialRef', 'allowUnencryptedLan', 'volumeLimitRaw', 'name', 'port', 'timeoutMs', 'maxPendingOperations', 'maxResponseBytes']);
37
+ if (values.homeId !== undefined && values.homeId !== admitted.homeId) throw new Error('BRAVIA submitted home conflicts with the host-selected home.');
38
+ // Discovery supplies only captured endpoint hints; exact model and MAC remain explicit selections.
39
+ const config = normalizeBraviatvConfig({ ...values, homeId: admitted.homeId, host: values.host ?? hints.host });
40
+ return await this.#scope.run(admitted, config.homeId, async (lease) => {
41
+ const client = new BraviatvClient(config, { ...lease.context, abortSignal: lease.signal }, options);
42
+ lease.own(() => client.retryCleanup());
43
+ await client.start(lease.signal);
44
+ lease.assertOpen();
45
+ return { kind: 'done', title: 'Selected display admitted', config };
46
+ });
47
+ } catch (error) {
48
+ if (error instanceof AggregateError) throw error;
49
+ return { kind: 'error', title: 'Display admission failed', error: 'Confirm exact home and display identity, private PSK reference, explicit LAN consent, supported APIs and owner speaker ceiling.' };
30
50
  }
31
-
32
- const useSsl = this.booleanValue(valuesArg.useSsl) ?? this.booleanMetadata(candidateArg, 'useSsl') ?? false;
33
- return {
34
- kind: 'done',
35
- title: 'Sony Bravia TV configured',
36
- config: {
37
- host,
38
- port: this.numberValue(valuesArg.port) || candidateArg.port || (useSsl ? 443 : 80),
39
- useSsl,
40
- psk,
41
- pin,
42
- usePsk: Boolean(psk),
43
- name: this.stringValue(valuesArg.name) || candidateArg.name,
44
- model: this.stringValue(valuesArg.model) || candidateArg.model,
45
- manufacturer: candidateArg.manufacturer || 'Sony',
46
- macAddress: candidateArg.macAddress,
47
- serialNumber: candidateArg.serialNumber,
48
- cid: candidateArg.id || this.stringMetadata(candidateArg, 'cid'),
49
- scalarWebApiBaseUrl: this.stringMetadata(candidateArg, 'scalarWebApiBaseUrl'),
50
- },
51
- };
52
- },
53
- };
54
- }
55
-
56
- private stringValue(valueArg: unknown): string | undefined {
57
- return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
58
- }
59
-
60
- private numberValue(valueArg: unknown): number | undefined {
61
- if (typeof valueArg === 'number' && Number.isFinite(valueArg)) {
62
- return valueArg;
63
- }
64
- if (typeof valueArg === 'string' && valueArg.trim()) {
65
- const value = Number(valueArg);
66
- return Number.isFinite(value) ? value : undefined;
67
- }
68
- return undefined;
69
- }
70
-
71
- private booleanValue(valueArg: unknown): boolean | undefined {
72
- return typeof valueArg === 'boolean' ? valueArg : undefined;
73
- }
74
-
75
- private stringMetadata(candidateArg: IDiscoveryCandidate, keyArg: string): string | undefined {
76
- const value = candidateArg.metadata?.[keyArg];
77
- return typeof value === 'string' && value ? value : undefined;
78
- }
79
-
80
- private booleanMetadata(candidateArg: IDiscoveryCandidate, keyArg: string): boolean | undefined {
81
- const value = candidateArg.metadata?.[keyArg];
82
- return typeof value === 'boolean' ? value : undefined;
51
+ } };
83
52
  }
53
+ public destroy(): Promise<void> { return this.#scope.close(); }
54
+ public retryCleanup(): Promise<void> { return this.#scope.retryCleanup(); }
84
55
  }
@@ -1,177 +1,197 @@
1
1
  import * as plugins from '../../plugins.js';
2
2
  import { BaseIntegration } from '../../core/classes.baseintegration.js';
3
- import type { IIntegrationEntity, IIntegrationRuntime, IIntegrationSetupContext, IServiceCallRequest, IServiceCallResult } from '../../core/types.js';
3
+ import { NativeIntegrationOwner, type INativeSetupLease } from '../../core/classes.nativeintegrationowner.js';
4
+ import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IIntegrationEvent, IIntegrationRuntime,
5
+ IServiceCallRequest, IServiceCallResult } from '../../core/types.js';
4
6
  import { BraviatvClient } from './braviatv.classes.client.js';
5
7
  import { BraviatvConfigFlow } from './braviatv.classes.configflow.js';
6
8
  import { createBraviatvDiscoveryDescriptor } from './braviatv.discovery.js';
7
9
  import { BraviatvMapper } from './braviatv.mapper.js';
8
- import type { IBraviatvConfig } from './braviatv.types.js';
10
+ import { braviatvRecord, normalizeBraviatvConfig, normalizeBraviatvOptions, validateBraviatvControl } from './braviatv.validation.js';
11
+ import type { IBraviatvConfig, IBraviatvEffectResult, IBraviatvIntegrationOptions,
12
+ IBraviatvSetupContext, IBraviatvSnapshot, TBraviatvControl } from './braviatv.types.js';
9
13
 
10
14
  export class BraviatvIntegration extends BaseIntegration<IBraviatvConfig> {
11
15
  public readonly domain = 'braviatv';
12
- public readonly displayName = 'Sony Bravia TV';
16
+ public readonly displayName = 'Selected Sony BRAVIA Professional display';
13
17
  public readonly status = 'control-runtime' as const;
14
18
  public readonly discoveryDescriptor = createBraviatvDiscoveryDescriptor();
15
- public readonly configFlow = new BraviatvConfigFlow();
16
- public readonly metadata = {
17
- source: 'home-assistant/core',
18
- upstreamPath: 'homeassistant/components/braviatv',
19
- upstreamDomain: 'braviatv',
20
- integrationType: 'device',
21
- iotClass: 'local_polling',
22
- requirements: ['pybravia==0.4.1'],
23
- dependencies: ['ssdp'],
24
- afterDependencies: [],
25
- codeowners: ['@bieniu', '@Drafteed'],
26
- configFlow: true,
27
- documentation: 'https://www.home-assistant.io/integrations/braviatv',
28
- };
19
+ public readonly configFlow: BraviatvConfigFlow;
20
+ public readonly metadata = { source: 'native-typescript', integrationType: 'device', iotClass: 'local_poll',
21
+ documentation: 'https://pro-bravia.sony.net/remote-display-control/rest-api/reference/' };
22
+ readonly #options?: Readonly<IBraviatvIntegrationOptions>;
23
+ readonly #owner: NativeIntegrationOwner;
29
24
 
30
- public async setup(configArg: IBraviatvConfig, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime> {
31
- void contextArg;
32
- return new BraviatvRuntime(new BraviatvClient(configArg));
25
+ /** Unconfigured registry descriptors are inert; setup requires explicit caller home and credentials. */
26
+ public constructor(options?: IBraviatvIntegrationOptions) {
27
+ super();
28
+ this.#options = options === undefined ? undefined : normalizeBraviatvOptions(options);
29
+ this.#owner = new NativeIntegrationOwner('braviatv', { homeId: this.#options?.homeId, capacity: this.#options?.capacity });
30
+ this.configFlow = new BraviatvConfigFlow(this.#options, this.#owner.createFlowScope());
33
31
  }
34
32
 
35
- public async destroy(): Promise<void> {}
36
- }
33
+ public setup(config: IBraviatvConfig, context: IBraviatvSetupContext): Promise<IIntegrationRuntime> {
34
+ if (!this.#options) return Promise.reject(new Error('BRAVIA setup requires caller-owned PSK resolver options.'));
35
+ const options = this.#options;
36
+ try {
37
+ const selected = normalizeBraviatvConfig(config);
38
+ return this.#owner.runSetup(context, selected.homeId, async (lease) => {
39
+ const client = new BraviatvClient(selected, { ...lease.context, abortSignal: lease.signal }, options);
40
+ let runtime: BraviatvRuntime | undefined;
41
+ lease.own(async () => {
42
+ const ownedRuntime = runtime;
43
+ const results = await Promise.allSettled([
44
+ Promise.resolve().then(() => client.retryCleanup()),
45
+ ...(ownedRuntime ? [Promise.resolve().then(() => ownedRuntime.closeSubscriptions())] : []),
46
+ ]);
47
+ const failures = results.filter((entry): entry is PromiseRejectedResult => entry.status === 'rejected');
48
+ if (failures.length) throw new AggregateError(failures.map((entry) => entry.reason), 'BRAVIA owned cleanup failed.');
49
+ });
50
+ const initial = await client.start(lease.signal);
51
+ lease.assertOpen();
52
+ runtime = new BraviatvRuntime(client, initial, lease);
53
+ lease.promoteToRuntime();
54
+ return runtime;
55
+ });
56
+ } catch (error) { return Promise.reject(error); }
57
+ }
37
58
 
59
+ public destroy(): Promise<void> {
60
+ return this.#owner.close();
61
+ }
62
+ public retryCleanup(): Promise<void> { return this.#owner.retryCleanup(); }
63
+ }
38
64
  export class HomeAssistantBraviatvIntegration extends BraviatvIntegration {}
39
65
 
40
- class BraviatvRuntime implements IIntegrationRuntime {
41
- public domain = 'braviatv';
66
+ interface IBraviatvSubscription {
67
+ handler: (event: IIntegrationEvent) => void;
68
+ active: boolean;
69
+ failed: boolean;
70
+ detach(): void;
71
+ stop(): Promise<void>;
72
+ }
42
73
 
43
- constructor(private readonly client: BraviatvClient) {}
74
+ class BraviatvRuntime implements IIntegrationRuntime {
75
+ public readonly domain = 'braviatv';
76
+ readonly #subscriptions = new Set<IBraviatvSubscription>();
77
+ readonly #parentAbort: () => void;
78
+ #closePromise?: Promise<void>;
79
+ #closed = false;
44
80
 
45
- public async devices(): Promise<plugins.shxInterfaces.data.IDeviceDefinition[]> {
46
- return BraviatvMapper.toDevices(await this.client.getSnapshot());
81
+ public constructor(private readonly client: BraviatvClient, private snapshot: IBraviatvSnapshot,
82
+ private readonly lease: INativeSetupLease) {
83
+ this.#parentAbort = () => { void this.destroy().catch(() => {}); };
84
+ lease.signal.addEventListener('abort', this.#parentAbort, { once: true });
85
+ if (lease.signal.aborted) this.#parentAbort();
86
+ }
87
+ public isHealthy(): boolean { return !this.#closed && this.client.isHealthy(); }
88
+ public async devices(signal?: AbortSignal): Promise<plugins.shxInterfaces.data.IDeviceDefinition[]> {
89
+ this.assertOpen();
90
+ const snapshot = await this.client.getSnapshot(signal);
91
+ this.publish(snapshot);
92
+ return BraviatvMapper.toDevices(snapshot);
47
93
  }
48
-
49
94
  public async entities(): Promise<IIntegrationEntity[]> {
50
- return BraviatvMapper.toEntities(await this.client.getSnapshot());
95
+ this.assertOpen();
96
+ const snapshot = await this.client.getSnapshot();
97
+ this.publish(snapshot);
98
+ return BraviatvMapper.toEntities(snapshot);
51
99
  }
52
-
53
- public async callService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
54
- try {
55
- if (requestArg.domain === 'remote') {
56
- return await this.callRemoteService(requestArg);
57
- }
58
- if (requestArg.domain === 'braviatv') {
59
- return await this.callBraviatvService(requestArg);
60
- }
61
- if (requestArg.domain !== 'media_player') {
62
- return { success: false, error: `Unsupported Sony Bravia TV service domain: ${requestArg.domain}` };
63
- }
64
- return await this.callMediaPlayerService(requestArg);
65
- } catch (errorArg) {
66
- return { success: false, error: errorArg instanceof Error ? errorArg.message : String(errorArg) };
67
- }
100
+ public async writeFeature(input: IDeviceFeatureWriteRequest, signal?: AbortSignal): Promise<IServiceCallResult> {
101
+ this.assertOpen();
102
+ const request = braviatvRecord(input, ['device', 'feature', 'value']);
103
+ const device = braviatvRecord(request.device);
104
+ const feature = braviatvRecord(request.feature);
105
+ const deviceId = BraviatvMapper.deviceId(this.snapshot.homeId, this.snapshot.identity.macAddress);
106
+ if (device.id !== deviceId || device.integrationDomain !== this.domain) throw new Error('BRAVIA feature target is outside the selected home and display.');
107
+ const control = validateBraviatvControl({ feature: feature.id, value: request.value });
108
+ if (feature.capability !== (control.feature === 'speaker_volume_raw' ? 'sensor' : 'switch')) throw new Error('BRAVIA feature capability does not match the selected control.');
109
+ return this.control(control, signal);
68
110
  }
69
-
70
- public async destroy(): Promise<void> {
71
- await this.client.destroy();
111
+ public async callService(input: IServiceCallRequest): Promise<IServiceCallResult> {
112
+ this.assertOpen();
113
+ const request = braviatvRecord(input, ['domain', 'service', 'target', 'data']);
114
+ if (request.domain !== 'braviatv') throw new Error('BRAVIA selected-display services use braviatv.');
115
+ let control: TBraviatvControl;
116
+ if (request.service === 'set_power') {
117
+ const data = braviatvRecord(request.data, ['power']);
118
+ control = validateBraviatvControl({ feature: 'power', value: data.power });
119
+ } else if (request.service === 'set_device_mute') {
120
+ const data = braviatvRecord(request.data, ['muted']);
121
+ control = validateBraviatvControl({ feature: 'device_mute', value: data.muted });
122
+ } else if (request.service === 'set_speaker_volume_raw') {
123
+ const data = braviatvRecord(request.data, ['volume_raw']);
124
+ control = validateBraviatvControl({ feature: 'speaker_volume_raw', value: data.volume_raw });
125
+ } else throw new Error('BRAVIA supports separate absolute power, device mute and integer speaker volume services only.');
126
+ const target = braviatvRecord(request.target, ['deviceId', 'entityId']);
127
+ const deviceId = BraviatvMapper.deviceId(this.snapshot.homeId, this.snapshot.identity.macAddress);
128
+ const entityId = BraviatvMapper.entityId(this.snapshot.homeId, this.snapshot.identity.macAddress, control.feature);
129
+ if ((!target.deviceId && !target.entityId) || target.deviceId !== undefined && target.deviceId !== deviceId || target.entityId !== undefined && target.entityId !== entityId) {
130
+ throw new Error('BRAVIA service target is outside the selected home, display and control.');
131
+ }
132
+ return this.control(control);
72
133
  }
73
-
74
- private async callRemoteService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
75
- if (requestArg.service !== 'send_command') {
76
- return { success: false, error: `Unsupported Sony Bravia TV remote service: ${requestArg.service}` };
77
- }
78
- const command = requestArg.data?.command;
79
- const commands = typeof command === 'string' ? [command] : Array.isArray(command) ? command.filter((itemArg): itemArg is string => typeof itemArg === 'string' && Boolean(itemArg)) : [];
80
- if (!commands.length) {
81
- return { success: false, error: 'Sony Bravia TV remote.send_command requires data.command.' };
82
- }
83
- const repeatsValue = requestArg.data?.num_repeats ?? requestArg.data?.numRepeats ?? 1;
84
- const repeats = typeof repeatsValue === 'number' && Number.isFinite(repeatsValue) ? repeatsValue : 1;
85
- await this.client.sendCommands(commands, repeats);
86
- return { success: true };
134
+ /** Completed observations only; subscriptions never start a polling loop. */
135
+ public async subscribe(handler: (event: IIntegrationEvent) => void, signal?: AbortSignal): Promise<() => Promise<void>> {
136
+ this.assertOpen();
137
+ if (typeof handler !== 'function' || signal !== undefined && !(signal instanceof AbortSignal)) throw new TypeError('BRAVIA subscription requires a callback and optional AbortSignal.');
138
+ if (signal?.aborted) throw new Error('BRAVIA subscription was cancelled.');
139
+ if (this.#subscriptions.size >= 32) throw new Error('BRAVIA subscription capacity reached.');
140
+ const aborted = () => { subscription.detach(); this.#subscriptions.delete(subscription); };
141
+ const subscription: IBraviatvSubscription = { handler, active: true, failed: false,
142
+ detach: () => { subscription.active = false; signal?.removeEventListener('abort', aborted); },
143
+ stop: async () => { subscription.detach(); this.#subscriptions.delete(subscription);
144
+ if (subscription.failed) throw new Error('BRAVIA subscriber failed.'); } };
145
+ signal?.addEventListener('abort', aborted, { once: true });
146
+ this.#subscriptions.add(subscription);
147
+ if (signal?.aborted) aborted();
148
+ return subscription.stop;
87
149
  }
88
-
89
- private async callBraviatvService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
90
- if (requestArg.service === 'reboot') {
91
- await this.client.reboot();
92
- return { success: true };
93
- }
94
- if (requestArg.service === 'terminate_apps') {
95
- await this.client.terminateApps();
96
- return { success: true };
97
- }
98
- return { success: false, error: `Unsupported Sony Bravia TV service: ${requestArg.service}` };
150
+ public destroy(): Promise<void> {
151
+ if (!this.#closePromise) {
152
+ this.#closePromise = Promise.resolve().then(() => this.lease.close());
153
+ this.#closed = true;
154
+ this.lease.signal.removeEventListener('abort', this.#parentAbort);
155
+ for (const subscription of this.#subscriptions) subscription.detach();
156
+ }
157
+ return this.#closePromise;
99
158
  }
100
-
101
- private async callMediaPlayerService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
102
- if (requestArg.service === 'turn_on') {
103
- await this.client.turnOn();
104
- return { success: true };
105
- }
106
- if (requestArg.service === 'turn_off') {
107
- await this.client.turnOff();
108
- return { success: true };
109
- }
110
- if (requestArg.service === 'play' || requestArg.service === 'media_play') {
111
- await this.client.mediaPlay();
112
- return { success: true };
113
- }
114
- if (requestArg.service === 'pause' || requestArg.service === 'media_pause') {
115
- await this.client.mediaPause();
116
- return { success: true };
117
- }
118
- if (requestArg.service === 'play_pause' || requestArg.service === 'media_play_pause') {
119
- await this.client.sendCommand('Play');
120
- return { success: true };
121
- }
122
- if (requestArg.service === 'stop' || requestArg.service === 'media_stop') {
123
- await this.client.mediaStop();
124
- return { success: true };
125
- }
126
- if (requestArg.service === 'next_track' || requestArg.service === 'media_next_track') {
127
- await this.client.nextTrack();
128
- return { success: true };
129
- }
130
- if (requestArg.service === 'previous_track' || requestArg.service === 'media_previous_track') {
131
- await this.client.previousTrack();
132
- return { success: true };
133
- }
134
- if (requestArg.service === 'volume_set') {
135
- const level = requestArg.data?.volume_level;
136
- if (typeof level !== 'number') {
137
- return { success: false, error: 'Sony Bravia TV volume_set requires data.volume_level.' };
138
- }
139
- await this.client.setVolumeLevel(level);
140
- return { success: true };
141
- }
142
- if (requestArg.service === 'volume_up') {
143
- await this.client.volumeUp();
144
- return { success: true };
145
- }
146
- if (requestArg.service === 'volume_down') {
147
- await this.client.volumeDown();
148
- return { success: true };
149
- }
150
- if (requestArg.service === 'volume_mute' || requestArg.service === 'mute') {
151
- const muted = requestArg.data?.is_volume_muted ?? requestArg.data?.muted;
152
- if (typeof muted !== 'boolean') {
153
- return { success: false, error: 'Sony Bravia TV volume_mute requires data.is_volume_muted.' };
154
- }
155
- await this.client.muteVolume(muted);
156
- return { success: true };
157
- }
158
- if (requestArg.service === 'select_source') {
159
- const source = requestArg.data?.source;
160
- if (typeof source !== 'string' || !source) {
161
- return { success: false, error: 'Sony Bravia TV select_source requires data.source.' };
162
- }
163
- await this.client.selectSource(source);
164
- return { success: true };
159
+ public async closeSubscriptions(): Promise<void> {
160
+ this.#closed = true;
161
+ this.lease.signal.removeEventListener('abort', this.#parentAbort);
162
+ const results = await Promise.allSettled([...this.#subscriptions].map((entry) => entry.stop()));
163
+ const failures = results.filter((entry): entry is PromiseRejectedResult => entry.status === 'rejected');
164
+ if (failures.length) throw new AggregateError(failures.map((entry) => entry.reason), 'BRAVIA subscriber cleanup failed.');
165
+ }
166
+ private async control(control: TBraviatvControl, signal?: AbortSignal): Promise<IServiceCallResult> {
167
+ try {
168
+ const result = await this.client.setControl(control, signal);
169
+ this.publish(result.snapshot);
170
+ return this.result(result);
171
+ } catch (error) {
172
+ const failure = error instanceof plugins.ecobridgeDeviceManager.SonyBraviaProtocolError ? error : undefined;
173
+ return { success: false, error: failure?.message ?? 'BRAVIA selected-display control was not admitted.',
174
+ data: { effectOutcome: failure?.effectOutcome ?? 'not-sent', commandAcknowledged: failure?.commandAcknowledged ?? false, causalityConfirmed: false,
175
+ ...(failure ? { code: failure.code } : {}) } };
165
176
  }
166
- if (requestArg.service === 'play_media') {
167
- const mediaId = requestArg.data?.media_content_id;
168
- const mediaType = requestArg.data?.media_content_type;
169
- if (typeof mediaId !== 'string' || typeof mediaType !== 'string') {
170
- return { success: false, error: 'Sony Bravia TV play_media requires data.media_content_type and data.media_content_id.' };
171
- }
172
- await this.client.playMedia(mediaType, mediaId);
173
- return { success: true };
177
+ }
178
+ private result(result: IBraviatvEffectResult): IServiceCallResult {
179
+ return { success: result.observation === 'matching-reported-state',
180
+ ...(result.observation === 'different-reported-state' ? { error: 'BRAVIA acknowledged the command, but the independent reported state differs.' } : {}),
181
+ data: { commandAcknowledged: result.commandAcknowledged, causalityConfirmed: result.causalityConfirmed,
182
+ observation: result.observation, control: result.control, requested: result.requested,
183
+ devices: BraviatvMapper.toDevices(result.snapshot), entities: BraviatvMapper.toEntities(result.snapshot) } };
184
+ }
185
+ private publish(snapshot: IBraviatvSnapshot): void {
186
+ if (this.#closed) return;
187
+ this.snapshot = snapshot;
188
+ for (const subscription of [...this.#subscriptions]) {
189
+ if (this.#closed) break;
190
+ if (!subscription.active) continue;
191
+ try { subscription.handler({ type: 'state_changed', integrationDomain: this.domain,
192
+ deviceId: BraviatvMapper.deviceId(snapshot.homeId, snapshot.identity.macAddress), data: structuredClone(snapshot), timestamp: Date.now() }); }
193
+ catch { subscription.failed = true; subscription.detach(); }
174
194
  }
175
- return { success: false, error: `Unsupported Sony Bravia TV media_player service: ${requestArg.service}` };
176
195
  }
196
+ private assertOpen(): void { if (this.#closed) throw new Error('BRAVIA runtime is closed.'); }
177
197
  }
@@ -30,8 +30,8 @@ export class BraviatvSsdpMatcher implements IDiscoveryMatcher<IBraviatvSsdpRecor
30
30
  const id = stripUuid(usn || stringValue(recordArg, 'udn', 'UDN')) || stringValue(recordArg, 'cid', 'macAddr');
31
31
  return {
32
32
  matched: true,
33
- confidence: id ? 'certain' : 'high',
34
- reason: 'SSDP record matches Sony Bravia ScalarWebAPI metadata.',
33
+ confidence: 'medium',
34
+ reason: 'Unverified SSDP metadata supplies Sony BRAVIA setup hints only.',
35
35
  normalizedDeviceId: id,
36
36
  candidate: {
37
37
  source: 'ssdp',
@@ -72,8 +72,8 @@ export class BraviatvMdnsMatcher implements IDiscoveryMatcher<IBraviatvMdnsRecor
72
72
  const id = valueForKey(properties, 'cid') || valueForKey(properties, 'id') || valueForKey(properties, 'deviceid') || name;
73
73
  return {
74
74
  matched: true,
75
- confidence: id ? 'certain' : recordArg.host ? 'high' : 'medium',
76
- reason: 'mDNS record matches Sony Bravia metadata.',
75
+ confidence: 'medium',
76
+ reason: 'Unverified mDNS metadata supplies Sony BRAVIA setup hints only.',
77
77
  normalizedDeviceId: id,
78
78
  candidate: {
79
79
  source: 'mdns',
@@ -88,7 +88,6 @@ export class BraviatvMdnsMatcher implements IDiscoveryMatcher<IBraviatvMdnsRecor
88
88
  metadata: {
89
89
  mdnsType: recordArg.type,
90
90
  mdnsName: recordArg.name,
91
- txt: properties,
92
91
  },
93
92
  },
94
93
  };
@@ -116,17 +115,14 @@ export class BraviatvManualMatcher implements IDiscoveryMatcher<IBraviatvManualE
116
115
  integrationDomain: 'braviatv',
117
116
  id,
118
117
  host: inputArg.host,
119
- port: inputArg.port || (inputArg.useSsl ? 443 : 80),
118
+ port: inputArg.port || 80,
120
119
  name: inputArg.name,
121
120
  manufacturer: inputArg.manufacturer || 'Sony',
122
121
  model: inputArg.model,
123
122
  serialNumber: inputArg.serialNumber,
124
123
  macAddress: inputArg.macAddress,
125
124
  metadata: {
126
- ...(inputArg.metadata || {}),
127
125
  cid: inputArg.cid,
128
- psk: inputArg.psk,
129
- useSsl: inputArg.useSsl,
130
126
  },
131
127
  },
132
128
  };
@@ -146,7 +142,12 @@ export class BraviatvCandidateValidator implements IDiscoveryValidator {
146
142
  matched,
147
143
  confidence: matched && candidateArg.host ? 'high' : matched ? 'medium' : 'low',
148
144
  reason: matched ? 'Candidate has Sony Bravia metadata.' : 'Candidate is not Sony Bravia TV.',
149
- candidate: matched ? candidateArg : undefined,
145
+ candidate: matched ? {
146
+ source: candidateArg.source, integrationDomain: 'braviatv', id: candidateArg.id,
147
+ host: candidateArg.host, port: candidateArg.port, name: candidateArg.name,
148
+ manufacturer: candidateArg.manufacturer, model: candidateArg.model,
149
+ macAddress: candidateArg.macAddress, serialNumber: candidateArg.serialNumber,
150
+ } : undefined,
150
151
  normalizedDeviceId: candidateArg.id || candidateArg.macAddress || candidateArg.serialNumber || candidateArg.host,
151
152
  };
152
153
  }