@smarthome.exchange/integrations 1.0.0 → 2.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 (294) hide show
  1. package/changelog.md +49 -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 +79 -0
  8. package/dist_ts/core/classes.nativeintegrationowner.js +269 -0
  9. package/dist_ts/core/index.d.ts +2 -0
  10. package/dist_ts/core/index.js +3 -1
  11. package/dist_ts/core/types.d.ts +14 -0
  12. package/dist_ts/integrations/braviatv/braviatv.classes.client.d.ts +23 -72
  13. package/dist_ts/integrations/braviatv/braviatv.classes.client.js +265 -625
  14. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.d.ts +7 -7
  15. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.js +51 -68
  16. package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +8 -11
  17. package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +186 -135
  18. package/dist_ts/integrations/braviatv/braviatv.discovery.js +12 -11
  19. package/dist_ts/integrations/braviatv/braviatv.mapper.d.ts +6 -14
  20. package/dist_ts/integrations/braviatv/braviatv.mapper.js +37 -131
  21. package/dist_ts/integrations/braviatv/braviatv.types.d.ts +55 -133
  22. package/dist_ts/integrations/braviatv/braviatv.validation.d.ts +7 -0
  23. package/dist_ts/integrations/braviatv/braviatv.validation.js +72 -0
  24. package/dist_ts/integrations/broadlink/broadlink.actions.d.ts +2 -0
  25. package/dist_ts/integrations/broadlink/broadlink.actions.js +36 -0
  26. package/dist_ts/integrations/broadlink/broadlink.classes.client.d.ts +21 -19
  27. package/dist_ts/integrations/broadlink/broadlink.classes.client.js +185 -124
  28. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.d.ts +5 -4
  29. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.js +64 -83
  30. package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +16 -19
  31. package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +114 -59
  32. package/dist_ts/integrations/broadlink/broadlink.mapper.d.ts +3 -2
  33. package/dist_ts/integrations/broadlink/broadlink.mapper.js +2 -1
  34. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.d.ts +10 -0
  35. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.js +41 -0
  36. package/dist_ts/integrations/broadlink/broadlink.types.d.ts +43 -7
  37. package/dist_ts/integrations/broadlink/broadlink.validation.d.ts +7 -0
  38. package/dist_ts/integrations/broadlink/broadlink.validation.js +63 -0
  39. package/dist_ts/integrations/daikin/daikin.classes.client.d.ts +10 -52
  40. package/dist_ts/integrations/daikin/daikin.classes.client.js +55 -614
  41. package/dist_ts/integrations/daikin/daikin.classes.configflow.d.ts +8 -12
  42. package/dist_ts/integrations/daikin/daikin.classes.configflow.js +77 -138
  43. package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +7 -24
  44. package/dist_ts/integrations/daikin/daikin.classes.integration.js +175 -67
  45. package/dist_ts/integrations/daikin/daikin.discovery.d.ts +11 -24
  46. package/dist_ts/integrations/daikin/daikin.discovery.js +98 -305
  47. package/dist_ts/integrations/daikin/daikin.mapper.d.ts +6 -7
  48. package/dist_ts/integrations/daikin/daikin.mapper.js +95 -155
  49. package/dist_ts/integrations/daikin/daikin.types.d.ts +24 -44
  50. package/dist_ts/integrations/daikin/daikin.types.js +1 -1
  51. package/dist_ts/integrations/daikin/daikin.validation.d.ts +5 -0
  52. package/dist_ts/integrations/daikin/daikin.validation.js +53 -0
  53. package/dist_ts/integrations/denonavr/denonavr.classes.client.d.ts +31 -40
  54. package/dist_ts/integrations/denonavr/denonavr.classes.client.js +149 -404
  55. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.d.ts +7 -2
  56. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.js +44 -36
  57. package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +6 -11
  58. package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +192 -113
  59. package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +10 -18
  60. package/dist_ts/integrations/denonavr/denonavr.discovery.js +71 -193
  61. package/dist_ts/integrations/denonavr/denonavr.mapper.d.ts +5 -13
  62. package/dist_ts/integrations/denonavr/denonavr.mapper.js +35 -159
  63. package/dist_ts/integrations/denonavr/denonavr.types.d.ts +55 -90
  64. package/dist_ts/integrations/denonavr/denonavr.validation.d.ts +10 -0
  65. package/dist_ts/integrations/denonavr/denonavr.validation.js +86 -0
  66. package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +11 -45
  67. package/dist_ts/integrations/kodi/kodi.classes.client.js +84 -310
  68. package/dist_ts/integrations/kodi/kodi.classes.configflow.d.ts +9 -8
  69. package/dist_ts/integrations/kodi/kodi.classes.configflow.js +53 -48
  70. package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +11 -11
  71. package/dist_ts/integrations/kodi/kodi.classes.integration.js +114 -171
  72. package/dist_ts/integrations/kodi/kodi.discovery.js +53 -29
  73. package/dist_ts/integrations/kodi/kodi.mapper.d.ts +7 -2
  74. package/dist_ts/integrations/kodi/kodi.mapper.js +48 -10
  75. package/dist_ts/integrations/kodi/kodi.types.d.ts +32 -28
  76. package/dist_ts/integrations/kodi/kodi.validation.d.ts +9 -0
  77. package/dist_ts/integrations/kodi/kodi.validation.js +62 -0
  78. package/dist_ts/integrations/modbus/modbus.classes.client.d.ts +15 -61
  79. package/dist_ts/integrations/modbus/modbus.classes.client.js +117 -776
  80. package/dist_ts/integrations/modbus/modbus.classes.configflow.d.ts +9 -5
  81. package/dist_ts/integrations/modbus/modbus.classes.configflow.js +70 -38
  82. package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +6 -17
  83. package/dist_ts/integrations/modbus/modbus.classes.integration.js +133 -57
  84. package/dist_ts/integrations/modbus/modbus.discovery.d.ts +5 -8
  85. package/dist_ts/integrations/modbus/modbus.discovery.js +38 -93
  86. package/dist_ts/integrations/modbus/modbus.mapper.d.ts +8 -32
  87. package/dist_ts/integrations/modbus/modbus.mapper.js +71 -431
  88. package/dist_ts/integrations/modbus/modbus.types.d.ts +82 -332
  89. package/dist_ts/integrations/modbus/modbus.validation.d.ts +10 -0
  90. package/dist_ts/integrations/modbus/modbus.validation.js +128 -0
  91. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.d.ts +12 -34
  92. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +143 -231
  93. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.d.ts +6 -1
  94. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.js +105 -18
  95. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +8 -8
  96. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +141 -155
  97. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.d.ts +9 -0
  98. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.js +35 -0
  99. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.d.ts +6 -18
  100. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.js +45 -220
  101. package/dist_ts/integrations/nanoleaf/nanoleaf.types.d.ts +33 -147
  102. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.d.ts +6 -0
  103. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.js +82 -0
  104. package/dist_ts/integrations/onkyo/onkyo.classes.client.d.ts +15 -20
  105. package/dist_ts/integrations/onkyo/onkyo.classes.client.js +161 -404
  106. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.d.ts +9 -4
  107. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.js +51 -6
  108. package/dist_ts/integrations/onkyo/onkyo.classes.integration.d.ts +22 -6
  109. package/dist_ts/integrations/onkyo/onkyo.classes.integration.js +144 -11
  110. package/dist_ts/integrations/onkyo/onkyo.discovery.d.ts +6 -1
  111. package/dist_ts/integrations/onkyo/onkyo.discovery.js +40 -4
  112. package/dist_ts/integrations/onkyo/onkyo.mapper.d.ts +7 -8
  113. package/dist_ts/integrations/onkyo/onkyo.mapper.js +45 -12
  114. package/dist_ts/integrations/onkyo/onkyo.types.d.ts +58 -8
  115. package/dist_ts/integrations/onkyo/onkyo.types.js +13 -102
  116. package/dist_ts/integrations/onkyo/onkyo.validation.d.ts +16 -0
  117. package/dist_ts/integrations/onkyo/onkyo.validation.js +77 -0
  118. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.d.ts +25 -25
  119. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +116 -360
  120. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.d.ts +11 -3
  121. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.js +76 -6
  122. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.d.ts +26 -4
  123. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.js +142 -9
  124. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.d.ts +2 -1
  125. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.js +31 -4
  126. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.d.ts +9 -9
  127. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.js +31 -149
  128. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.d.ts +51 -11
  129. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.js +22 -87
  130. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.d.ts +6 -0
  131. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.js +56 -0
  132. package/dist_ts/integrations/pioneer/pioneer.classes.client.d.ts +31 -16
  133. package/dist_ts/integrations/pioneer/pioneer.classes.client.js +167 -409
  134. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.d.ts +10 -3
  135. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.js +66 -6
  136. package/dist_ts/integrations/pioneer/pioneer.classes.integration.d.ts +13 -5
  137. package/dist_ts/integrations/pioneer/pioneer.classes.integration.js +239 -11
  138. package/dist_ts/integrations/pioneer/pioneer.discovery.d.ts +14 -1
  139. package/dist_ts/integrations/pioneer/pioneer.discovery.js +51 -4
  140. package/dist_ts/integrations/pioneer/pioneer.mapper.d.ts +14 -8
  141. package/dist_ts/integrations/pioneer/pioneer.mapper.js +54 -12
  142. package/dist_ts/integrations/pioneer/pioneer.types.d.ts +79 -12
  143. package/dist_ts/integrations/pioneer/pioneer.types.js +12 -76
  144. package/dist_ts/integrations/pioneer/pioneer.validation.d.ts +10 -0
  145. package/dist_ts/integrations/pioneer/pioneer.validation.js +85 -0
  146. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.d.ts +13 -36
  147. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +179 -502
  148. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.d.ts +6 -1
  149. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.js +50 -40
  150. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +14 -15
  151. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +108 -128
  152. package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -20
  153. package/dist_ts/integrations/soundtouch/soundtouch.discovery.js +23 -113
  154. package/dist_ts/integrations/soundtouch/soundtouch.mapper.d.ts +3 -12
  155. package/dist_ts/integrations/soundtouch/soundtouch.mapper.js +35 -189
  156. package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +57 -142
  157. package/dist_ts/integrations/soundtouch/soundtouch.types.js +18 -3
  158. package/dist_ts/integrations/soundtouch/soundtouch.validation.d.ts +22 -0
  159. package/dist_ts/integrations/soundtouch/soundtouch.validation.js +65 -0
  160. package/dist_ts/integrations/wiz/index.d.ts +1 -0
  161. package/dist_ts/integrations/wiz/index.js +2 -1
  162. package/dist_ts/integrations/wiz/wiz.classes.client.d.ts +14 -28
  163. package/dist_ts/integrations/wiz/wiz.classes.client.js +93 -229
  164. package/dist_ts/integrations/wiz/wiz.classes.configflow.d.ts +6 -4
  165. package/dist_ts/integrations/wiz/wiz.classes.configflow.js +38 -67
  166. package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +10 -21
  167. package/dist_ts/integrations/wiz/wiz.classes.integration.js +204 -44
  168. package/dist_ts/integrations/wiz/wiz.discovery.d.ts +10 -31
  169. package/dist_ts/integrations/wiz/wiz.discovery.js +48 -249
  170. package/dist_ts/integrations/wiz/wiz.mapper.d.ts +7 -51
  171. package/dist_ts/integrations/wiz/wiz.mapper.js +82 -668
  172. package/dist_ts/integrations/wiz/wiz.types.d.ts +34 -208
  173. package/dist_ts/integrations/wiz/wiz.validation.d.ts +8 -0
  174. package/dist_ts/integrations/wiz/wiz.validation.js +72 -0
  175. package/dist_ts/integrations/yamaha/index.d.ts +1 -0
  176. package/dist_ts/integrations/yamaha/index.js +2 -1
  177. package/dist_ts/integrations/yamaha/yamaha.classes.client.d.ts +30 -4
  178. package/dist_ts/integrations/yamaha/yamaha.classes.client.js +162 -6
  179. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.d.ts +10 -3
  180. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.js +106 -6
  181. package/dist_ts/integrations/yamaha/yamaha.classes.integration.d.ts +22 -4
  182. package/dist_ts/integrations/yamaha/yamaha.classes.integration.js +243 -8
  183. package/dist_ts/integrations/yamaha/yamaha.discovery.d.ts +13 -1
  184. package/dist_ts/integrations/yamaha/yamaha.discovery.js +57 -4
  185. package/dist_ts/integrations/yamaha/yamaha.mapper.d.ts +16 -8
  186. package/dist_ts/integrations/yamaha/yamaha.mapper.js +58 -12
  187. package/dist_ts/integrations/yamaha/yamaha.types.d.ts +73 -6
  188. package/dist_ts/integrations/yamaha/yamaha.types.js +8 -94
  189. package/dist_ts/integrations/yamaha/yamaha.validation.d.ts +12 -0
  190. package/dist_ts/integrations/yamaha/yamaha.validation.js +89 -0
  191. package/package.json +3 -3
  192. package/readme.md +514 -2
  193. package/ts/00_commitinfo_data.ts +1 -1
  194. package/ts/core/classes.configstore.ts +84 -27
  195. package/ts/core/classes.nativehomeadmission.ts +96 -0
  196. package/ts/core/classes.nativeintegrationowner.ts +297 -0
  197. package/ts/core/index.ts +2 -0
  198. package/ts/core/types.ts +16 -0
  199. package/ts/integrations/braviatv/braviatv.classes.client.ts +245 -709
  200. package/ts/integrations/braviatv/braviatv.classes.configflow.ts +47 -76
  201. package/ts/integrations/braviatv/braviatv.classes.integration.ts +167 -147
  202. package/ts/integrations/braviatv/braviatv.discovery.ts +11 -10
  203. package/ts/integrations/braviatv/braviatv.mapper.ts +39 -142
  204. package/ts/integrations/braviatv/braviatv.types.ts +53 -173
  205. package/ts/integrations/braviatv/braviatv.validation.ts +68 -0
  206. package/ts/integrations/broadlink/broadlink.actions.ts +31 -0
  207. package/ts/integrations/broadlink/broadlink.classes.client.ts +170 -144
  208. package/ts/integrations/broadlink/broadlink.classes.configflow.ts +59 -89
  209. package/ts/integrations/broadlink/broadlink.classes.integration.ts +110 -64
  210. package/ts/integrations/broadlink/broadlink.mapper.ts +5 -4
  211. package/ts/integrations/broadlink/broadlink.selected.mapper.ts +46 -0
  212. package/ts/integrations/broadlink/broadlink.types.ts +48 -8
  213. package/ts/integrations/broadlink/broadlink.validation.ts +66 -0
  214. package/ts/integrations/daikin/daikin.classes.client.ts +52 -661
  215. package/ts/integrations/daikin/daikin.classes.configflow.ts +72 -152
  216. package/ts/integrations/daikin/daikin.classes.integration.ts +166 -71
  217. package/ts/integrations/daikin/daikin.discovery.ts +94 -346
  218. package/ts/integrations/daikin/daikin.mapper.ts +83 -166
  219. package/ts/integrations/daikin/daikin.types.ts +27 -48
  220. package/ts/integrations/daikin/daikin.validation.ts +51 -0
  221. package/ts/integrations/daikin/readme.md +83 -0
  222. package/ts/integrations/denonavr/denonavr.classes.client.ts +132 -421
  223. package/ts/integrations/denonavr/denonavr.classes.configflow.ts +44 -37
  224. package/ts/integrations/denonavr/denonavr.classes.integration.ts +171 -117
  225. package/ts/integrations/denonavr/denonavr.discovery.ts +67 -220
  226. package/ts/integrations/denonavr/denonavr.mapper.ts +36 -182
  227. package/ts/integrations/denonavr/denonavr.types.ts +48 -111
  228. package/ts/integrations/denonavr/denonavr.validation.ts +87 -0
  229. package/ts/integrations/kodi/kodi.classes.client.ts +72 -352
  230. package/ts/integrations/kodi/kodi.classes.configflow.ts +52 -55
  231. package/ts/integrations/kodi/kodi.classes.integration.ts +97 -178
  232. package/ts/integrations/kodi/kodi.discovery.ts +49 -28
  233. package/ts/integrations/kodi/kodi.mapper.ts +52 -10
  234. package/ts/integrations/kodi/kodi.types.ts +33 -58
  235. package/ts/integrations/kodi/kodi.validation.ts +60 -0
  236. package/ts/integrations/modbus/modbus.classes.client.ts +100 -842
  237. package/ts/integrations/modbus/modbus.classes.configflow.ts +70 -41
  238. package/ts/integrations/modbus/modbus.classes.integration.ts +115 -60
  239. package/ts/integrations/modbus/modbus.discovery.ts +38 -106
  240. package/ts/integrations/modbus/modbus.mapper.ts +64 -467
  241. package/ts/integrations/modbus/modbus.types.ts +64 -381
  242. package/ts/integrations/modbus/modbus.validation.ts +119 -0
  243. package/ts/integrations/nanoleaf/nanoleaf.classes.client.ts +115 -249
  244. package/ts/integrations/nanoleaf/nanoleaf.classes.configflow.ts +90 -19
  245. package/ts/integrations/nanoleaf/nanoleaf.classes.integration.ts +130 -181
  246. package/ts/integrations/nanoleaf/nanoleaf.credentials.ts +39 -0
  247. package/ts/integrations/nanoleaf/nanoleaf.mapper.ts +47 -260
  248. package/ts/integrations/nanoleaf/nanoleaf.types.ts +29 -147
  249. package/ts/integrations/nanoleaf/nanoleaf.validation.ts +77 -0
  250. package/ts/integrations/onkyo/onkyo.classes.client.ts +148 -457
  251. package/ts/integrations/onkyo/onkyo.classes.configflow.ts +52 -6
  252. package/ts/integrations/onkyo/onkyo.classes.integration.ts +121 -12
  253. package/ts/integrations/onkyo/onkyo.discovery.ts +41 -3
  254. package/ts/integrations/onkyo/onkyo.mapper.ts +46 -19
  255. package/ts/integrations/onkyo/onkyo.types.ts +55 -110
  256. package/ts/integrations/onkyo/onkyo.validation.ts +85 -0
  257. package/ts/integrations/onkyo/readme.md +126 -0
  258. package/ts/integrations/panasonic_viera/panasonic_viera.classes.client.ts +101 -398
  259. package/ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.ts +69 -5
  260. package/ts/integrations/panasonic_viera/panasonic_viera.classes.integration.ts +141 -9
  261. package/ts/integrations/panasonic_viera/panasonic_viera.discovery.ts +32 -3
  262. package/ts/integrations/panasonic_viera/panasonic_viera.mapper.ts +34 -161
  263. package/ts/integrations/panasonic_viera/panasonic_viera.types.ts +52 -96
  264. package/ts/integrations/panasonic_viera/panasonic_viera.validation.ts +56 -0
  265. package/ts/integrations/pioneer/pioneer.classes.client.ts +132 -428
  266. package/ts/integrations/pioneer/pioneer.classes.configflow.ts +67 -5
  267. package/ts/integrations/pioneer/pioneer.classes.integration.ts +225 -11
  268. package/ts/integrations/pioneer/pioneer.discovery.ts +45 -3
  269. package/ts/integrations/pioneer/pioneer.mapper.ts +57 -13
  270. package/ts/integrations/pioneer/pioneer.types.ts +87 -85
  271. package/ts/integrations/pioneer/pioneer.validation.ts +84 -0
  272. package/ts/integrations/soundtouch/soundtouch.classes.client.ts +152 -571
  273. package/ts/integrations/soundtouch/soundtouch.classes.configflow.ts +47 -42
  274. package/ts/integrations/soundtouch/soundtouch.classes.integration.ts +95 -150
  275. package/ts/integrations/soundtouch/soundtouch.discovery.ts +21 -133
  276. package/ts/integrations/soundtouch/soundtouch.mapper.ts +36 -207
  277. package/ts/integrations/soundtouch/soundtouch.types.ts +50 -195
  278. package/ts/integrations/soundtouch/soundtouch.validation.ts +60 -0
  279. package/ts/integrations/wiz/index.ts +1 -0
  280. package/ts/integrations/wiz/wiz.classes.client.ts +84 -254
  281. package/ts/integrations/wiz/wiz.classes.configflow.ts +39 -70
  282. package/ts/integrations/wiz/wiz.classes.integration.ts +189 -45
  283. package/ts/integrations/wiz/wiz.discovery.ts +48 -291
  284. package/ts/integrations/wiz/wiz.mapper.ts +81 -754
  285. package/ts/integrations/wiz/wiz.types.ts +24 -224
  286. package/ts/integrations/wiz/wiz.validation.ts +73 -0
  287. package/ts/integrations/yamaha/index.ts +1 -0
  288. package/ts/integrations/yamaha/yamaha.classes.client.ts +150 -6
  289. package/ts/integrations/yamaha/yamaha.classes.configflow.ts +100 -5
  290. package/ts/integrations/yamaha/yamaha.classes.integration.ts +236 -8
  291. package/ts/integrations/yamaha/yamaha.discovery.ts +52 -3
  292. package/ts/integrations/yamaha/yamaha.mapper.ts +65 -13
  293. package/ts/integrations/yamaha/yamaha.types.ts +77 -97
  294. package/ts/integrations/yamaha/yamaha.validation.ts +86 -0
@@ -1,8 +1,8 @@
1
1
  import * as plugins from '../../plugins.js';
2
- import type { IIntegrationEntity, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
2
+ import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IServiceCallRequest, TEntityPlatform } from '../../core/types.js';
3
3
  import type {
4
- IDaikinCommandRequest,
5
4
  IDaikinConfig,
5
+ IDaikinNativeConfig,
6
6
  IDaikinDeviceSnapshotInfo,
7
7
  IDaikinEnergySnapshot,
8
8
  IDaikinRawData,
@@ -10,11 +10,11 @@ import type {
10
10
  IDaikinValueMap,
11
11
  IDaikinZoneSnapshot,
12
12
  TDaikinApiVariant,
13
- TDaikinHvacAction,
14
13
  TDaikinHvacMode,
15
14
  TDaikinPresetMode,
16
15
  TDaikinSnapshotSource,
17
16
  } from './daikin.types.js';
17
+ import { daikinKeys, daikinObject } from './daikin.validation.js';
18
18
  import { daikinDefaultHttpPort, daikinDisplayName, daikinDomain, daikinSkyFiPort } from './daikin.types.js';
19
19
 
20
20
  interface IDaikinSnapshotOptions {
@@ -201,6 +201,61 @@ const sensorDefinitions: Array<{ key: string; name: string; unit?: string; devic
201
201
  ];
202
202
 
203
203
  export class DaikinMapper {
204
+ /** Maps only fields supplied by a fresh public-protocol observation. */
205
+ public static fromState(configArg: Readonly<IDaikinNativeConfig>, stateArg: plugins.ecobridgeDeviceManager.IDaikinState): IDaikinSnapshot {
206
+ return {
207
+ device: { id: stateArg.mac, homeId: configArg.homeId, name: configArg.name ?? `Daikin ${stateArg.mac}`,
208
+ manufacturer: 'Daikin', model: stateArg.model, firmware: stateArg.firmwareVersion,
209
+ host: configArg.host, port: configArg.port ?? 80, ssl: false, macAddress: this.normalizeMac(stateArg.mac), apiVariant: 'brp069' },
210
+ climate: { power: stateArg.power, hvacMode: stateArg.power ? stateArg.mode === 'fan' ? 'fan_only' : stateArg.mode : 'off',
211
+ hvacAction: stateArg.power ? 'unknown' : 'off', rawDaikinMode: stateArg.modeCode, rawPower: stateArg.power ? '1' : '0',
212
+ targetTemperature: stateArg.targetTemperatureCelsius,
213
+ targetHumidity: /^\d+$/.test(stateArg.targetHumidity) ? Number(stateArg.targetHumidity) : undefined,
214
+ fanMode: stateArg.fanRate, swingMode: stateArg.fanDirection, presetMode: 'none',
215
+ fanModes: [], swingModes: [], presetModes: [], temperatureUnit: 'C', targetTemperatureStep: 1 },
216
+ energy: {}, zones: [], capabilities: { localControl: stateArg.capabilities.power,
217
+ fanRate: stateArg.fanRate !== undefined, swingMode: stateArg.fanDirection !== undefined,
218
+ awayMode: false, advancedModes: false, streamer: false, outsideTemperature: false, humidity: false,
219
+ compressorFrequency: false, energyConsumption: false, zones: false, zoneTemperatureControl: false },
220
+ online: true, updatedAt: stateArg.observedAt, source: 'http', nativeState: stateArg,
221
+ };
222
+ }
223
+
224
+ public static controlForService(snapshotArg: IDaikinSnapshot, requestArg: IServiceCallRequest): plugins.ecobridgeDeviceManager.IDaikinControl | 'snapshot' {
225
+ const request = daikinObject(requestArg, 'Daikin service request');
226
+ daikinKeys(request, ['domain', 'service', 'target', 'data']);
227
+ const target = daikinObject(request.target, 'Daikin service target');
228
+ daikinKeys(target, ['entityId', 'deviceId']);
229
+ const data = request.data === undefined ? {} : daikinObject(request.data, 'Daikin service data');
230
+ const entities = this.toEntities(snapshotArg);
231
+ const selected = target.entityId === undefined ? undefined : entities.find((entityArg) => entityArg.id === target.entityId);
232
+ if ((!selected && target.entityId !== undefined) || (target.deviceId !== undefined && target.deviceId !== this.deviceId(snapshotArg))
233
+ || (target.entityId === undefined && target.deviceId === undefined)) throw new TypeError('Daikin service requires an exact owned entity or device target.');
234
+ if (request.domain === 'daikin' && request.service === 'refresh') { daikinKeys(data, []); return 'snapshot'; }
235
+ if (request.domain !== 'climate' && request.domain !== 'switch') throw new TypeError('Unsupported Daikin service domain.');
236
+ if (selected && (selected.platform !== request.domain || !['climate', 'power'].includes(String(selected.attributes?.key)))) throw new TypeError('Daikin service does not match the selected entity.');
237
+ if (request.service === 'turn_on' || request.service === 'turn_off') { daikinKeys(data, []); return { power: request.service === 'turn_on' }; }
238
+ if (request.domain === 'climate' && request.service === 'set_temperature') {
239
+ daikinKeys(data, ['temperature']);
240
+ if (typeof data.temperature !== 'number' || !Number.isSafeInteger(data.temperature)) throw new TypeError('Daikin target must be an explicit integer Celsius number.');
241
+ return { targetTemperatureCelsius: data.temperature };
242
+ }
243
+ throw new TypeError('Unsupported Daikin service.');
244
+ }
245
+
246
+ public static controlForFeature(snapshotArg: IDaikinSnapshot, requestArg: IDeviceFeatureWriteRequest): plugins.ecobridgeDeviceManager.IDaikinControl {
247
+ const request = daikinObject(requestArg, 'Daikin feature request');
248
+ daikinKeys(request, ['device', 'feature', 'value']);
249
+ const device = daikinObject(request.device, 'Daikin device target');
250
+ const feature = daikinObject(request.feature, 'Daikin feature target');
251
+ daikinKeys(feature, ['id', 'capability', 'name', 'readable', 'writable', 'unit']);
252
+ if (device.id !== this.deviceId(snapshotArg) || device.integrationDomain !== daikinDomain) throw new TypeError('Daikin feature requires an exact owned device.');
253
+ if (feature.id === 'power' && feature.capability === 'switch' && typeof request.value === 'boolean') return { power: request.value };
254
+ if (feature.id === 'target_temperature' && feature.capability === 'climate' && feature.unit === 'C'
255
+ && typeof request.value === 'number' && Number.isSafeInteger(request.value)) return { targetTemperatureCelsius: request.value };
256
+ throw new TypeError('Unsupported Daikin feature or nonexplicit value.');
257
+ }
258
+
204
259
  public static toSnapshot(optionsArg: IDaikinSnapshotOptions): IDaikinSnapshot {
205
260
  if (optionsArg.config.snapshot && !optionsArg.rawData) {
206
261
  return this.normalizeSnapshot(this.clone(optionsArg.config.snapshot), optionsArg.config, optionsArg.source || 'snapshot');
@@ -214,7 +269,7 @@ export class DaikinMapper {
214
269
  const climate = this.climate(values, variant);
215
270
  const energy = this.energy(values);
216
271
  const capabilities = {
217
- localControl: Boolean(optionsArg.config.host || optionsArg.config.url || optionsArg.config.commandExecutor || optionsArg.config.client?.execute),
272
+ localControl: false,
218
273
  fanRate: values.f_rate !== undefined,
219
274
  swingMode: values.f_dir !== undefined || values.f_dir_ud !== undefined || values.f_dir_lr !== undefined,
220
275
  awayMode: values.en_hol !== undefined,
@@ -245,11 +300,13 @@ export class DaikinMapper {
245
300
  public static toDevices(snapshotArg: IDaikinSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
246
301
  const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
247
302
  const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
248
- { id: 'power', capability: 'switch', name: 'Power', readable: true, writable: snapshotArg.capabilities.localControl },
249
- { id: 'hvac_mode', capability: 'climate', name: 'HVAC mode', readable: true, writable: snapshotArg.capabilities.localControl },
250
- { id: 'target_temperature', capability: 'climate', name: 'Target temperature', readable: true, writable: snapshotArg.capabilities.localControl, unit: 'C' },
251
- { id: 'inside_temperature', capability: 'sensor', name: 'Inside temperature', readable: true, writable: false, unit: 'C' },
303
+ { id: 'power', capability: 'switch', name: 'Power', readable: true, writable: snapshotArg.nativeState?.capabilities.power === true },
304
+ { id: 'hvac_mode', capability: 'climate', name: 'HVAC mode', readable: true, writable: false },
305
+ { id: 'target_temperature', capability: 'climate', name: 'Target temperature', readable: true, writable: snapshotArg.nativeState?.capabilities.targetTemperature === true, unit: 'C' },
252
306
  ];
307
+ if (snapshotArg.climate.insideTemperature !== undefined) {
308
+ features.push({ id: 'inside_temperature', capability: 'sensor', name: 'Inside temperature', readable: true, writable: false, unit: 'C' });
309
+ }
253
310
  if (snapshotArg.capabilities.outsideTemperature) {
254
311
  features.push({ id: 'outside_temperature', capability: 'sensor', name: 'Outside temperature', readable: true, writable: false, unit: 'C' });
255
312
  }
@@ -257,24 +314,24 @@ export class DaikinMapper {
257
314
  features.push({ id: 'humidity', capability: 'sensor', name: 'Humidity', readable: true, writable: false, unit: '%' });
258
315
  }
259
316
  if (snapshotArg.capabilities.fanRate) {
260
- features.push({ id: 'fan_mode', capability: 'fan', name: 'Fan mode', readable: true, writable: snapshotArg.capabilities.localControl });
317
+ features.push({ id: 'fan_mode', capability: 'fan', name: 'Fan mode', readable: true, writable: false });
261
318
  }
262
319
  if (snapshotArg.capabilities.swingMode) {
263
- features.push({ id: 'swing_mode', capability: 'fan', name: 'Swing mode', readable: true, writable: snapshotArg.capabilities.localControl });
320
+ features.push({ id: 'swing_mode', capability: 'fan', name: 'Swing mode', readable: true, writable: false });
264
321
  }
265
322
  if (snapshotArg.capabilities.energyConsumption) {
266
323
  features.push({ id: 'energy_today', capability: 'sensor', name: 'Energy today', readable: true, writable: false, unit: 'kWh' });
267
324
  }
268
325
  for (const zone of snapshotArg.zones) {
269
- features.push({ id: `zone_${zone.id}`, capability: 'switch', name: `${zone.name} zone`, readable: true, writable: snapshotArg.capabilities.localControl });
326
+ features.push({ id: `zone_${zone.id}`, capability: 'switch', name: `${zone.name} zone`, readable: true, writable: false });
270
327
  }
271
328
 
272
329
  const state: plugins.shxInterfaces.data.IDeviceState[] = [
273
330
  { featureId: 'power', value: snapshotArg.climate.power, updatedAt },
274
331
  { featureId: 'hvac_mode', value: snapshotArg.climate.hvacMode, updatedAt },
275
332
  { featureId: 'target_temperature', value: snapshotArg.climate.targetTemperature ?? null, updatedAt },
276
- { featureId: 'inside_temperature', value: snapshotArg.climate.insideTemperature ?? null, updatedAt },
277
333
  ];
334
+ if (snapshotArg.climate.insideTemperature !== undefined) state.push({ featureId: 'inside_temperature', value: snapshotArg.climate.insideTemperature, updatedAt });
278
335
  if (snapshotArg.capabilities.outsideTemperature) {
279
336
  state.push({ featureId: 'outside_temperature', value: snapshotArg.climate.outsideTemperature ?? null, updatedAt });
280
337
  }
@@ -313,6 +370,7 @@ export class DaikinMapper {
313
370
  apiVariant: snapshotArg.device.apiVariant,
314
371
  source: snapshotArg.source,
315
372
  error: snapshotArg.error,
373
+ homeId: snapshotArg.device.homeId,
316
374
  }),
317
375
  }];
318
376
  }
@@ -332,7 +390,7 @@ export class DaikinMapper {
332
390
  currentTemperature: snapshotArg.climate.insideTemperature,
333
391
  targetTemperature: snapshotArg.climate.targetTemperature,
334
392
  hvacAction: snapshotArg.climate.hvacAction,
335
- hvacModes: ['off', 'fan_only', 'dry', 'cool', 'heat', 'heat_cool'],
393
+ hvacModes: [],
336
394
  fanMode: snapshotArg.climate.fanMode,
337
395
  fanModes: snapshotArg.climate.fanModes,
338
396
  swingMode: snapshotArg.climate.swingMode,
@@ -410,83 +468,6 @@ export class DaikinMapper {
410
468
  return entities;
411
469
  }
412
470
 
413
- public static commandForService(snapshotArg: IDaikinSnapshot, requestArg: IServiceCallRequest): IDaikinCommandRequest | undefined {
414
- if (requestArg.domain === daikinDomain && requestArg.service === 'refresh') {
415
- return { action: 'refresh', service: requestArg.service, target: requestArg.target, data: requestArg.data };
416
- }
417
-
418
- if (requestArg.domain === 'climate') {
419
- if (requestArg.service === 'turn_on') {
420
- return this.controlCommand(snapshotArg, {}, requestArg);
421
- }
422
- if (requestArg.service === 'turn_off') {
423
- return this.controlCommand(snapshotArg, { mode: 'off' }, requestArg);
424
- }
425
- if (requestArg.service === 'set_temperature') {
426
- const temperature = this.numberValue(requestArg.data?.temperature);
427
- if (temperature === undefined) {
428
- return undefined;
429
- }
430
- const hvacMode = this.stringValue(requestArg.data?.hvac_mode ?? requestArg.data?.hvacMode);
431
- return this.controlCommand(snapshotArg, {
432
- stemp: this.formatTargetTemperature(temperature),
433
- mode: hvacMode ? this.hvacToDaikinMode(hvacMode) : undefined,
434
- }, requestArg);
435
- }
436
- if (requestArg.service === 'set_hvac_mode') {
437
- const hvacMode = this.stringValue(requestArg.data?.hvac_mode ?? requestArg.data?.hvacMode);
438
- return hvacMode ? this.controlCommand(snapshotArg, { mode: this.hvacToDaikinMode(hvacMode) }, requestArg) : undefined;
439
- }
440
- if (requestArg.service === 'set_fan_mode') {
441
- const fanMode = this.stringValue(requestArg.data?.fan_mode ?? requestArg.data?.fanMode);
442
- return fanMode ? this.controlCommand(snapshotArg, { f_rate: fanMode.toLowerCase() }, requestArg) : undefined;
443
- }
444
- if (requestArg.service === 'set_swing_mode') {
445
- const swingMode = this.stringValue(requestArg.data?.swing_mode ?? requestArg.data?.swingMode);
446
- return swingMode ? this.controlCommand(snapshotArg, { f_dir: swingMode.toLowerCase() }, requestArg) : undefined;
447
- }
448
- if (requestArg.service === 'set_preset_mode') {
449
- return this.presetCommand(snapshotArg, this.stringValue(requestArg.data?.preset_mode ?? requestArg.data?.presetMode), requestArg);
450
- }
451
- }
452
-
453
- if (requestArg.domain === 'switch') {
454
- const enabled = requestArg.service === 'turn_on' ? true : requestArg.service === 'turn_off' ? false : undefined;
455
- if (enabled === undefined) {
456
- return undefined;
457
- }
458
- const target = `${requestArg.target.entityId || ''} ${requestArg.target.deviceId || ''}`.toLowerCase();
459
- const zoneMatch = target.match(/(?:zone[_\-. ]?)(\d+)/);
460
- if (zoneMatch) {
461
- return { action: 'set_zone', protocol: snapshotArg.device.apiVariant, zoneId: Number(zoneMatch[1]), zoneKey: 'zone_onoff', zoneValue: enabled ? '1' : '0', service: requestArg.service, target: requestArg.target, data: requestArg.data };
462
- }
463
- if (target.includes('streamer')) {
464
- return { action: 'set_streamer', protocol: snapshotArg.device.apiVariant, enabled, mode: enabled ? 'on' : 'off', service: requestArg.service, target: requestArg.target, data: requestArg.data };
465
- }
466
- return this.controlCommand(snapshotArg, { mode: enabled ? undefined : 'off' }, requestArg);
467
- }
468
-
469
- if (requestArg.domain === daikinDomain && requestArg.service === 'set_zone') {
470
- const zoneId = this.numberValue(requestArg.data?.zone_id ?? requestArg.data?.zoneId);
471
- const value = requestArg.data?.value ?? requestArg.data?.enabled ?? requestArg.data?.on;
472
- if (zoneId === undefined) {
473
- return undefined;
474
- }
475
- return {
476
- action: 'set_zone',
477
- protocol: snapshotArg.device.apiVariant,
478
- zoneId,
479
- zoneKey: this.stringValue(requestArg.data?.key) || 'zone_onoff',
480
- zoneValue: typeof value === 'boolean' ? value ? '1' : '0' : String(value ?? '1'),
481
- service: requestArg.service,
482
- target: requestArg.target,
483
- data: requestArg.data,
484
- };
485
- }
486
-
487
- return undefined;
488
- }
489
-
490
471
  public static deviceId(snapshotArg: IDaikinSnapshot): string {
491
472
  return `${daikinDomain}.ac.${this.uniqueBase(snapshotArg)}`;
492
473
  }
@@ -496,6 +477,7 @@ export class DaikinMapper {
496
477
  }
497
478
 
498
479
  public static uniqueBase(snapshotArg: IDaikinSnapshot): string {
480
+ if (snapshotArg.device.homeId !== undefined) return `${Buffer.from(snapshotArg.device.homeId, 'utf8').toString('base64url')}.${this.compactMac(snapshotArg.device.macAddress)}`;
499
481
  return this.slug(snapshotArg.device.macAddress || snapshotArg.device.id || snapshotArg.device.host || snapshotArg.device.name || daikinDomain);
500
482
  }
501
483
 
@@ -508,7 +490,7 @@ export class DaikinMapper {
508
490
  return undefined;
509
491
  }
510
492
  const compact = valueArg.replace(/[^a-fA-F0-9]/g, '').toLowerCase();
511
- return compact.length === 12 ? compact.match(/.{1,2}/g)?.join(':') : valueArg.toLowerCase();
493
+ return compact.length === 12 && /^[a-fA-F0-9:.-]+$/.test(valueArg) ? compact.match(/.{1,2}/g)?.join(':') : undefined;
512
494
  }
513
495
 
514
496
  public static compactMac(valueArg?: string): string | undefined {
@@ -625,7 +607,8 @@ export class DaikinMapper {
625
607
  device: { ...derived.device, ...snapshotArg.device },
626
608
  climate: { ...derived.climate, ...snapshotArg.climate },
627
609
  energy: { ...derived.energy, ...snapshotArg.energy },
628
- capabilities: { ...derived.capabilities, ...snapshotArg.capabilities },
610
+ capabilities: { ...derived.capabilities, ...snapshotArg.capabilities, localControl: false },
611
+ nativeState: undefined,
629
612
  zones: snapshotArg.zones?.length ? snapshotArg.zones : derived.zones,
630
613
  rawData: Object.keys(rawData).length ? rawData : snapshotArg.rawData,
631
614
  source: snapshotArg.source || sourceArg,
@@ -675,7 +658,7 @@ export class DaikinMapper {
675
658
  return {
676
659
  power: hvacMode !== 'off' && rawPower !== '0',
677
660
  hvacMode,
678
- hvacAction: this.hvacAction(hvacMode, compressorFrequency),
661
+ hvacAction: hvacMode === 'off' ? 'off' : 'unknown',
679
662
  rawDaikinMode: daikinMode,
680
663
  rawPower,
681
664
  targetTemperature: this.numberValue(valuesArg.stemp),
@@ -763,7 +746,7 @@ export class DaikinMapper {
763
746
  private static entity(snapshotArg: IDaikinSnapshot, definitionArg: IDaikinEntityDefinition, deviceIdArg: string, uniqueBaseArg: string): IIntegrationEntity {
764
747
  const platform = definitionArg.platform || 'sensor';
765
748
  return {
766
- id: `${platform}.${this.slug(definitionArg.name)}`,
749
+ id: snapshotArg.device.homeId === undefined ? `${platform}.${this.slug(definitionArg.name)}` : `${platform}.daikin.${uniqueBaseArg}.${definitionArg.key}`,
767
750
  uniqueId: `${daikinDomain}_${uniqueBaseArg}_${this.slug(definitionArg.key)}`,
768
751
  integrationDomain: daikinDomain,
769
752
  deviceId: deviceIdArg,
@@ -778,56 +761,19 @@ export class DaikinMapper {
778
761
  entityCategory: definitionArg.entityCategory,
779
762
  source: snapshotArg.source,
780
763
  error: snapshotArg.error,
764
+ homeId: snapshotArg.device.homeId,
781
765
  ...definitionArg.attributes,
782
766
  }),
783
767
  available: definitionArg.available ?? snapshotArg.online,
784
768
  };
785
769
  }
786
770
 
787
- private static controlCommand(snapshotArg: IDaikinSnapshot, settingsArg: IDaikinCommandRequest['settings'], requestArg: IServiceCallRequest): IDaikinCommandRequest {
788
- return { action: 'set_control', protocol: snapshotArg.device.apiVariant, settings: this.cleanAttributes(settingsArg || {}) as IDaikinCommandRequest['settings'], service: requestArg.service, target: requestArg.target, data: requestArg.data };
789
- }
790
-
791
- private static presetCommand(snapshotArg: IDaikinSnapshot, presetArg: string | undefined, requestArg: IServiceCallRequest): IDaikinCommandRequest | undefined {
792
- if (!presetArg) {
793
- return undefined;
794
- }
795
- const preset = presetArg.toLowerCase();
796
- if (preset === 'away') {
797
- return { action: 'set_holiday', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'on', service: requestArg.service, target: requestArg.target, data: requestArg.data };
798
- }
799
- if (preset === 'boost') {
800
- return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'powerful', service: requestArg.service, target: requestArg.target, data: requestArg.data };
801
- }
802
- if (preset === 'eco') {
803
- return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: true, mode: 'econo', service: requestArg.service, target: requestArg.target, data: requestArg.data };
804
- }
805
- if (preset === 'none') {
806
- if (snapshotArg.climate.presetMode === 'away') {
807
- return { action: 'set_holiday', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'off', service: requestArg.service, target: requestArg.target, data: requestArg.data };
808
- }
809
- if (snapshotArg.climate.presetMode === 'boost') {
810
- return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'powerful', service: requestArg.service, target: requestArg.target, data: requestArg.data };
811
- }
812
- if (snapshotArg.climate.presetMode === 'eco') {
813
- return { action: 'set_advanced_mode', protocol: snapshotArg.device.apiVariant, enabled: false, mode: 'econo', service: requestArg.service, target: requestArg.target, data: requestArg.data };
814
- }
815
- }
816
- return undefined;
817
- }
818
-
819
771
  private static supportedClimateFeatures(snapshotArg: IDaikinSnapshot): string[] {
820
- const features = ['turn_on', 'turn_off', 'target_temperature'];
821
- if (snapshotArg.capabilities.fanRate) {
822
- features.push('fan_mode');
823
- }
824
- if (snapshotArg.capabilities.swingMode) {
825
- features.push('swing_mode');
826
- }
827
- if (snapshotArg.capabilities.awayMode || snapshotArg.capabilities.advancedModes) {
828
- features.push('preset_mode');
829
- }
830
- return features;
772
+ if (!snapshotArg.nativeState) return [];
773
+ return [
774
+ ...(snapshotArg.nativeState.capabilities.power ? ['turn_on', 'turn_off'] : []),
775
+ ...(snapshotArg.nativeState.capabilities.targetTemperature ? ['target_temperature'] : []),
776
+ ];
831
777
  }
832
778
 
833
779
  private static detectVariant(configArg: IDaikinConfig, rawDataArg: Partial<IDaikinRawData>, valuesArg: IDaikinValueMap): TDaikinApiVariant {
@@ -846,9 +792,6 @@ export class DaikinMapper {
846
792
  if (Object.keys(rawDataArg.resources || {}).some((keyArg) => keyArg.startsWith('skyfi/')) || valuesArg.lztemp_c !== undefined || valuesArg.zone_name !== undefined) {
847
793
  return 'airbase';
848
794
  }
849
- if (configArg.apiKey) {
850
- return 'brp072c';
851
- }
852
795
  return 'brp069';
853
796
  }
854
797
 
@@ -869,28 +812,6 @@ export class DaikinMapper {
869
812
  return value || 'unknown';
870
813
  }
871
814
 
872
- private static hvacAction(hvacModeArg: TDaikinHvacMode, compressorFrequencyArg?: number): TDaikinHvacAction {
873
- if (hvacModeArg === 'off') {
874
- return 'off';
875
- }
876
- if (compressorFrequencyArg === 0 && (hvacModeArg === 'cool' || hvacModeArg === 'heat')) {
877
- return 'idle';
878
- }
879
- if (hvacModeArg === 'cool') {
880
- return 'cooling';
881
- }
882
- if (hvacModeArg === 'heat') {
883
- return 'heating';
884
- }
885
- if (hvacModeArg === 'dry') {
886
- return 'drying';
887
- }
888
- if (hvacModeArg === 'fan_only') {
889
- return 'fan';
890
- }
891
- return 'idle';
892
- }
893
-
894
815
  private static presetMode(valuesArg: IDaikinValueMap, variantArg: TDaikinApiVariant): TDaikinPresetMode {
895
816
  if (this.daikinToHuman('en_hol', valuesArg.en_hol, variantArg) === 'on') {
896
817
  return 'away';
@@ -1025,10 +946,6 @@ export class DaikinMapper {
1025
946
  return undefined;
1026
947
  }
1027
948
 
1028
- private static stringValue(valueArg: unknown): string | undefined {
1029
- return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
1030
- }
1031
-
1032
949
  private static title(valueArg: string | undefined): string | undefined {
1033
950
  if (!valueArg) {
1034
951
  return undefined;
@@ -1,3 +1,5 @@
1
+ import type * as plugins from '../../plugins.js';
2
+
1
3
  export const daikinDomain = 'daikin';
2
4
  export const daikinDisplayName = 'Daikin AC';
3
5
  export const daikinDefaultHttpPort = 80;
@@ -10,11 +12,10 @@ export const daikinUdpDiscoveryMessage = 'DAIKIN_UDP/common/basic_info';
10
12
  export const daikinZeroconfType = '_dkapi._tcp.local.';
11
13
 
12
14
  export type TDaikinApiVariant = 'auto' | 'brp069' | 'brp072c' | 'airbase' | 'skyfi' | 'brp084';
13
- export type TDaikinSnapshotSource = 'http' | 'client' | 'manual' | 'snapshot' | 'runtime' | 'executor';
15
+ export type TDaikinSnapshotSource = 'http' | 'manual' | 'snapshot' | 'runtime';
14
16
  export type TDaikinHvacMode = 'off' | 'fan_only' | 'dry' | 'cool' | 'heat' | 'heat_cool' | 'auto' | 'unknown' | string;
15
17
  export type TDaikinHvacAction = 'off' | 'idle' | 'cooling' | 'heating' | 'drying' | 'fan' | 'unknown';
16
18
  export type TDaikinPresetMode = 'none' | 'away' | 'boost' | 'eco' | string;
17
- export type TDaikinCommandAction = 'refresh' | 'set_control' | 'set_holiday' | 'set_advanced_mode' | 'set_streamer' | 'set_zone';
18
19
 
19
20
  export interface IDaikinValueMap {
20
21
  [key: string]: string | undefined;
@@ -52,6 +53,7 @@ export interface IDaikinDeviceSnapshotInfo {
52
53
  ssl?: boolean;
53
54
  macAddress?: string;
54
55
  apiVariant: TDaikinApiVariant;
56
+ homeId?: string;
55
57
  }
56
58
 
57
59
  export interface IDaikinClimateSnapshot {
@@ -121,58 +123,18 @@ export interface IDaikinSnapshot {
121
123
  updatedAt: string;
122
124
  source: TDaikinSnapshotSource;
123
125
  error?: string;
126
+ /** Present only for a current observation from the public selected BRP069 protocol. */
127
+ nativeState?: plugins.ecobridgeDeviceManager.IDaikinState;
124
128
  }
125
129
 
126
- export interface IDaikinControlSettings {
127
- mode?: string;
128
- pow?: string;
129
- stemp?: string | number;
130
- shum?: string | number;
131
- f_rate?: string;
132
- f_dir?: string;
133
- }
134
-
135
- export interface IDaikinCommandRequest {
136
- action: TDaikinCommandAction;
137
- method?: 'GET' | 'POST';
138
- path?: string;
139
- query?: Record<string, string | number | boolean | undefined>;
140
- protocol?: TDaikinApiVariant | 'legacy';
141
- settings?: Partial<IDaikinControlSettings>;
142
- mode?: string;
143
- enabled?: boolean;
144
- zoneId?: number;
145
- zoneKey?: string;
146
- zoneValue?: string;
147
- service?: string;
148
- target?: Record<string, unknown>;
149
- data?: Record<string, unknown>;
150
- }
151
-
152
- export interface IDaikinCommandExecutor {
153
- execute(requestArg: IDaikinCommandRequest): Promise<unknown>;
154
- }
155
-
156
- export interface IDaikinClientLike {
157
- getSnapshot?: () => Promise<IDaikinSnapshot | Partial<IDaikinRawData>>;
158
- getRawData?: () => Promise<Partial<IDaikinRawData>>;
159
- getResource?: (pathArg: string, queryArg?: Record<string, string | number | boolean | undefined>) => Promise<IDaikinValueMap>;
160
- execute?: (requestArg: IDaikinCommandRequest) => Promise<unknown>;
161
- destroy?: () => Promise<void>;
162
- }
163
-
130
+ /** Offline mapper input; this shape cannot authorize native setup or effects. */
164
131
  export interface IDaikinConfig {
165
132
  host?: string;
166
133
  url?: string;
167
134
  port?: number;
168
135
  ssl?: boolean;
169
136
  tls?: boolean;
170
- verifySsl?: boolean;
171
- apiKey?: string;
172
- uuid?: string;
173
- password?: string;
174
137
  apiVariant?: TDaikinApiVariant;
175
- timeoutMs?: number;
176
138
  name?: string;
177
139
  manufacturer?: string;
178
140
  model?: string;
@@ -181,12 +143,10 @@ export interface IDaikinConfig {
181
143
  snapshot?: IDaikinSnapshot;
182
144
  rawData?: Partial<IDaikinRawData>;
183
145
  values?: IDaikinValueMap;
184
- client?: IDaikinClientLike;
185
- commandExecutor?: IDaikinCommandExecutor;
186
146
  online?: boolean;
187
147
  }
188
148
 
189
- export interface IHomeAssistantDaikinConfig extends IDaikinConfig {}
149
+ export interface IHomeAssistantDaikinConfig extends IDaikinNativeConfig {}
190
150
 
191
151
  export interface IDaikinManualEntry extends IDaikinConfig {
192
152
  id?: string;
@@ -239,3 +199,22 @@ export interface IDaikinRefreshResult {
239
199
  error?: string;
240
200
  data?: unknown;
241
201
  }
202
+
203
+ /** Live setup is an explicit selected, unauthenticated BRP069 LAN connection. */
204
+ export interface IDaikinIntegrationOptions {
205
+ readonly homeId?: string;
206
+ readonly capacity?: number;
207
+ }
208
+
209
+ export interface IDaikinNativeConfig {
210
+ homeId: string;
211
+ apiVariant: 'brp069';
212
+ host: string;
213
+ expectedMac: string;
214
+ allowPlaintext: true;
215
+ name?: string;
216
+ port?: number;
217
+ timeoutMs?: number;
218
+ maxResponseBytes?: number;
219
+ maxPendingOperations?: number;
220
+ }
@@ -0,0 +1,51 @@
1
+ import type { IDaikinNativeConfig } from './daikin.types.js';
2
+
3
+ export const daikinObject = (valueArg: unknown, nameArg: string): Record<string, unknown> => {
4
+ if (!valueArg || typeof valueArg !== 'object' || Object.getPrototypeOf(valueArg) !== Object.prototype) {
5
+ throw new TypeError(`${nameArg} must be a plain object.`);
6
+ }
7
+ const result: Record<string, unknown> = {};
8
+ for (const key of Reflect.ownKeys(valueArg)) {
9
+ const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
10
+ if (typeof key !== 'string' || !descriptor || !('value' in descriptor) || !descriptor.enumerable) {
11
+ throw new TypeError(`${nameArg} accepts only enumerable own data fields.`);
12
+ }
13
+ Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
14
+ }
15
+ return result;
16
+ };
17
+
18
+ export const daikinKeys = (valueArg: Record<string, unknown>, allowedArg: readonly string[]): void => {
19
+ if (Object.keys(valueArg).some((keyArg) => !allowedArg.includes(keyArg))) throw new TypeError('Daikin arguments contain unsupported fields.');
20
+ };
21
+
22
+ const text = (valueArg: unknown, nameArg: string, maximumArg: number): string => {
23
+ if (typeof valueArg !== 'string' || valueArg.length === 0 || valueArg.length > maximumArg || /[\p{Cc}\p{Cs}]/u.test(valueArg)) {
24
+ throw new TypeError(`${nameArg} must be a nonempty bounded string without control characters.`);
25
+ }
26
+ return valueArg;
27
+ };
28
+
29
+ const optionalNumber = (valueArg: unknown, nameArg: string): number | undefined => {
30
+ if (valueArg === undefined) return undefined;
31
+ if (typeof valueArg !== 'number') throw new TypeError(`${nameArg} must be a number.`);
32
+ return valueArg;
33
+ };
34
+
35
+ /** Device address, MAC and protocol limits are validated by the public DaikinProtocol. */
36
+ export const normalizeDaikinConfig = (valueArg: IDaikinNativeConfig): Readonly<IDaikinNativeConfig> => {
37
+ const value = daikinObject(valueArg, 'Daikin configuration');
38
+ daikinKeys(value, ['homeId', 'apiVariant', 'host', 'expectedMac', 'allowPlaintext', 'name', 'port', 'timeoutMs', 'maxResponseBytes', 'maxPendingOperations']);
39
+ if (value.apiVariant !== 'brp069') throw new TypeError('Daikin live control requires the explicitly selected brp069 family.');
40
+ if (value.allowPlaintext !== true) throw new TypeError('Daikin BRP069 requires explicit allowPlaintext: true for unauthenticated LAN HTTP.');
41
+ const result: IDaikinNativeConfig = {
42
+ allowPlaintext: true, homeId: text(value.homeId, 'Daikin home ID', 256), apiVariant: 'brp069',
43
+ host: text(value.host, 'Daikin selected IPv4', 64), expectedMac: text(value.expectedMac, 'Daikin expected adapter MAC', 12).toUpperCase(),
44
+ };
45
+ if (value.name !== undefined) result.name = text(value.name, 'Daikin name', 256);
46
+ for (const key of ['port', 'timeoutMs', 'maxResponseBytes', 'maxPendingOperations'] as const) {
47
+ const number = optionalNumber(value[key], `Daikin ${key}`);
48
+ if (number !== undefined) result[key] = number;
49
+ }
50
+ return Object.freeze(result);
51
+ };