@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,407 +1,90 @@
1
- export type TModbusTransport = 'tcp' | 'udp' | 'rtuovertcp' | 'serial';
1
+ import type * as plugins from '../../plugins.js';
2
+ import type { INativeIntegrationOwnerOptions } from '../../core/classes.nativeintegrationowner.js';
2
3
 
3
- export type TModbusRegisterType = 'holding' | 'input';
4
+ export interface IModbusIntegrationOptions extends INativeIntegrationOwnerOptions {}
4
5
 
5
- export type TModbusCoilType = 'coil' | 'discrete_input';
6
-
7
- export type TModbusDataType =
8
- | 'custom'
9
- | 'string'
10
- | 'int'
11
- | 'integer'
12
- | 'int16'
13
- | 'int32'
14
- | 'int64'
15
- | 'uint'
16
- | 'uint16'
17
- | 'uint32'
18
- | 'uint64'
19
- | 'float'
20
- | 'float16'
21
- | 'float32'
22
- | 'float64';
23
-
24
- export type TModbusSwap = 'byte' | 'word' | 'word_byte';
25
-
26
- export type TModbusEntityPlatform = 'sensor' | 'binary_sensor' | 'switch' | 'number';
27
-
28
- export type TModbusEventType =
29
- | 'snapshot_refreshed'
30
- | 'command_mapped'
31
- | 'command_executed'
32
- | 'command_failed'
33
- | 'register_read'
34
- | 'register_written'
35
- | 'coil_read'
36
- | 'coil_written';
37
-
38
- export interface IModbusConfig {
39
- hubs?: IModbusHubConfig[];
40
- modbus?: IModbusHubConfig[];
41
- snapshot?: IModbusSnapshot;
42
- manualEntries?: IModbusManualTcpEntry[];
43
- connected?: boolean;
44
- timeoutMs?: number;
45
- commandExecutor?: (commandArg: IModbusCommand) => Promise<IModbusCommandResult | unknown>;
6
+ export interface IModbusMappingBase {
7
+ readonly id: string;
8
+ readonly name: string;
9
+ /** Zero-based wire address; no 40001 notation or vendor interpretation. */
10
+ readonly address: number;
11
+ readonly quantity?: number;
46
12
  }
47
13
 
48
- export interface IHomeAssistantModbusConfig extends IModbusConfig {}
49
-
50
- export interface IModbusHubConfig {
51
- id?: string;
52
- name?: string;
53
- type?: TModbusTransport;
54
- host?: string;
55
- port?: number | string;
56
- timeout?: number;
57
- timeoutMs?: number;
58
- delay?: number;
59
- messageWaitMilliseconds?: number;
60
- message_wait_milliseconds?: number;
61
- slave?: number;
62
- unit?: number;
63
- unitId?: number;
64
- deviceAddress?: number;
65
- device_address?: number;
66
- connected?: boolean;
67
- manufacturer?: string;
68
- model?: string;
69
- serialNumber?: string;
70
- serial_number?: string;
71
- metadata?: Record<string, unknown>;
72
- slaves?: IModbusSlaveConfig[];
73
- registers?: IModbusRegisterConfig[];
74
- coils?: IModbusCoilConfig[];
75
- sensors?: IModbusRegisterConfig[];
76
- binarySensors?: IModbusCoilConfig[];
77
- binary_sensors?: IModbusCoilConfig[];
78
- switches?: IModbusSwitchConfig[];
79
- numbers?: IModbusNumberConfig[];
80
- }
81
-
82
- export interface IModbusSlaveConfig {
83
- id?: string;
84
- unitId?: number;
85
- unit?: number;
86
- slave?: number;
87
- deviceAddress?: number;
88
- device_address?: number;
89
- name?: string;
90
- connected?: boolean;
91
- manufacturer?: string;
92
- model?: string;
93
- serialNumber?: string;
94
- serial_number?: string;
95
- metadata?: Record<string, unknown>;
14
+ export interface IModbusCoilMapping extends IModbusMappingBase {
15
+ readonly kind: 'coil';
16
+ /** Owner permission for one absolute FC5 write. Requires quantity one. */
17
+ readonly write?: true;
96
18
  }
97
19
 
98
- export interface IModbusEntityConfigBase {
99
- id?: string;
100
- name: string;
101
- uniqueId?: string;
102
- unique_id?: string;
103
- platform?: TModbusEntityPlatform;
104
- address: number;
105
- slave?: number;
106
- unit?: number;
107
- unitId?: number;
108
- deviceAddress?: number;
109
- device_address?: number;
110
- scanInterval?: number;
111
- scan_interval?: number;
112
- deviceClass?: string;
113
- device_class?: string;
114
- available?: boolean;
115
- metadata?: Record<string, unknown>;
20
+ export interface IModbusDiscreteInputMapping extends IModbusMappingBase {
21
+ readonly kind: 'discrete_input';
116
22
  }
117
23
 
118
- export interface IModbusRegisterConfig extends IModbusEntityConfigBase {
119
- platform?: 'sensor' | 'number';
120
- inputType?: TModbusRegisterType;
121
- input_type?: TModbusRegisterType;
122
- registerType?: TModbusRegisterType;
123
- register_type?: TModbusRegisterType;
124
- count?: number;
125
- dataType?: TModbusDataType;
126
- data_type?: TModbusDataType;
127
- structure?: string;
128
- scale?: number;
129
- offset?: number;
130
- precision?: number;
131
- swap?: TModbusSwap;
132
- unitOfMeasurement?: string;
133
- unit_of_measurement?: string;
134
- stateClass?: string;
135
- state_class?: string;
136
- minValue?: number;
137
- min_value?: number;
138
- maxValue?: number;
139
- max_value?: number;
140
- nanValue?: number;
141
- nan_value?: number;
142
- zeroSuppress?: number;
143
- zero_suppress?: number;
144
- min?: number;
145
- max?: number;
146
- step?: number;
147
- writable?: boolean;
148
- value?: number | string | null;
149
- registers?: number[];
24
+ export interface IModbusHoldingRegisterMapping extends IModbusMappingBase {
25
+ readonly kind: 'holding';
26
+ /** Inclusive unsigned raw bounds for one FC6 write. Requires quantity one. */
27
+ readonly write?: { readonly minimum: number; readonly maximum: number };
150
28
  }
151
29
 
152
- export interface IModbusNumberConfig extends IModbusRegisterConfig {
153
- platform?: 'number';
154
- writable?: true;
30
+ export interface IModbusInputRegisterMapping extends IModbusMappingBase {
31
+ readonly kind: 'input';
155
32
  }
156
33
 
157
- export interface IModbusCoilConfig extends IModbusEntityConfigBase {
158
- platform?: 'binary_sensor' | 'switch';
159
- inputType?: TModbusCoilType | TModbusRegisterType;
160
- input_type?: TModbusCoilType | TModbusRegisterType;
161
- coilType?: TModbusCoilType;
162
- coil_type?: TModbusCoilType;
163
- count?: number;
164
- slaveCount?: number;
165
- slave_count?: number;
166
- virtualCount?: number;
167
- virtual_count?: number;
168
- writable?: boolean;
169
- value?: boolean | number | null;
170
- bits?: boolean[];
171
- }
34
+ export type TModbusMapping = IModbusCoilMapping | IModbusDiscreteInputMapping | IModbusHoldingRegisterMapping | IModbusInputRegisterMapping;
35
+ export type TModbusNormalizedMapping = TModbusMapping & { readonly quantity: number };
172
36
 
173
- export interface IModbusSwitchConfig extends IModbusCoilConfig {
174
- platform?: 'switch';
175
- writeType?: TModbusWriteType;
176
- write_type?: TModbusWriteType;
177
- commandOn?: number;
178
- command_on?: number;
179
- commandOff?: number;
180
- command_off?: number;
181
- stateOn?: number[];
182
- state_on?: number[];
183
- stateOff?: number[];
184
- state_off?: number[];
185
- verify?: IModbusSwitchVerifyConfig | null;
186
- }
187
-
188
- export interface IModbusSwitchVerifyConfig {
189
- address?: number;
190
- inputType?: TModbusCoilType | TModbusRegisterType;
191
- input_type?: TModbusCoilType | TModbusRegisterType;
192
- delay?: number;
193
- stateOn?: number[];
194
- state_on?: number[];
195
- stateOff?: number[];
196
- state_off?: number[];
197
- }
198
-
199
- export type TModbusWriteType = 'holding' | 'holdings' | 'coil' | 'coils';
200
-
201
- export interface IModbusRegisterState {
202
- hubId?: string;
203
- unitId: number;
204
- address: number;
205
- count: number;
206
- inputType: TModbusRegisterType;
207
- dataType: TModbusDataType;
208
- registers?: number[];
209
- value?: number | string | number[] | null;
210
- updatedAt?: string;
211
- metadata?: Record<string, unknown>;
212
- }
213
-
214
- export interface IModbusCoilState {
215
- hubId?: string;
216
- unitId: number;
217
- address: number;
218
- count: number;
219
- inputType: TModbusCoilType | TModbusRegisterType;
220
- bits?: boolean[];
221
- value?: boolean | number | null;
222
- updatedAt?: string;
223
- metadata?: Record<string, unknown>;
37
+ export interface IModbusConfig {
38
+ readonly homeId: string;
39
+ readonly address: string;
40
+ readonly unitId: number;
41
+ readonly expectedVendorName: string;
42
+ readonly expectedProductCode: string;
43
+ readonly expectedRevision?: string;
44
+ readonly allowUnencryptedLan: true;
45
+ readonly mappings: readonly TModbusMapping[];
46
+ readonly port?: number;
47
+ readonly localAddress?: string;
48
+ readonly name?: string;
49
+ readonly timeoutMs?: number;
50
+ readonly maxQueuedOperations?: number;
224
51
  }
225
52
 
226
- export interface IModbusEntitySnapshot {
227
- id: string;
228
- name: string;
229
- uniqueId: string;
230
- platform: TModbusEntityPlatform;
231
- hubId: string;
232
- hubName: string;
233
- unitId: number;
234
- address: number;
235
- available: boolean;
236
- writable: boolean;
237
- register?: IModbusRegisterState;
238
- coil?: IModbusCoilState;
239
- state?: unknown;
240
- attributes?: Record<string, unknown>;
241
- }
53
+ export interface IHomeAssistantModbusConfig extends IModbusConfig {}
242
54
 
243
- export interface IModbusSlaveSnapshot {
244
- id: string;
245
- hubId: string;
246
- unitId: number;
247
- name: string;
248
- online: boolean;
249
- manufacturer?: string;
250
- model?: string;
251
- serialNumber?: string;
252
- registers: IModbusRegisterState[];
253
- coils: IModbusCoilState[];
254
- metadata?: Record<string, unknown>;
55
+ export interface IModbusNormalizedConfig extends Omit<IModbusConfig, 'mappings' | 'port' | 'timeoutMs' | 'maxQueuedOperations'> {
56
+ readonly mappings: readonly TModbusNormalizedMapping[];
57
+ readonly port: number;
58
+ readonly timeoutMs: number;
59
+ readonly maxQueuedOperations: number;
255
60
  }
256
61
 
257
- export interface IModbusHubSnapshot {
258
- id: string;
259
- name: string;
260
- type: TModbusTransport;
261
- host?: string;
262
- port?: number | string;
263
- online: boolean;
264
- manufacturer?: string;
265
- model?: string;
266
- serialNumber?: string;
267
- unsupportedReason?: string;
268
- slaves: IModbusSlaveSnapshot[];
269
- registers: IModbusRegisterState[];
270
- coils: IModbusCoilState[];
271
- entities: IModbusEntitySnapshot[];
272
- metadata?: Record<string, unknown>;
62
+ export interface IModbusObservation {
63
+ readonly mapping: TModbusNormalizedMapping;
64
+ readonly identity: plugins.ecobridgeDeviceManager.IModbusIdentity;
65
+ readonly values: readonly boolean[] | readonly number[];
66
+ readonly observedAt: string;
273
67
  }
274
68
 
275
69
  export interface IModbusSnapshot {
276
- hubs: IModbusHubSnapshot[];
277
- events: IModbusEvent[];
278
- connected: boolean;
279
- updatedAt: string;
280
- raw?: Record<string, unknown>;
281
- }
282
-
283
- export interface IModbusEvent {
284
- type: TModbusEventType;
285
- command?: IModbusCommand;
286
- hubId?: string;
287
- hubName?: string;
288
- unitId?: number;
289
- entityId?: string;
290
- deviceId?: string;
291
- uniqueId?: string;
292
- data?: unknown;
293
- timestamp: number;
70
+ readonly config: IModbusNormalizedConfig;
71
+ readonly identity: plugins.ecobridgeDeviceManager.IModbusIdentity;
72
+ readonly observations: readonly IModbusObservation[];
73
+ readonly observedAt: string;
294
74
  }
295
75
 
296
- export type IModbusCommand =
297
- | IModbusRefreshCommand
298
- | IModbusReadRegisterCommand
299
- | IModbusWriteRegisterCommand
300
- | IModbusReadCoilCommand
301
- | IModbusWriteCoilCommand
302
- | IModbusStopCommand
303
- | IModbusRestartCommand;
304
-
305
- export interface IModbusCommandBase {
306
- hub?: string;
307
- hubId?: string;
308
- unitId?: number;
309
- slave?: number;
310
- entityId?: string;
311
- deviceId?: string;
312
- uniqueId?: string;
313
- }
314
-
315
- export interface IModbusRefreshCommand extends IModbusCommandBase {
316
- type: 'refresh';
317
- }
318
-
319
- export interface IModbusStopCommand extends IModbusCommandBase {
320
- type: 'stop';
321
- }
322
-
323
- export interface IModbusRestartCommand extends IModbusCommandBase {
324
- type: 'restart';
325
- }
326
-
327
- export interface IModbusReadRegisterCommand extends IModbusCommandBase {
328
- type: 'read_register';
329
- address: number;
330
- count?: number;
331
- inputType?: TModbusRegisterType;
332
- dataType?: TModbusDataType;
333
- }
334
-
335
- export interface IModbusWriteRegisterCommand extends IModbusCommandBase {
336
- type: 'write_register';
337
- address: number;
338
- value: number | number[];
339
- }
340
-
341
- export interface IModbusReadCoilCommand extends IModbusCommandBase {
342
- type: 'read_coil';
343
- address: number;
344
- count?: number;
345
- inputType?: TModbusCoilType;
346
- }
347
-
348
- export interface IModbusWriteCoilCommand extends IModbusCommandBase {
349
- type: 'write_coil';
350
- address: number;
351
- value: boolean | boolean[] | number | number[];
352
- }
353
-
354
- export interface IModbusCommandResult {
355
- success: boolean;
356
- error?: string;
357
- data?: unknown;
358
- }
359
-
360
- export interface IModbusTcpCommandShape {
361
- transport: 'tcp';
362
- host?: string;
363
- port?: number;
364
- unitId: number;
365
- transactionId: number;
366
- functionCode: number;
367
- functionName: string;
368
- address?: number;
369
- quantity?: number;
370
- values?: number[] | boolean[];
371
- mbap: {
372
- transactionId: number;
373
- protocolId: 0;
374
- length: number;
375
- unitId: number;
376
- };
377
- pduHex: string;
378
- requestHex: string;
379
- }
380
-
381
- export interface IModbusTcpResponse {
382
- transactionId: number;
383
- unitId: number;
384
- functionCode: number;
385
- registers?: number[];
386
- bits?: boolean[];
387
- address?: number;
388
- quantity?: number;
389
- rawHex: string;
390
- }
76
+ export type TModbusCommand =
77
+ | { readonly type: 'read'; readonly mappingId: string }
78
+ | { readonly type: 'write_coil'; readonly mappingId: string; readonly value: boolean }
79
+ | { readonly type: 'write_register'; readonly mappingId: string; readonly value: number };
391
80
 
392
81
  export interface IModbusManualTcpEntry {
393
- host?: string;
394
- port?: number;
395
- type?: TModbusTransport;
396
- protocol?: string;
397
- name?: string;
398
- id?: string;
399
- unitId?: number;
400
- slave?: number;
401
- manufacturer?: string;
402
- model?: string;
403
- serialNumber?: string;
404
- metadata?: Record<string, unknown>;
82
+ readonly integrationDomain: 'modbus';
83
+ readonly address: string;
84
+ readonly unitId: number;
85
+ readonly expectedVendorName: string;
86
+ readonly expectedProductCode: string;
87
+ readonly expectedRevision?: string;
88
+ readonly port?: number;
89
+ readonly name?: string;
405
90
  }
406
-
407
- export interface IModbusDiscoveryEntry extends IModbusManualTcpEntry {}
@@ -0,0 +1,119 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import type { IModbusNormalizedConfig, TModbusCommand, TModbusNormalizedMapping } from './modbus.types.js';
3
+
4
+ export function modbusRecord(valueArg: unknown, allowedArg?: readonly string[]): Record<string, unknown> {
5
+ if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg) || ![Object.prototype, null].includes(Object.getPrototypeOf(valueArg))) {
6
+ throw new TypeError('Modbus inputs must be plain data objects.');
7
+ }
8
+ const result: Record<string, unknown> = {};
9
+ for (const key of Reflect.ownKeys(valueArg)) {
10
+ const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
11
+ if (typeof key !== 'string' || allowedArg && !allowedArg.includes(key) || !descriptor || !('value' in descriptor) || !descriptor.enumerable) {
12
+ throw new TypeError('Modbus inputs may not contain accessors, symbols, hidden or unsupported fields.');
13
+ }
14
+ Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
15
+ }
16
+ return result;
17
+ }
18
+
19
+ export function modbusText(valueArg: unknown, nameArg: string, maximumArg = 256): string {
20
+ if (typeof valueArg !== 'string' || !valueArg.length || valueArg.length > maximumArg || valueArg !== valueArg.trim() || /[\p{Cc}\p{Cs}]/u.test(valueArg)) {
21
+ throw new TypeError(`Modbus ${nameArg} requires bounded nonempty text without control characters.`);
22
+ }
23
+ return valueArg;
24
+ }
25
+
26
+ export function modbusIdentityText(valueArg: unknown): string {
27
+ if (typeof valueArg !== 'string' || !/^[\x20-\x7e]{1,244}$/.test(valueArg)) throw new TypeError('Modbus identity requires exact bounded printable ASCII text.');
28
+ return valueArg;
29
+ }
30
+
31
+ export function modbusAddress(valueArg: unknown): string {
32
+ if (typeof valueArg !== 'string' || plugins.net.isIP(valueArg) !== 4) throw new TypeError('Modbus requires an explicitly selected local IPv4 address.');
33
+ const parts = valueArg.split('.').map(Number);
34
+ const local = parts[0] === 10 || parts[0] === 127 || parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31 ||
35
+ parts[0] === 192 && parts[1] === 168 || parts[0] === 169 && parts[1] === 254;
36
+ if (!local || parts[3] === 255) throw new TypeError('Modbus requires a private, link-local or loopback unicast IPv4 address.');
37
+ return valueArg;
38
+ }
39
+
40
+ export function modbusInteger(valueArg: unknown, minimumArg: number, maximumArg: number): number {
41
+ if (typeof valueArg !== 'number' || !Number.isSafeInteger(valueArg) || valueArg < minimumArg || valueArg > maximumArg) {
42
+ throw new TypeError(`Modbus value must be an integer from ${minimumArg} through ${maximumArg}.`);
43
+ }
44
+ return valueArg;
45
+ }
46
+
47
+ export function modbusUnit(valueArg: unknown): number {
48
+ const unit = modbusInteger(valueArg, 1, 255);
49
+ if (unit > 247 && unit !== 255) throw new TypeError('Modbus requires an explicit unit 1–247 or direct TCP unit 255.');
50
+ return unit;
51
+ }
52
+
53
+ export function normalizeModbusConfig(valueArg: unknown): IModbusNormalizedConfig {
54
+ const value = modbusRecord(valueArg, ['homeId', 'address', 'unitId', 'expectedVendorName', 'expectedProductCode', 'expectedRevision',
55
+ 'allowUnencryptedLan', 'mappings', 'port', 'localAddress', 'name', 'timeoutMs', 'maxQueuedOperations']);
56
+ if (value.allowUnencryptedLan !== true) throw new TypeError('Modbus requires explicit acceptance of unencrypted LAN transport.');
57
+ const mappings = modbusMappings(value.mappings);
58
+ return Object.freeze({
59
+ homeId: modbusText(value.homeId, 'homeId'), address: modbusAddress(value.address), unitId: modbusUnit(value.unitId),
60
+ expectedVendorName: modbusIdentityText(value.expectedVendorName), expectedProductCode: modbusIdentityText(value.expectedProductCode),
61
+ ...(value.expectedRevision === undefined ? {} : { expectedRevision: modbusIdentityText(value.expectedRevision) }),
62
+ ...(value.localAddress === undefined ? {} : { localAddress: modbusAddress(value.localAddress) }),
63
+ ...(value.name === undefined ? {} : { name: modbusText(value.name, 'name', 128) }), allowUnencryptedLan: true,
64
+ port: modbusInteger(value.port === undefined ? 502 : value.port, 1, 65535),
65
+ timeoutMs: modbusInteger(value.timeoutMs === undefined ? 5000 : value.timeoutMs, 1, 60000),
66
+ maxQueuedOperations: modbusInteger(value.maxQueuedOperations === undefined ? 16 : value.maxQueuedOperations, 1, 128), mappings,
67
+ });
68
+ }
69
+
70
+ export function modbusMappings(valueArg: unknown): readonly TModbusNormalizedMapping[] {
71
+ if (!Array.isArray(valueArg) || valueArg.length < 1 || valueArg.length > 64) throw new TypeError('Modbus requires one through 64 explicit owner read mappings.');
72
+ if (Reflect.ownKeys(valueArg).some((key) => key !== 'length' && (typeof key !== 'string' || !/^(0|[1-9]\d*)$/.test(key)))) throw new TypeError('Modbus mapping lists contain only indexed data entries.');
73
+ const mappings: TModbusNormalizedMapping[] = [];
74
+ for (let index = 0; index < valueArg.length; index++) {
75
+ const descriptor = Object.getOwnPropertyDescriptor(valueArg, String(index));
76
+ if (!descriptor || !('value' in descriptor) || !descriptor.enumerable) throw new TypeError('Modbus mappings must be dense enumerable data entries.');
77
+ const value = modbusRecord(descriptor.value, ['id', 'name', 'address', 'quantity', 'kind', 'write']);
78
+ const id = modbusText(value.id, 'mapping id', 64);
79
+ if (!/^[a-z0-9][a-z0-9_-]*$/.test(id)) throw new TypeError('Modbus mapping IDs require lowercase letters, digits, underscore or hyphen.');
80
+ const name = modbusText(value.name, 'mapping name', 128);
81
+ const address = modbusInteger(value.address, 0, 65535);
82
+ const kind = value.kind;
83
+ if (kind !== 'coil' && kind !== 'discrete_input' && kind !== 'holding' && kind !== 'input') throw new TypeError('Modbus mapping kind is unsupported.');
84
+ const quantity = modbusInteger(value.quantity === undefined ? 1 : value.quantity, 1, kind === 'coil' || kind === 'discrete_input' ? 2000 : 125);
85
+ if (address + quantity > 65536) throw new TypeError('Modbus mapping exceeds the zero-based address space.');
86
+ if (mappings.some((mapping) => mapping.id === id || mapping.kind === kind && address < mapping.address + mapping.quantity && mapping.address < address + quantity)) {
87
+ throw new TypeError('Modbus mappings require unique IDs and nonoverlapping ranges per read kind.');
88
+ }
89
+ let mapping: TModbusNormalizedMapping;
90
+ if (value.write === undefined) mapping = { id, name, address, quantity, kind };
91
+ else {
92
+ if (quantity !== 1) throw new TypeError('Modbus write permission requires one absolute mapped address.');
93
+ if (kind === 'coil' && value.write === true) mapping = { id, name, address, quantity, kind, write: true };
94
+ else if (kind === 'holding') {
95
+ const write = modbusRecord(value.write, ['minimum', 'maximum']);
96
+ const minimum = modbusInteger(write.minimum, 0, 65535);
97
+ const maximum = modbusInteger(write.maximum, minimum, 65535);
98
+ mapping = { id, name, address, quantity, kind, write: Object.freeze({ minimum, maximum }) };
99
+ } else throw new TypeError('Modbus permits explicit single-coil or bounded single-holding-register writes only.');
100
+ }
101
+ mappings.push(Object.freeze(mapping));
102
+ }
103
+ return Object.freeze(mappings);
104
+ }
105
+
106
+ export function modbusCommand(valueArg: unknown, configArg: IModbusNormalizedConfig): TModbusCommand {
107
+ const value = modbusRecord(valueArg, ['type', 'mappingId', 'value']);
108
+ const mappingId = modbusText(value.mappingId, 'mapping id', 64);
109
+ const mapping = configArg.mappings.find((entry) => entry.id === mappingId);
110
+ if (!mapping) throw new TypeError('Modbus command must target one explicitly owned read mapping.');
111
+ if (value.type === 'read' && !Object.hasOwn(value, 'value')) return Object.freeze({ type: 'read', mappingId });
112
+ if (value.type === 'write_coil' && mapping.kind === 'coil' && mapping.write === true && typeof value.value === 'boolean') {
113
+ return Object.freeze({ type: 'write_coil', mappingId, value: value.value });
114
+ }
115
+ if (value.type === 'write_register' && mapping.kind === 'holding' && mapping.write !== undefined) {
116
+ return Object.freeze({ type: 'write_register', mappingId, value: modbusInteger(value.value, mapping.write.minimum, mapping.write.maximum) });
117
+ }
118
+ throw new TypeError('Modbus command is outside the explicit mapping write permission or absolute raw value contract.');
119
+ }