@smarthome.exchange/integrations 1.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. package/changelog.md +84 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/core/classes.configstore.d.ts +2 -0
  4. package/dist_ts/core/classes.configstore.js +84 -27
  5. package/dist_ts/core/classes.nativehomeadmission.d.ts +19 -0
  6. package/dist_ts/core/classes.nativehomeadmission.js +84 -0
  7. package/dist_ts/core/classes.nativeintegrationowner.d.ts +81 -0
  8. package/dist_ts/core/classes.nativeintegrationowner.js +273 -0
  9. package/dist_ts/core/classes.runtimemanager.d.ts +2 -0
  10. package/dist_ts/core/classes.runtimemanager.js +11 -3
  11. package/dist_ts/core/index.d.ts +2 -0
  12. package/dist_ts/core/index.js +3 -1
  13. package/dist_ts/core/types.d.ts +16 -0
  14. package/dist_ts/integrations/braviatv/braviatv.classes.client.d.ts +23 -72
  15. package/dist_ts/integrations/braviatv/braviatv.classes.client.js +265 -625
  16. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.d.ts +7 -7
  17. package/dist_ts/integrations/braviatv/braviatv.classes.configflow.js +51 -68
  18. package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +8 -11
  19. package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +186 -135
  20. package/dist_ts/integrations/braviatv/braviatv.discovery.js +12 -11
  21. package/dist_ts/integrations/braviatv/braviatv.mapper.d.ts +6 -14
  22. package/dist_ts/integrations/braviatv/braviatv.mapper.js +37 -131
  23. package/dist_ts/integrations/braviatv/braviatv.types.d.ts +55 -133
  24. package/dist_ts/integrations/braviatv/braviatv.validation.d.ts +7 -0
  25. package/dist_ts/integrations/braviatv/braviatv.validation.js +72 -0
  26. package/dist_ts/integrations/broadlink/broadlink.actions.d.ts +2 -0
  27. package/dist_ts/integrations/broadlink/broadlink.actions.js +36 -0
  28. package/dist_ts/integrations/broadlink/broadlink.classes.client.d.ts +21 -19
  29. package/dist_ts/integrations/broadlink/broadlink.classes.client.js +185 -124
  30. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.d.ts +5 -4
  31. package/dist_ts/integrations/broadlink/broadlink.classes.configflow.js +64 -83
  32. package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +16 -19
  33. package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +114 -59
  34. package/dist_ts/integrations/broadlink/broadlink.mapper.d.ts +3 -2
  35. package/dist_ts/integrations/broadlink/broadlink.mapper.js +2 -1
  36. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.d.ts +10 -0
  37. package/dist_ts/integrations/broadlink/broadlink.selected.mapper.js +41 -0
  38. package/dist_ts/integrations/broadlink/broadlink.types.d.ts +43 -7
  39. package/dist_ts/integrations/broadlink/broadlink.validation.d.ts +7 -0
  40. package/dist_ts/integrations/broadlink/broadlink.validation.js +63 -0
  41. package/dist_ts/integrations/daikin/daikin.classes.client.d.ts +10 -52
  42. package/dist_ts/integrations/daikin/daikin.classes.client.js +55 -614
  43. package/dist_ts/integrations/daikin/daikin.classes.configflow.d.ts +8 -12
  44. package/dist_ts/integrations/daikin/daikin.classes.configflow.js +77 -138
  45. package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +7 -24
  46. package/dist_ts/integrations/daikin/daikin.classes.integration.js +175 -67
  47. package/dist_ts/integrations/daikin/daikin.discovery.d.ts +11 -24
  48. package/dist_ts/integrations/daikin/daikin.discovery.js +98 -305
  49. package/dist_ts/integrations/daikin/daikin.mapper.d.ts +6 -7
  50. package/dist_ts/integrations/daikin/daikin.mapper.js +95 -155
  51. package/dist_ts/integrations/daikin/daikin.types.d.ts +24 -44
  52. package/dist_ts/integrations/daikin/daikin.types.js +1 -1
  53. package/dist_ts/integrations/daikin/daikin.validation.d.ts +5 -0
  54. package/dist_ts/integrations/daikin/daikin.validation.js +53 -0
  55. package/dist_ts/integrations/deconz/deconz.classes.client.d.ts +37 -29
  56. package/dist_ts/integrations/deconz/deconz.classes.client.js +521 -294
  57. package/dist_ts/integrations/deconz/deconz.classes.configflow.d.ts +6 -1
  58. package/dist_ts/integrations/deconz/deconz.classes.configflow.js +63 -33
  59. package/dist_ts/integrations/deconz/deconz.classes.integration.d.ts +4 -3
  60. package/dist_ts/integrations/deconz/deconz.classes.integration.js +85 -40
  61. package/dist_ts/integrations/deconz/deconz.mapper.d.ts +1 -0
  62. package/dist_ts/integrations/deconz/deconz.mapper.js +24 -6
  63. package/dist_ts/integrations/deconz/deconz.types.d.ts +43 -6
  64. package/dist_ts/integrations/deconz/deconz.validation.d.ts +7 -1
  65. package/dist_ts/integrations/deconz/deconz.validation.js +215 -4
  66. package/dist_ts/integrations/denonavr/denonavr.classes.client.d.ts +31 -40
  67. package/dist_ts/integrations/denonavr/denonavr.classes.client.js +149 -404
  68. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.d.ts +7 -2
  69. package/dist_ts/integrations/denonavr/denonavr.classes.configflow.js +44 -36
  70. package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +6 -11
  71. package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +192 -113
  72. package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +10 -18
  73. package/dist_ts/integrations/denonavr/denonavr.discovery.js +71 -193
  74. package/dist_ts/integrations/denonavr/denonavr.mapper.d.ts +5 -13
  75. package/dist_ts/integrations/denonavr/denonavr.mapper.js +35 -159
  76. package/dist_ts/integrations/denonavr/denonavr.types.d.ts +55 -90
  77. package/dist_ts/integrations/denonavr/denonavr.validation.d.ts +10 -0
  78. package/dist_ts/integrations/denonavr/denonavr.validation.js +86 -0
  79. package/dist_ts/integrations/esphome/esphome.classes.client.d.ts +19 -7
  80. package/dist_ts/integrations/esphome/esphome.classes.client.js +183 -89
  81. package/dist_ts/integrations/esphome/esphome.classes.configflow.d.ts +5 -2
  82. package/dist_ts/integrations/esphome/esphome.classes.configflow.js +43 -33
  83. package/dist_ts/integrations/esphome/esphome.classes.integration.d.ts +8 -6
  84. package/dist_ts/integrations/esphome/esphome.classes.integration.js +71 -43
  85. package/dist_ts/integrations/esphome/esphome.discovery.js +4 -12
  86. package/dist_ts/integrations/esphome/esphome.mapper.d.ts +2 -2
  87. package/dist_ts/integrations/esphome/esphome.mapper.js +6 -4
  88. package/dist_ts/integrations/esphome/esphome.types.d.ts +31 -6
  89. package/dist_ts/integrations/esphome/esphome.types.js +1 -1
  90. package/dist_ts/integrations/esphome/esphome.validation.d.ts +7 -0
  91. package/dist_ts/integrations/esphome/esphome.validation.js +66 -0
  92. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.d.ts +32 -4
  93. package/dist_ts/integrations/homeassistant/homeassistant.classes.client.js +345 -116
  94. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.d.ts +8 -5
  95. package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.js +34 -8
  96. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.d.ts +7 -4
  97. package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.js +44 -56
  98. package/dist_ts/integrations/homeassistant/homeassistant.types.d.ts +12 -1
  99. package/dist_ts/integrations/hue/hue.classes.client.d.ts +6 -1
  100. package/dist_ts/integrations/hue/hue.classes.client.js +120 -45
  101. package/dist_ts/integrations/hue/hue.classes.configflow.js +16 -7
  102. package/dist_ts/integrations/hue/hue.classes.integration.d.ts +2 -0
  103. package/dist_ts/integrations/hue/hue.classes.integration.js +103 -30
  104. package/dist_ts/integrations/hue/hue.validation.d.ts +1 -0
  105. package/dist_ts/integrations/hue/hue.validation.js +14 -4
  106. package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +11 -45
  107. package/dist_ts/integrations/kodi/kodi.classes.client.js +84 -310
  108. package/dist_ts/integrations/kodi/kodi.classes.configflow.d.ts +9 -8
  109. package/dist_ts/integrations/kodi/kodi.classes.configflow.js +53 -48
  110. package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +11 -11
  111. package/dist_ts/integrations/kodi/kodi.classes.integration.js +114 -171
  112. package/dist_ts/integrations/kodi/kodi.discovery.js +53 -29
  113. package/dist_ts/integrations/kodi/kodi.mapper.d.ts +7 -2
  114. package/dist_ts/integrations/kodi/kodi.mapper.js +48 -10
  115. package/dist_ts/integrations/kodi/kodi.types.d.ts +32 -28
  116. package/dist_ts/integrations/kodi/kodi.validation.d.ts +9 -0
  117. package/dist_ts/integrations/kodi/kodi.validation.js +62 -0
  118. package/dist_ts/integrations/modbus/modbus.classes.client.d.ts +15 -61
  119. package/dist_ts/integrations/modbus/modbus.classes.client.js +117 -776
  120. package/dist_ts/integrations/modbus/modbus.classes.configflow.d.ts +9 -5
  121. package/dist_ts/integrations/modbus/modbus.classes.configflow.js +70 -38
  122. package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +6 -17
  123. package/dist_ts/integrations/modbus/modbus.classes.integration.js +133 -57
  124. package/dist_ts/integrations/modbus/modbus.discovery.d.ts +5 -8
  125. package/dist_ts/integrations/modbus/modbus.discovery.js +38 -93
  126. package/dist_ts/integrations/modbus/modbus.mapper.d.ts +8 -32
  127. package/dist_ts/integrations/modbus/modbus.mapper.js +71 -431
  128. package/dist_ts/integrations/modbus/modbus.types.d.ts +82 -332
  129. package/dist_ts/integrations/modbus/modbus.validation.d.ts +10 -0
  130. package/dist_ts/integrations/modbus/modbus.validation.js +128 -0
  131. package/dist_ts/integrations/mqtt/mqtt.classes.client.d.ts +15 -2
  132. package/dist_ts/integrations/mqtt/mqtt.classes.client.js +173 -23
  133. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.d.ts +5 -1
  134. package/dist_ts/integrations/mqtt/mqtt.classes.configflow.js +53 -33
  135. package/dist_ts/integrations/mqtt/mqtt.classes.integration.d.ts +4 -1
  136. package/dist_ts/integrations/mqtt/mqtt.classes.integration.js +127 -56
  137. package/dist_ts/integrations/mqtt/mqtt.classes.session.d.ts +13 -0
  138. package/dist_ts/integrations/mqtt/mqtt.classes.session.js +130 -0
  139. package/dist_ts/integrations/mqtt/mqtt.mapper.d.ts +3 -0
  140. package/dist_ts/integrations/mqtt/mqtt.mapper.js +44 -1
  141. package/dist_ts/integrations/mqtt/mqtt.types.d.ts +46 -0
  142. package/dist_ts/integrations/mqtt/mqtt.validation.d.ts +7 -0
  143. package/dist_ts/integrations/mqtt/mqtt.validation.js +180 -0
  144. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.d.ts +12 -34
  145. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +143 -231
  146. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.d.ts +6 -1
  147. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.js +105 -18
  148. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +8 -8
  149. package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +141 -155
  150. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.d.ts +9 -0
  151. package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.js +35 -0
  152. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.d.ts +6 -18
  153. package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.js +45 -220
  154. package/dist_ts/integrations/nanoleaf/nanoleaf.types.d.ts +33 -147
  155. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.d.ts +6 -0
  156. package/dist_ts/integrations/nanoleaf/nanoleaf.validation.js +82 -0
  157. package/dist_ts/integrations/onkyo/onkyo.classes.client.d.ts +15 -20
  158. package/dist_ts/integrations/onkyo/onkyo.classes.client.js +161 -404
  159. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.d.ts +9 -4
  160. package/dist_ts/integrations/onkyo/onkyo.classes.configflow.js +51 -6
  161. package/dist_ts/integrations/onkyo/onkyo.classes.integration.d.ts +22 -6
  162. package/dist_ts/integrations/onkyo/onkyo.classes.integration.js +144 -11
  163. package/dist_ts/integrations/onkyo/onkyo.discovery.d.ts +6 -1
  164. package/dist_ts/integrations/onkyo/onkyo.discovery.js +40 -4
  165. package/dist_ts/integrations/onkyo/onkyo.mapper.d.ts +7 -8
  166. package/dist_ts/integrations/onkyo/onkyo.mapper.js +45 -12
  167. package/dist_ts/integrations/onkyo/onkyo.types.d.ts +58 -8
  168. package/dist_ts/integrations/onkyo/onkyo.types.js +13 -102
  169. package/dist_ts/integrations/onkyo/onkyo.validation.d.ts +16 -0
  170. package/dist_ts/integrations/onkyo/onkyo.validation.js +77 -0
  171. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.d.ts +25 -25
  172. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +116 -360
  173. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.d.ts +11 -3
  174. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.js +76 -6
  175. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.d.ts +26 -4
  176. package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.js +142 -9
  177. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.d.ts +2 -1
  178. package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.js +31 -4
  179. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.d.ts +9 -9
  180. package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.js +31 -149
  181. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.d.ts +51 -11
  182. package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.js +22 -87
  183. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.d.ts +6 -0
  184. package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.js +56 -0
  185. package/dist_ts/integrations/pioneer/pioneer.classes.client.d.ts +31 -16
  186. package/dist_ts/integrations/pioneer/pioneer.classes.client.js +167 -409
  187. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.d.ts +10 -3
  188. package/dist_ts/integrations/pioneer/pioneer.classes.configflow.js +66 -6
  189. package/dist_ts/integrations/pioneer/pioneer.classes.integration.d.ts +13 -5
  190. package/dist_ts/integrations/pioneer/pioneer.classes.integration.js +239 -11
  191. package/dist_ts/integrations/pioneer/pioneer.discovery.d.ts +14 -1
  192. package/dist_ts/integrations/pioneer/pioneer.discovery.js +51 -4
  193. package/dist_ts/integrations/pioneer/pioneer.mapper.d.ts +14 -8
  194. package/dist_ts/integrations/pioneer/pioneer.mapper.js +54 -12
  195. package/dist_ts/integrations/pioneer/pioneer.types.d.ts +79 -12
  196. package/dist_ts/integrations/pioneer/pioneer.types.js +12 -76
  197. package/dist_ts/integrations/pioneer/pioneer.validation.d.ts +10 -0
  198. package/dist_ts/integrations/pioneer/pioneer.validation.js +85 -0
  199. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.d.ts +4 -2
  200. package/dist_ts/integrations/samsungtv/samsungtv.classes.client.js +41 -16
  201. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.d.ts +5 -0
  202. package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.js +20 -7
  203. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.d.ts +1 -0
  204. package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.js +53 -50
  205. package/dist_ts/integrations/samsungtv/samsungtv.types.d.ts +4 -1
  206. package/dist_ts/integrations/shelly/shelly.classes.client.d.ts +26 -30
  207. package/dist_ts/integrations/shelly/shelly.classes.client.js +504 -276
  208. package/dist_ts/integrations/shelly/shelly.classes.configflow.d.ts +8 -3
  209. package/dist_ts/integrations/shelly/shelly.classes.configflow.js +43 -38
  210. package/dist_ts/integrations/shelly/shelly.classes.integration.d.ts +6 -6
  211. package/dist_ts/integrations/shelly/shelly.classes.integration.js +103 -101
  212. package/dist_ts/integrations/shelly/shelly.classes.subscription.d.ts +4 -0
  213. package/dist_ts/integrations/shelly/shelly.classes.subscription.js +24 -2
  214. package/dist_ts/integrations/shelly/shelly.mapper.d.ts +1 -2
  215. package/dist_ts/integrations/shelly/shelly.mapper.js +21 -20
  216. package/dist_ts/integrations/shelly/shelly.rpc.js +4 -1
  217. package/dist_ts/integrations/shelly/shelly.types.d.ts +42 -2
  218. package/dist_ts/integrations/shelly/shelly.types.js +11 -2
  219. package/dist_ts/integrations/shelly/shelly.validation.d.ts +7 -0
  220. package/dist_ts/integrations/shelly/shelly.validation.js +79 -0
  221. package/dist_ts/integrations/sonos/sonos.classes.client.d.ts +79 -22
  222. package/dist_ts/integrations/sonos/sonos.classes.client.js +427 -139
  223. package/dist_ts/integrations/sonos/sonos.classes.configflow.d.ts +9 -2
  224. package/dist_ts/integrations/sonos/sonos.classes.configflow.js +26 -28
  225. package/dist_ts/integrations/sonos/sonos.classes.integration.d.ts +7 -6
  226. package/dist_ts/integrations/sonos/sonos.classes.integration.js +289 -224
  227. package/dist_ts/integrations/sonos/sonos.config.d.ts +6 -1
  228. package/dist_ts/integrations/sonos/sonos.config.js +23 -2
  229. package/dist_ts/integrations/sonos/sonos.mapper.d.ts +1 -1
  230. package/dist_ts/integrations/sonos/sonos.mapper.js +14 -9
  231. package/dist_ts/integrations/sonos/sonos.matchers.js +3 -3
  232. package/dist_ts/integrations/sonos/sonos.types.d.ts +26 -1
  233. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.d.ts +13 -36
  234. package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +179 -502
  235. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.d.ts +6 -1
  236. package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.js +50 -40
  237. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +14 -15
  238. package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +108 -128
  239. package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -20
  240. package/dist_ts/integrations/soundtouch/soundtouch.discovery.js +23 -113
  241. package/dist_ts/integrations/soundtouch/soundtouch.mapper.d.ts +3 -12
  242. package/dist_ts/integrations/soundtouch/soundtouch.mapper.js +35 -189
  243. package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +57 -142
  244. package/dist_ts/integrations/soundtouch/soundtouch.types.js +18 -3
  245. package/dist_ts/integrations/soundtouch/soundtouch.validation.d.ts +22 -0
  246. package/dist_ts/integrations/soundtouch/soundtouch.validation.js +65 -0
  247. package/dist_ts/integrations/tasmota/tasmota.classes.integration.d.ts +5 -0
  248. package/dist_ts/integrations/tasmota/tasmota.classes.integration.js +23 -7
  249. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.d.ts +19 -5
  250. package/dist_ts/integrations/tasmota/tasmota.classes.runtime.js +115 -41
  251. package/dist_ts/integrations/tasmota/tasmota.config.js +23 -1
  252. package/dist_ts/integrations/tasmota/tasmota.credentials.d.ts +11 -0
  253. package/dist_ts/integrations/tasmota/tasmota.credentials.js +97 -0
  254. package/dist_ts/integrations/tasmota/tasmota.discovery.d.ts +7 -1
  255. package/dist_ts/integrations/tasmota/tasmota.discovery.js +108 -30
  256. package/dist_ts/integrations/tasmota/tasmota.mapper.d.ts +2 -2
  257. package/dist_ts/integrations/tasmota/tasmota.mapper.js +7 -7
  258. package/dist_ts/integrations/tasmota/tasmota.types.d.ts +41 -2
  259. package/dist_ts/integrations/tuya/tuya.classes.integration.d.ts +4 -1
  260. package/dist_ts/integrations/tuya/tuya.classes.integration.js +79 -110
  261. package/dist_ts/integrations/tuya/tuya.classes.runtime.d.ts +5 -2
  262. package/dist_ts/integrations/tuya/tuya.classes.runtime.js +73 -26
  263. package/dist_ts/integrations/tuya/tuya.mapper.js +2 -2
  264. package/dist_ts/integrations/tuya/tuya.types.d.ts +3 -0
  265. package/dist_ts/integrations/tuya/tuya.validation.d.ts +2 -2
  266. package/dist_ts/integrations/tuya/tuya.validation.js +6 -11
  267. package/dist_ts/integrations/webostv/webostv.classes.client.d.ts +6 -5
  268. package/dist_ts/integrations/webostv/webostv.classes.client.js +147 -76
  269. package/dist_ts/integrations/webostv/webostv.classes.configflow.d.ts +7 -2
  270. package/dist_ts/integrations/webostv/webostv.classes.configflow.js +36 -20
  271. package/dist_ts/integrations/webostv/webostv.classes.integration.d.ts +4 -4
  272. package/dist_ts/integrations/webostv/webostv.classes.integration.js +46 -54
  273. package/dist_ts/integrations/webostv/webostv.mapper.js +5 -5
  274. package/dist_ts/integrations/webostv/webostv.types.d.ts +16 -3
  275. package/dist_ts/integrations/webostv/webostv.types.js +1 -1
  276. package/dist_ts/integrations/webostv/webostv.validation.d.ts +3 -1
  277. package/dist_ts/integrations/webostv/webostv.validation.js +23 -1
  278. package/dist_ts/integrations/wiz/index.d.ts +1 -0
  279. package/dist_ts/integrations/wiz/index.js +2 -1
  280. package/dist_ts/integrations/wiz/wiz.classes.client.d.ts +14 -28
  281. package/dist_ts/integrations/wiz/wiz.classes.client.js +93 -229
  282. package/dist_ts/integrations/wiz/wiz.classes.configflow.d.ts +6 -4
  283. package/dist_ts/integrations/wiz/wiz.classes.configflow.js +38 -67
  284. package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +10 -21
  285. package/dist_ts/integrations/wiz/wiz.classes.integration.js +204 -44
  286. package/dist_ts/integrations/wiz/wiz.discovery.d.ts +10 -31
  287. package/dist_ts/integrations/wiz/wiz.discovery.js +48 -249
  288. package/dist_ts/integrations/wiz/wiz.mapper.d.ts +7 -51
  289. package/dist_ts/integrations/wiz/wiz.mapper.js +82 -668
  290. package/dist_ts/integrations/wiz/wiz.types.d.ts +34 -208
  291. package/dist_ts/integrations/wiz/wiz.validation.d.ts +8 -0
  292. package/dist_ts/integrations/wiz/wiz.validation.js +72 -0
  293. package/dist_ts/integrations/yamaha/index.d.ts +1 -0
  294. package/dist_ts/integrations/yamaha/index.js +2 -1
  295. package/dist_ts/integrations/yamaha/yamaha.classes.client.d.ts +30 -4
  296. package/dist_ts/integrations/yamaha/yamaha.classes.client.js +162 -6
  297. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.d.ts +10 -3
  298. package/dist_ts/integrations/yamaha/yamaha.classes.configflow.js +106 -6
  299. package/dist_ts/integrations/yamaha/yamaha.classes.integration.d.ts +22 -4
  300. package/dist_ts/integrations/yamaha/yamaha.classes.integration.js +243 -8
  301. package/dist_ts/integrations/yamaha/yamaha.discovery.d.ts +13 -1
  302. package/dist_ts/integrations/yamaha/yamaha.discovery.js +57 -4
  303. package/dist_ts/integrations/yamaha/yamaha.mapper.d.ts +16 -8
  304. package/dist_ts/integrations/yamaha/yamaha.mapper.js +58 -12
  305. package/dist_ts/integrations/yamaha/yamaha.types.d.ts +73 -6
  306. package/dist_ts/integrations/yamaha/yamaha.types.js +8 -94
  307. package/dist_ts/integrations/yamaha/yamaha.validation.d.ts +12 -0
  308. package/dist_ts/integrations/yamaha/yamaha.validation.js +89 -0
  309. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.d.ts +6 -1
  310. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.js +18 -8
  311. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.d.ts +4 -1
  312. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.js +54 -6
  313. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.d.ts +12 -6
  314. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.js +73 -59
  315. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.d.ts +3 -2
  316. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.js +17 -12
  317. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.d.ts +31 -2
  318. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.d.ts +9 -1
  319. package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.js +57 -7
  320. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.d.ts +10 -4
  321. package/dist_ts/integrations/zwave_js/zwave_js.classes.client.js +167 -31
  322. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.d.ts +6 -1
  323. package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.js +57 -35
  324. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.d.ts +3 -1
  325. package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.js +59 -37
  326. package/dist_ts/integrations/zwave_js/zwave_js.discovery.js +3 -3
  327. package/dist_ts/integrations/zwave_js/zwave_js.mapper.js +41 -24
  328. package/dist_ts/integrations/zwave_js/zwave_js.types.d.ts +25 -3
  329. package/dist_ts/integrations/zwave_js/zwave_js.validation.d.ts +6 -2
  330. package/dist_ts/integrations/zwave_js/zwave_js.validation.js +52 -17
  331. package/dist_ts/plugins.d.ts +2 -1
  332. package/dist_ts/plugins.js +3 -2
  333. package/package.json +9 -9
  334. package/readme.md +539 -8
  335. package/ts/00_commitinfo_data.ts +1 -1
  336. package/ts/core/classes.configstore.ts +84 -27
  337. package/ts/core/classes.nativehomeadmission.ts +96 -0
  338. package/ts/core/classes.nativeintegrationowner.ts +302 -0
  339. package/ts/core/classes.runtimemanager.ts +11 -2
  340. package/ts/core/index.ts +2 -0
  341. package/ts/core/types.ts +18 -0
  342. package/ts/integrations/braviatv/braviatv.classes.client.ts +245 -709
  343. package/ts/integrations/braviatv/braviatv.classes.configflow.ts +47 -76
  344. package/ts/integrations/braviatv/braviatv.classes.integration.ts +167 -147
  345. package/ts/integrations/braviatv/braviatv.discovery.ts +11 -10
  346. package/ts/integrations/braviatv/braviatv.mapper.ts +39 -142
  347. package/ts/integrations/braviatv/braviatv.types.ts +53 -173
  348. package/ts/integrations/braviatv/braviatv.validation.ts +68 -0
  349. package/ts/integrations/broadlink/broadlink.actions.ts +31 -0
  350. package/ts/integrations/broadlink/broadlink.classes.client.ts +170 -144
  351. package/ts/integrations/broadlink/broadlink.classes.configflow.ts +59 -89
  352. package/ts/integrations/broadlink/broadlink.classes.integration.ts +110 -64
  353. package/ts/integrations/broadlink/broadlink.mapper.ts +5 -4
  354. package/ts/integrations/broadlink/broadlink.selected.mapper.ts +46 -0
  355. package/ts/integrations/broadlink/broadlink.types.ts +48 -8
  356. package/ts/integrations/broadlink/broadlink.validation.ts +66 -0
  357. package/ts/integrations/daikin/daikin.classes.client.ts +52 -661
  358. package/ts/integrations/daikin/daikin.classes.configflow.ts +72 -152
  359. package/ts/integrations/daikin/daikin.classes.integration.ts +166 -71
  360. package/ts/integrations/daikin/daikin.discovery.ts +94 -346
  361. package/ts/integrations/daikin/daikin.mapper.ts +83 -166
  362. package/ts/integrations/daikin/daikin.types.ts +27 -48
  363. package/ts/integrations/daikin/daikin.validation.ts +51 -0
  364. package/ts/integrations/daikin/readme.md +83 -0
  365. package/ts/integrations/deconz/deconz.classes.client.ts +348 -252
  366. package/ts/integrations/deconz/deconz.classes.configflow.ts +57 -29
  367. package/ts/integrations/deconz/deconz.classes.integration.ts +69 -37
  368. package/ts/integrations/deconz/deconz.mapper.ts +22 -5
  369. package/ts/integrations/deconz/deconz.types.ts +49 -6
  370. package/ts/integrations/deconz/deconz.validation.ts +177 -4
  371. package/ts/integrations/deconz/readme.md +15 -1
  372. package/ts/integrations/denonavr/denonavr.classes.client.ts +132 -421
  373. package/ts/integrations/denonavr/denonavr.classes.configflow.ts +44 -37
  374. package/ts/integrations/denonavr/denonavr.classes.integration.ts +171 -117
  375. package/ts/integrations/denonavr/denonavr.discovery.ts +67 -220
  376. package/ts/integrations/denonavr/denonavr.mapper.ts +36 -182
  377. package/ts/integrations/denonavr/denonavr.types.ts +48 -111
  378. package/ts/integrations/denonavr/denonavr.validation.ts +87 -0
  379. package/ts/integrations/esphome/esphome.classes.client.ts +179 -94
  380. package/ts/integrations/esphome/esphome.classes.configflow.ts +40 -33
  381. package/ts/integrations/esphome/esphome.classes.integration.ts +63 -36
  382. package/ts/integrations/esphome/esphome.discovery.ts +3 -12
  383. package/ts/integrations/esphome/esphome.mapper.ts +9 -7
  384. package/ts/integrations/esphome/esphome.types.ts +35 -6
  385. package/ts/integrations/esphome/esphome.validation.ts +66 -0
  386. package/ts/integrations/esphome/readme.md +20 -6
  387. package/ts/integrations/homeassistant/homeassistant.classes.client.ts +353 -125
  388. package/ts/integrations/homeassistant/homeassistant.classes.integration.ts +35 -18
  389. package/ts/integrations/homeassistant/homeassistant.classes.runtime.ts +50 -63
  390. package/ts/integrations/homeassistant/homeassistant.types.ts +17 -1
  391. package/ts/integrations/homeassistant/readme.md +22 -6
  392. package/ts/integrations/hue/hue.classes.client.ts +110 -41
  393. package/ts/integrations/hue/hue.classes.configflow.ts +12 -6
  394. package/ts/integrations/hue/hue.classes.integration.ts +92 -26
  395. package/ts/integrations/hue/hue.validation.ts +13 -3
  396. package/ts/integrations/hue/readme.md +3 -3
  397. package/ts/integrations/kodi/kodi.classes.client.ts +72 -352
  398. package/ts/integrations/kodi/kodi.classes.configflow.ts +52 -55
  399. package/ts/integrations/kodi/kodi.classes.integration.ts +97 -178
  400. package/ts/integrations/kodi/kodi.discovery.ts +49 -28
  401. package/ts/integrations/kodi/kodi.mapper.ts +52 -10
  402. package/ts/integrations/kodi/kodi.types.ts +33 -58
  403. package/ts/integrations/kodi/kodi.validation.ts +60 -0
  404. package/ts/integrations/modbus/modbus.classes.client.ts +100 -842
  405. package/ts/integrations/modbus/modbus.classes.configflow.ts +70 -41
  406. package/ts/integrations/modbus/modbus.classes.integration.ts +115 -60
  407. package/ts/integrations/modbus/modbus.discovery.ts +38 -106
  408. package/ts/integrations/modbus/modbus.mapper.ts +64 -467
  409. package/ts/integrations/modbus/modbus.types.ts +64 -381
  410. package/ts/integrations/modbus/modbus.validation.ts +119 -0
  411. package/ts/integrations/mqtt/mqtt.classes.client.ts +136 -19
  412. package/ts/integrations/mqtt/mqtt.classes.configflow.ts +45 -32
  413. package/ts/integrations/mqtt/mqtt.classes.integration.ts +99 -38
  414. package/ts/integrations/mqtt/mqtt.classes.session.ts +118 -0
  415. package/ts/integrations/mqtt/mqtt.mapper.ts +43 -1
  416. package/ts/integrations/mqtt/mqtt.types.ts +52 -0
  417. package/ts/integrations/mqtt/mqtt.validation.ts +157 -0
  418. package/ts/integrations/mqtt/readme.md +12 -3
  419. package/ts/integrations/nanoleaf/nanoleaf.classes.client.ts +115 -249
  420. package/ts/integrations/nanoleaf/nanoleaf.classes.configflow.ts +90 -19
  421. package/ts/integrations/nanoleaf/nanoleaf.classes.integration.ts +130 -181
  422. package/ts/integrations/nanoleaf/nanoleaf.credentials.ts +39 -0
  423. package/ts/integrations/nanoleaf/nanoleaf.mapper.ts +47 -260
  424. package/ts/integrations/nanoleaf/nanoleaf.types.ts +29 -147
  425. package/ts/integrations/nanoleaf/nanoleaf.validation.ts +77 -0
  426. package/ts/integrations/onkyo/onkyo.classes.client.ts +148 -457
  427. package/ts/integrations/onkyo/onkyo.classes.configflow.ts +52 -6
  428. package/ts/integrations/onkyo/onkyo.classes.integration.ts +121 -12
  429. package/ts/integrations/onkyo/onkyo.discovery.ts +41 -3
  430. package/ts/integrations/onkyo/onkyo.mapper.ts +46 -19
  431. package/ts/integrations/onkyo/onkyo.types.ts +55 -110
  432. package/ts/integrations/onkyo/onkyo.validation.ts +85 -0
  433. package/ts/integrations/onkyo/readme.md +126 -0
  434. package/ts/integrations/panasonic_viera/panasonic_viera.classes.client.ts +101 -398
  435. package/ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.ts +69 -5
  436. package/ts/integrations/panasonic_viera/panasonic_viera.classes.integration.ts +141 -9
  437. package/ts/integrations/panasonic_viera/panasonic_viera.discovery.ts +32 -3
  438. package/ts/integrations/panasonic_viera/panasonic_viera.mapper.ts +34 -161
  439. package/ts/integrations/panasonic_viera/panasonic_viera.types.ts +52 -96
  440. package/ts/integrations/panasonic_viera/panasonic_viera.validation.ts +56 -0
  441. package/ts/integrations/pioneer/pioneer.classes.client.ts +132 -428
  442. package/ts/integrations/pioneer/pioneer.classes.configflow.ts +67 -5
  443. package/ts/integrations/pioneer/pioneer.classes.integration.ts +225 -11
  444. package/ts/integrations/pioneer/pioneer.discovery.ts +45 -3
  445. package/ts/integrations/pioneer/pioneer.mapper.ts +57 -13
  446. package/ts/integrations/pioneer/pioneer.types.ts +87 -85
  447. package/ts/integrations/pioneer/pioneer.validation.ts +84 -0
  448. package/ts/integrations/samsungtv/readme.md +11 -5
  449. package/ts/integrations/samsungtv/samsungtv.classes.client.ts +40 -15
  450. package/ts/integrations/samsungtv/samsungtv.classes.configflow.ts +21 -6
  451. package/ts/integrations/samsungtv/samsungtv.classes.integration.ts +53 -38
  452. package/ts/integrations/samsungtv/samsungtv.types.ts +4 -1
  453. package/ts/integrations/shelly/readme.md +22 -7
  454. package/ts/integrations/shelly/shelly.classes.client.ts +386 -269
  455. package/ts/integrations/shelly/shelly.classes.configflow.ts +43 -38
  456. package/ts/integrations/shelly/shelly.classes.integration.ts +92 -111
  457. package/ts/integrations/shelly/shelly.classes.subscription.ts +24 -1
  458. package/ts/integrations/shelly/shelly.mapper.ts +19 -20
  459. package/ts/integrations/shelly/shelly.rpc.ts +2 -0
  460. package/ts/integrations/shelly/shelly.types.ts +50 -2
  461. package/ts/integrations/shelly/shelly.validation.ts +76 -0
  462. package/ts/integrations/sonos/readme.md +117 -38
  463. package/ts/integrations/sonos/sonos.classes.client.ts +392 -123
  464. package/ts/integrations/sonos/sonos.classes.configflow.ts +25 -28
  465. package/ts/integrations/sonos/sonos.classes.integration.ts +211 -186
  466. package/ts/integrations/sonos/sonos.config.ts +24 -2
  467. package/ts/integrations/sonos/sonos.mapper.ts +13 -8
  468. package/ts/integrations/sonos/sonos.matchers.ts +2 -2
  469. package/ts/integrations/sonos/sonos.types.ts +30 -1
  470. package/ts/integrations/soundtouch/soundtouch.classes.client.ts +152 -571
  471. package/ts/integrations/soundtouch/soundtouch.classes.configflow.ts +47 -42
  472. package/ts/integrations/soundtouch/soundtouch.classes.integration.ts +95 -150
  473. package/ts/integrations/soundtouch/soundtouch.discovery.ts +21 -133
  474. package/ts/integrations/soundtouch/soundtouch.mapper.ts +36 -207
  475. package/ts/integrations/soundtouch/soundtouch.types.ts +50 -195
  476. package/ts/integrations/soundtouch/soundtouch.validation.ts +60 -0
  477. package/ts/integrations/tasmota/readme.md +16 -5
  478. package/ts/integrations/tasmota/tasmota.classes.integration.ts +24 -6
  479. package/ts/integrations/tasmota/tasmota.classes.runtime.ts +112 -43
  480. package/ts/integrations/tasmota/tasmota.config.ts +17 -0
  481. package/ts/integrations/tasmota/tasmota.credentials.ts +92 -0
  482. package/ts/integrations/tasmota/tasmota.discovery.ts +87 -24
  483. package/ts/integrations/tasmota/tasmota.mapper.ts +6 -6
  484. package/ts/integrations/tasmota/tasmota.types.ts +43 -2
  485. package/ts/integrations/tuya/readme.md +52 -10
  486. package/ts/integrations/tuya/tuya.classes.integration.ts +69 -98
  487. package/ts/integrations/tuya/tuya.classes.runtime.ts +70 -24
  488. package/ts/integrations/tuya/tuya.mapper.ts +1 -1
  489. package/ts/integrations/tuya/tuya.types.ts +4 -0
  490. package/ts/integrations/tuya/tuya.validation.ts +5 -8
  491. package/ts/integrations/webostv/readme.md +115 -22
  492. package/ts/integrations/webostv/webostv.classes.client.ts +123 -50
  493. package/ts/integrations/webostv/webostv.classes.configflow.ts +35 -15
  494. package/ts/integrations/webostv/webostv.classes.integration.ts +44 -37
  495. package/ts/integrations/webostv/webostv.mapper.ts +4 -4
  496. package/ts/integrations/webostv/webostv.types.ts +18 -3
  497. package/ts/integrations/webostv/webostv.validation.ts +22 -1
  498. package/ts/integrations/wiz/index.ts +1 -0
  499. package/ts/integrations/wiz/wiz.classes.client.ts +84 -254
  500. package/ts/integrations/wiz/wiz.classes.configflow.ts +39 -70
  501. package/ts/integrations/wiz/wiz.classes.integration.ts +189 -45
  502. package/ts/integrations/wiz/wiz.discovery.ts +48 -291
  503. package/ts/integrations/wiz/wiz.mapper.ts +81 -754
  504. package/ts/integrations/wiz/wiz.types.ts +24 -224
  505. package/ts/integrations/wiz/wiz.validation.ts +73 -0
  506. package/ts/integrations/yamaha/index.ts +1 -0
  507. package/ts/integrations/yamaha/yamaha.classes.client.ts +150 -6
  508. package/ts/integrations/yamaha/yamaha.classes.configflow.ts +100 -5
  509. package/ts/integrations/yamaha/yamaha.classes.integration.ts +236 -8
  510. package/ts/integrations/yamaha/yamaha.discovery.ts +52 -3
  511. package/ts/integrations/yamaha/yamaha.mapper.ts +65 -13
  512. package/ts/integrations/yamaha/yamaha.types.ts +77 -97
  513. package/ts/integrations/yamaha/yamaha.validation.ts +86 -0
  514. package/ts/integrations/zigbee2mqtt/readme.md +22 -27
  515. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.ts +16 -7
  516. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.ts +53 -6
  517. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.ts +62 -49
  518. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.ts +17 -11
  519. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.types.ts +35 -2
  520. package/ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.ts +53 -7
  521. package/ts/integrations/zwave_js/readme.md +42 -9
  522. package/ts/integrations/zwave_js/zwave_js.classes.client.ts +155 -31
  523. package/ts/integrations/zwave_js/zwave_js.classes.configflow.ts +55 -31
  524. package/ts/integrations/zwave_js/zwave_js.classes.integration.ts +57 -35
  525. package/ts/integrations/zwave_js/zwave_js.discovery.ts +2 -2
  526. package/ts/integrations/zwave_js/zwave_js.mapper.ts +37 -23
  527. package/ts/integrations/zwave_js/zwave_js.types.ts +26 -3
  528. package/ts/integrations/zwave_js/zwave_js.validation.ts +52 -18
  529. package/ts/plugins.ts +2 -1
@@ -1,487 +1,84 @@
1
- import * as plugins from '../../plugins.js';
2
- import type { IIntegrationEntity, IIntegrationEvent, IServiceCallRequest } from '../../core/types.js';
3
- import type {
4
- IModbusCoilState,
5
- IModbusCommand,
6
- IModbusEntitySnapshot,
7
- IModbusEvent,
8
- IModbusHubSnapshot,
9
- IModbusRegisterState,
10
- IModbusSnapshot,
11
- TModbusCoilType,
12
- TModbusDataType,
13
- TModbusEntityPlatform,
14
- TModbusRegisterType,
15
- } from './modbus.types.js';
16
-
17
- const modbusDomain = 'modbus';
1
+ import type * as plugins from '../../plugins.js';
2
+ import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IServiceCallRequest } from '../../core/types.js';
3
+ import type { IModbusNormalizedConfig, IModbusObservation, IModbusSnapshot, TModbusCommand } from './modbus.types.js';
4
+ import { modbusCommand, modbusRecord } from './modbus.validation.js';
18
5
 
19
6
  export class ModbusMapper {
20
- public static toDevices(snapshotArg: IModbusSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
21
- const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
22
- const devices: plugins.shxInterfaces.data.IDeviceDefinition[] = [];
23
-
24
- for (const hub of snapshotArg.hubs) {
25
- devices.push({
26
- id: this.hubDeviceId(hub),
27
- integrationDomain: modbusDomain,
28
- name: hub.name,
29
- protocol: 'unknown',
30
- manufacturer: hub.manufacturer || 'Modbus',
31
- model: hub.model || `${hub.type.toUpperCase()} hub`,
32
- online: hub.online && !hub.unsupportedReason,
33
- features: [
34
- { id: 'connectivity', capability: 'sensor', name: 'Connectivity', readable: true, writable: false },
35
- { id: 'configured_entities', capability: 'sensor', name: 'Configured entities', readable: true, writable: false },
36
- ],
37
- state: [
38
- { featureId: 'connectivity', value: hub.online && !hub.unsupportedReason ? 'online' : 'offline', updatedAt },
39
- { featureId: 'configured_entities', value: hub.entities.length, updatedAt },
40
- ],
41
- metadata: this.cleanAttributes({
42
- type: hub.type,
43
- host: hub.host,
44
- port: hub.port,
45
- serialNumber: hub.serialNumber,
46
- unsupportedReason: hub.unsupportedReason,
47
- ...hub.metadata,
48
- }),
49
- });
50
-
51
- for (const slave of hub.slaves) {
52
- devices.push({
53
- id: this.slaveDeviceId(hub, slave.unitId),
54
- integrationDomain: modbusDomain,
55
- name: slave.name,
56
- protocol: 'unknown',
57
- manufacturer: slave.manufacturer || hub.manufacturer || 'Modbus',
58
- model: slave.model || 'Modbus slave',
59
- online: hub.online && slave.online && !hub.unsupportedReason,
60
- features: [
61
- { id: 'registers', capability: 'sensor', name: 'Configured registers', readable: true, writable: false },
62
- { id: 'coils', capability: 'sensor', name: 'Configured coils', readable: true, writable: false },
63
- ],
64
- state: [
65
- { featureId: 'registers', value: slave.registers.length, updatedAt },
66
- { featureId: 'coils', value: slave.coils.length, updatedAt },
67
- ],
68
- metadata: this.cleanAttributes({
69
- hubId: hub.id,
70
- hubName: hub.name,
71
- unitId: slave.unitId,
72
- viaDevice: this.hubDeviceId(hub),
73
- serialNumber: slave.serialNumber,
74
- ...slave.metadata,
75
- }),
76
- });
77
- }
78
- }
79
-
80
- return devices;
81
- }
82
-
83
- public static toEntities(snapshotArg: IModbusSnapshot): IIntegrationEntity[] {
84
- const usedIds = new Map<string, number>();
85
- return snapshotArg.hubs.flatMap((hubArg) => hubArg.entities.map((entityArg) => this.toEntity(hubArg, entityArg, usedIds)));
86
- }
87
-
88
- public static commandForService(snapshotArg: IModbusSnapshot, requestArg: IServiceCallRequest): IModbusCommand | undefined {
89
- const targetEntity = this.findEntity(snapshotArg, requestArg);
90
- if (requestArg.domain === modbusDomain && ['refresh', 'reload'].includes(requestArg.service)) {
91
- return { type: 'refresh', ...this.commandTarget(snapshotArg, requestArg, targetEntity) };
92
- }
93
- if (requestArg.domain === modbusDomain && requestArg.service === 'stop') {
94
- return { type: 'stop', ...this.commandTarget(snapshotArg, requestArg, targetEntity) };
95
- }
96
- if (requestArg.domain === modbusDomain && requestArg.service === 'restart') {
97
- return { type: 'restart', ...this.commandTarget(snapshotArg, requestArg, targetEntity) };
98
- }
99
-
100
- if (requestArg.domain === modbusDomain && ['read_register', 'read_holding_register', 'read_input_register'].includes(requestArg.service)) {
101
- const address = this.addressValue(requestArg, targetEntity);
102
- if (address === undefined) {
103
- return undefined;
104
- }
105
- return {
106
- type: 'read_register',
107
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
108
- address,
109
- count: this.numberData(requestArg, 'count') || targetEntity?.register?.count || 1,
110
- inputType: this.registerType(requestArg, targetEntity, requestArg.service === 'read_input_register' ? 'input' : undefined),
111
- dataType: this.dataType(requestArg, targetEntity),
112
- };
113
- }
114
-
115
- if (requestArg.domain === modbusDomain && ['read_coil', 'read_discrete_input'].includes(requestArg.service)) {
116
- const address = this.addressValue(requestArg, targetEntity);
117
- if (address === undefined) {
118
- return undefined;
119
- }
120
- return {
121
- type: 'read_coil',
122
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
123
- address,
124
- count: this.numberData(requestArg, 'count') || targetEntity?.coil?.count || 1,
125
- inputType: this.coilType(requestArg, targetEntity, requestArg.service === 'read_discrete_input' ? 'discrete_input' : undefined),
126
- };
127
- }
128
-
129
- if (requestArg.domain === modbusDomain && requestArg.service === 'write_register') {
130
- const address = this.addressValue(requestArg, targetEntity);
131
- const value = this.numberOrArrayData(requestArg, 'value');
132
- return address !== undefined && value !== undefined ? {
133
- type: 'write_register',
134
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
135
- address,
136
- value,
137
- } : undefined;
138
- }
139
-
140
- if (requestArg.domain === modbusDomain && requestArg.service === 'write_coil') {
141
- const address = this.addressValue(requestArg, targetEntity);
142
- const value = this.boolOrArrayData(requestArg, 'state') ?? this.boolOrArrayData(requestArg, 'value');
143
- return address !== undefined && value !== undefined ? {
144
- type: 'write_coil',
145
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
146
- address,
147
- value,
148
- } : undefined;
149
- }
150
-
151
- if (requestArg.domain === 'switch' && ['turn_on', 'turn_off'].includes(requestArg.service) && targetEntity?.platform === 'switch') {
152
- const commandValue = requestArg.service === 'turn_on' ? this.attributeNumber(targetEntity, 'commandOn') ?? 1 : this.attributeNumber(targetEntity, 'commandOff') ?? 0;
153
- const writeType = String(targetEntity.attributes?.writeType || 'coil');
154
- if (writeType === 'holding' || writeType === 'holdings' || targetEntity.register) {
155
- return {
156
- type: 'write_register',
157
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
158
- address: targetEntity.address,
159
- value: commandValue,
160
- };
161
- }
162
- return {
163
- type: 'write_coil',
164
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
165
- address: targetEntity.address,
166
- value: commandValue,
167
- };
168
- }
169
-
170
- if (requestArg.domain === 'number' && requestArg.service === 'set_value' && targetEntity?.platform === 'number') {
171
- const value = this.numberData(requestArg, 'value');
172
- return value !== undefined ? {
173
- type: 'write_register',
174
- ...this.commandTarget(snapshotArg, requestArg, targetEntity),
175
- address: targetEntity.address,
176
- value,
177
- } : undefined;
178
- }
179
-
180
- return undefined;
181
- }
182
-
183
- public static toIntegrationEvent(eventArg: IModbusEvent): IIntegrationEvent {
184
- return {
185
- type: eventArg.type === 'command_failed' ? 'error' : 'state_changed',
186
- integrationDomain: modbusDomain,
187
- deviceId: eventArg.deviceId,
188
- entityId: eventArg.entityId,
189
- data: eventArg,
190
- timestamp: eventArg.timestamp,
191
- };
192
- }
193
-
194
- public static hubDeviceId(hubArg: Pick<IModbusHubSnapshot, 'id'>): string {
195
- return `modbus.hub.${this.slug(hubArg.id)}`;
196
- }
197
-
198
- public static slaveDeviceId(hubArg: Pick<IModbusHubSnapshot, 'id'>, unitIdArg: number): string {
199
- return `modbus.slave.${this.slug(hubArg.id)}.${unitIdArg}`;
200
- }
201
-
202
- public static decodeRegisterValue(registerArg: IModbusRegisterState): number | string | number[] | null {
203
- if (registerArg.value !== undefined) {
204
- return registerArg.value;
205
- }
206
- const registers = registerArg.registers || [];
207
- if (!registers.length) {
208
- return null;
209
- }
210
- const dataType = this.normalizedDataType(registerArg.dataType);
211
- if (dataType === 'custom') {
212
- return registers;
213
- }
214
-
215
- const bytes = Buffer.alloc(registers.length * 2);
216
- registers.forEach((registerValueArg, indexArg) => bytes.writeUInt16BE(registerValueArg & 0xffff, indexArg * 2));
217
- let value: number | string;
218
- if (dataType === 'string') {
219
- value = bytes.toString('utf8').replace(/\0+$/g, '');
220
- } else if (dataType === 'int16') {
221
- value = bytes.readInt16BE(0);
222
- } else if (dataType === 'int32') {
223
- value = bytes.readInt32BE(0);
224
- } else if (dataType === 'uint32') {
225
- value = bytes.readUInt32BE(0);
226
- } else if (dataType === 'int64') {
227
- value = Number(bytes.readBigInt64BE(0));
228
- } else if (dataType === 'uint64') {
229
- value = Number(bytes.readBigUInt64BE(0));
230
- } else if (dataType === 'float16') {
231
- value = this.decodeFloat16(bytes.readUInt16BE(0));
232
- } else if (dataType === 'float32') {
233
- value = bytes.readFloatBE(0);
234
- } else if (dataType === 'float64') {
235
- value = bytes.readDoubleBE(0);
236
- } else {
237
- value = bytes.readUInt16BE(0);
238
- }
239
- return typeof value === 'number' ? this.processNumericValue(value, registerArg) : value;
240
- }
241
-
242
- public static registerCountForDataType(dataTypeArg: TModbusDataType | undefined): number {
243
- const dataType = this.normalizedDataType(dataTypeArg || 'int16');
244
- if (dataType === 'int32' || dataType === 'uint32' || dataType === 'float32') {
245
- return 2;
246
- }
247
- if (dataType === 'int64' || dataType === 'uint64' || dataType === 'float64') {
248
- return 4;
249
- }
250
- return 1;
251
- }
252
-
253
- private static toEntity(hubArg: IModbusHubSnapshot, entityArg: IModbusEntitySnapshot, usedIdsArg: Map<string, number>): IIntegrationEntity {
254
- const platform = entityArg.platform;
255
- const id = entityArg.id.includes('.') ? entityArg.id : this.uniqueEntityId(platform, entityArg.name, usedIdsArg);
256
- const state = this.entityState(entityArg);
257
- return {
258
- id,
259
- uniqueId: entityArg.uniqueId,
260
- integrationDomain: modbusDomain,
261
- deviceId: this.slaveDeviceId(hubArg, entityArg.unitId),
262
- platform,
263
- name: entityArg.name,
264
- state,
265
- attributes: this.cleanAttributes({
266
- hubId: hubArg.id,
267
- hubName: hubArg.name,
268
- unitId: entityArg.unitId,
269
- address: entityArg.address,
270
- writable: entityArg.writable,
271
- registerType: entityArg.register?.inputType,
272
- coilType: entityArg.coil?.inputType,
273
- dataType: entityArg.register?.dataType,
274
- count: entityArg.register?.count || entityArg.coil?.count,
275
- ...entityArg.attributes,
276
- }),
277
- available: entityArg.available && hubArg.online && !hubArg.unsupportedReason,
278
- };
279
- }
280
-
281
- private static entityState(entityArg: IModbusEntitySnapshot): unknown {
282
- if (entityArg.state !== undefined) {
283
- return entityArg.state;
284
- }
285
- if (entityArg.platform === 'sensor') {
286
- return entityArg.register ? this.decodeRegisterValue(entityArg.register) : null;
287
- }
288
- if (entityArg.platform === 'number') {
289
- const value = entityArg.register ? this.decodeRegisterValue(entityArg.register) : null;
290
- return typeof value === 'number' && Number.isFinite(value) ? value : null;
291
- }
292
- const boolValue = this.coilBoolean(entityArg.coil);
293
- return boolValue === undefined ? 'unknown' : boolValue ? 'on' : 'off';
294
- }
295
-
296
- private static coilBoolean(coilArg: IModbusCoilState | undefined): boolean | undefined {
297
- if (!coilArg) {
298
- return undefined;
299
- }
300
- if (typeof coilArg.value === 'boolean') {
301
- return coilArg.value;
302
- }
303
- if (typeof coilArg.value === 'number') {
304
- return Boolean(coilArg.value & 1);
305
- }
306
- if (coilArg.bits?.length) {
307
- return Boolean(coilArg.bits[0]);
308
- }
309
- return undefined;
310
- }
311
-
312
- private static uniqueEntityId(platformArg: TModbusEntityPlatform, nameArg: string, usedIdsArg: Map<string, number>): string {
313
- const baseId = `${platformArg}.${this.slug(nameArg)}`;
314
- const seen = usedIdsArg.get(baseId) || 0;
315
- usedIdsArg.set(baseId, seen + 1);
316
- return seen ? `${baseId}_${seen + 1}` : baseId;
317
- }
318
-
319
- private static findEntity(snapshotArg: IModbusSnapshot, requestArg: IServiceCallRequest): IModbusEntitySnapshot | undefined {
320
- const target = requestArg.target.entityId || requestArg.target.deviceId;
321
- if (!target) {
322
- return undefined;
323
- }
324
- for (const hub of snapshotArg.hubs) {
325
- const entity = hub.entities.find((entityArg) => entityArg.id === target || entityArg.uniqueId === target || this.slaveDeviceId(hub, entityArg.unitId) === target);
326
- if (entity) {
327
- return entity;
328
- }
329
- }
330
- return undefined;
331
- }
332
-
333
- private static commandTarget(snapshotArg: IModbusSnapshot, requestArg: IServiceCallRequest, entityArg?: IModbusEntitySnapshot): Pick<IModbusCommand, 'hub' | 'hubId' | 'unitId' | 'entityId' | 'deviceId' | 'uniqueId'> {
334
- const firstHub = snapshotArg.hubs[0];
335
- return {
336
- hub: this.stringData(requestArg, 'hub') || entityArg?.hubName || firstHub?.name,
337
- hubId: this.stringData(requestArg, 'hubId') || entityArg?.hubId || firstHub?.id,
338
- unitId: this.numberData(requestArg, 'unitId') ?? this.numberData(requestArg, 'unit') ?? this.numberData(requestArg, 'slave') ?? entityArg?.unitId ?? 1,
339
- entityId: requestArg.target.entityId,
340
- deviceId: requestArg.target.deviceId,
341
- uniqueId: entityArg?.uniqueId,
342
- };
343
- }
344
-
345
- private static addressValue(requestArg: IServiceCallRequest, entityArg?: IModbusEntitySnapshot): number | undefined {
346
- return this.numberData(requestArg, 'address') ?? entityArg?.address;
347
- }
348
-
349
- private static registerType(requestArg: IServiceCallRequest, entityArg?: IModbusEntitySnapshot, fallbackArg?: TModbusRegisterType): TModbusRegisterType {
350
- const value = this.stringData(requestArg, 'inputType') || this.stringData(requestArg, 'input_type') || this.stringData(requestArg, 'registerType') || this.stringData(requestArg, 'register_type') || entityArg?.register?.inputType || fallbackArg || 'holding';
351
- return value === 'input' ? 'input' : 'holding';
352
- }
353
-
354
- private static coilType(requestArg: IServiceCallRequest, entityArg?: IModbusEntitySnapshot, fallbackArg?: TModbusCoilType): TModbusCoilType {
355
- const value = this.stringData(requestArg, 'inputType') || this.stringData(requestArg, 'input_type') || this.stringData(requestArg, 'coilType') || this.stringData(requestArg, 'coil_type') || entityArg?.coil?.inputType || fallbackArg || 'coil';
356
- return value === 'discrete_input' ? 'discrete_input' : 'coil';
357
- }
358
-
359
- private static dataType(requestArg: IServiceCallRequest, entityArg?: IModbusEntitySnapshot): TModbusDataType | undefined {
360
- const value = this.stringData(requestArg, 'dataType') || this.stringData(requestArg, 'data_type') || entityArg?.register?.dataType;
361
- return value as TModbusDataType | undefined;
362
- }
363
-
364
- private static numberData(requestArg: IServiceCallRequest, keyArg: string): number | undefined {
365
- const value = requestArg.data?.[keyArg];
366
- return this.toNumber(value);
367
- }
368
-
369
- private static attributeNumber(entityArg: IModbusEntitySnapshot, keyArg: string): number | undefined {
370
- return this.toNumber(entityArg.attributes?.[keyArg]);
371
- }
372
-
373
- private static toNumber(valueArg: unknown): number | undefined {
374
- return typeof valueArg === 'number' && Number.isFinite(valueArg) ? valueArg : typeof valueArg === 'string' && valueArg.trim() && Number.isFinite(Number(valueArg)) ? Number(valueArg) : undefined;
375
- }
376
-
377
- private static stringData(requestArg: IServiceCallRequest, keyArg: string): string | undefined {
378
- const value = requestArg.data?.[keyArg];
379
- return typeof value === 'string' && value.trim() ? value.trim() : undefined;
380
- }
381
-
382
- private static numberOrArrayData(requestArg: IServiceCallRequest, keyArg: string): number | number[] | undefined {
383
- const value = requestArg.data?.[keyArg];
384
- if (Array.isArray(value)) {
385
- const values = value.map((entryArg) => this.toNumber(entryArg)).filter((entryArg): entryArg is number => entryArg !== undefined);
386
- return values.length === value.length ? values : undefined;
387
- }
388
- return this.toNumber(value);
7
+ public static deviceId(configArg: IModbusNormalizedConfig): string {
8
+ return `modbus:${encodeURIComponent(configArg.homeId)}:${configArg.address}:${configArg.port}:${configArg.unitId}`;
389
9
  }
390
10
 
391
- private static boolOrArrayData(requestArg: IServiceCallRequest, keyArg: string): boolean | boolean[] | number | number[] | undefined {
392
- const value = requestArg.data?.[keyArg];
393
- if (Array.isArray(value)) {
394
- const values = value.map((entryArg) => this.toBooleanOrNumber(entryArg)).filter((entryArg): entryArg is boolean | number => entryArg !== undefined);
395
- return values.length === value.length ? values.map((entryArg) => typeof entryArg === 'boolean' ? entryArg : Boolean(entryArg)) : undefined;
396
- }
397
- return this.toBooleanOrNumber(value);
11
+ public static entityId(configArg: IModbusNormalizedConfig, mappingIdArg: string): string {
12
+ return `${this.deviceId(configArg)}:${mappingIdArg}`;
398
13
  }
399
14
 
400
- private static toBooleanOrNumber(valueArg: unknown): boolean | number | undefined {
401
- if (typeof valueArg === 'boolean') {
402
- return valueArg;
403
- }
404
- if (typeof valueArg === 'number' && Number.isFinite(valueArg)) {
405
- return valueArg;
406
- }
407
- if (typeof valueArg === 'string') {
408
- const value = valueArg.trim().toLowerCase();
409
- if (value === 'true' || value === 'on') {
410
- return true;
411
- }
412
- if (value === 'false' || value === 'off') {
413
- return false;
414
- }
415
- if (value && Number.isFinite(Number(value))) {
416
- return Number(value);
15
+ public static toDevices(snapshotArg: IModbusSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
16
+ const features: plugins.shxInterfaces.data.IDeviceFeature[] = [];
17
+ const state: plugins.shxInterfaces.data.IDeviceState[] = [];
18
+ for (const observation of snapshotArg.observations) {
19
+ const mapping = observation.mapping;
20
+ for (let index = 0; index < observation.values.length; index++) {
21
+ const id = mapping.quantity === 1 ? mapping.id : `${mapping.id}:${index}`;
22
+ features.push({ id, name: mapping.quantity === 1 ? mapping.name : `${mapping.name} [${index}]`, capability: 'sensor',
23
+ readable: true, writable: mapping.quantity === 1 && this.writable(observation) });
24
+ state.push({ featureId: id, value: observation.values[index], updatedAt: observation.observedAt });
417
25
  }
418
26
  }
419
- return undefined;
27
+ return [{ id: this.deviceId(snapshotArg.config), integrationDomain: 'modbus', protocol: 'tcp',
28
+ name: snapshotArg.config.name ?? snapshotArg.identity.productCode, manufacturer: snapshotArg.identity.vendorName,
29
+ model: snapshotArg.identity.productCode, features, state, online: true, metadata: {
30
+ homeId: snapshotArg.config.homeId, address: snapshotArg.config.address, port: snapshotArg.config.port,
31
+ unitId: snapshotArg.config.unitId, revision: snapshotArg.identity.revision, observedAt: snapshotArg.observedAt,
32
+ networkAuthenticated: false, physicalEffectConfirmed: false, interpretation: 'raw-modbus-values',
33
+ } }];
420
34
  }
421
35
 
422
- private static normalizedDataType(dataTypeArg: TModbusDataType): Exclude<TModbusDataType, 'int' | 'integer' | 'uint' | 'float'> {
423
- if (dataTypeArg === 'int' || dataTypeArg === 'integer') {
424
- return 'int16';
425
- }
426
- if (dataTypeArg === 'uint') {
427
- return 'uint16';
428
- }
429
- if (dataTypeArg === 'float') {
430
- return 'float32';
431
- }
432
- return dataTypeArg;
36
+ public static toEntities(snapshotArg: IModbusSnapshot): IIntegrationEntity[] {
37
+ return snapshotArg.observations.map((observation) => {
38
+ const mapping = observation.mapping;
39
+ const bit = mapping.kind === 'coil' || mapping.kind === 'discrete_input';
40
+ const writable = this.writable(observation);
41
+ return { id: this.entityId(snapshotArg.config, mapping.id), uniqueId: this.entityId(snapshotArg.config, mapping.id),
42
+ deviceId: this.deviceId(snapshotArg.config), integrationDomain: 'modbus',
43
+ platform: bit ? writable ? 'switch' : 'binary_sensor' : writable ? 'number' : 'sensor',
44
+ name: mapping.name, state: mapping.quantity === 1 ? observation.values[0] : observation.values, available: true,
45
+ attributes: { homeId: snapshotArg.config.homeId, kind: mapping.kind, address: mapping.address, quantity: mapping.quantity,
46
+ writable, ...(mapping.kind === 'holding' && mapping.write ? { minimum: mapping.write.minimum, maximum: mapping.write.maximum } : {}),
47
+ observedAt: observation.observedAt, interpretation: 'raw-modbus-values', networkAuthenticated: false, physicalEffectConfirmed: false },
48
+ };
49
+ });
433
50
  }
434
51
 
435
- private static decodeFloat16(valueArg: number): number {
436
- const sign = (valueArg & 0x8000) ? -1 : 1;
437
- const exponent = (valueArg >> 10) & 0x1f;
438
- const fraction = valueArg & 0x03ff;
439
- if (exponent === 0) {
440
- return sign * Math.pow(2, -14) * (fraction / 1024);
441
- }
442
- if (exponent === 31) {
443
- return fraction ? Number.NaN : sign * Number.POSITIVE_INFINITY;
52
+ public static commandForService(configArg: IModbusNormalizedConfig, requestArg: IServiceCallRequest): TModbusCommand {
53
+ const request = modbusRecord(requestArg, ['domain', 'service', 'target', 'data']);
54
+ const target = modbusRecord(request.target, ['deviceId', 'entityId']);
55
+ if (target.deviceId !== undefined && target.deviceId !== this.deviceId(configArg)) throw new TypeError('Modbus service device is outside the selected home and device.');
56
+ const mapping = configArg.mappings.find((entry) => this.entityId(configArg, entry.id) === target.entityId);
57
+ if (!mapping) throw new TypeError('Modbus services require one exact mapped entity target.');
58
+ if (request.domain !== 'modbus') throw new TypeError('Modbus raw services use the modbus domain.');
59
+ if (request.service === 'read') {
60
+ if (request.data !== undefined) modbusRecord(request.data, []);
61
+ return modbusCommand({ type: 'read', mappingId: mapping.id }, configArg);
444
62
  }
445
- return sign * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
63
+ const data = modbusRecord(request.data, ['value']);
64
+ return modbusCommand({ type: request.service, mappingId: mapping.id, value: data.value }, configArg);
446
65
  }
447
66
 
448
- private static processNumericValue(valueArg: number, registerArg: IModbusRegisterState): number | null {
449
- const metadata = registerArg.metadata || {};
450
- const nanValue = this.toNumberValue(metadata.nanValue) ?? this.toNumberValue(metadata.nan_value);
451
- if (nanValue !== undefined && (valueArg === nanValue || valueArg === -nanValue)) {
452
- return null;
453
- }
454
- if (Number.isNaN(valueArg)) {
455
- return null;
67
+ public static commandForFeature(configArg: IModbusNormalizedConfig, requestArg: IDeviceFeatureWriteRequest): TModbusCommand {
68
+ const request = modbusRecord(requestArg, ['device', 'feature', 'value']);
69
+ const device = modbusRecord(request.device);
70
+ const feature = modbusRecord(request.feature);
71
+ const metadata = modbusRecord(device.metadata);
72
+ if (device.id !== this.deviceId(configArg) || device.integrationDomain !== 'modbus' || metadata.homeId !== configArg.homeId) {
73
+ throw new TypeError('Modbus feature writes require the exact owned home and device.');
456
74
  }
457
- const scale = this.toNumberValue(metadata.scale) ?? 1;
458
- const offset = this.toNumberValue(metadata.offset) ?? 0;
459
- let value = valueArg * scale + offset;
460
- const min = this.toNumberValue(metadata.minValue) ?? this.toNumberValue(metadata.min_value);
461
- const max = this.toNumberValue(metadata.maxValue) ?? this.toNumberValue(metadata.max_value);
462
- const zeroSuppress = this.toNumberValue(metadata.zeroSuppress) ?? this.toNumberValue(metadata.zero_suppress);
463
- const precision = this.toNumberValue(metadata.precision);
464
- if (min !== undefined && value < min) {
465
- value = min;
466
- }
467
- if (max !== undefined && value > max) {
468
- value = max;
469
- }
470
- if (zeroSuppress !== undefined && Math.abs(value) <= zeroSuppress) {
471
- value = 0;
472
- }
473
- return precision !== undefined ? Number(value.toFixed(precision)) : value;
474
- }
475
-
476
- private static toNumberValue(valueArg: unknown): number | undefined {
477
- return typeof valueArg === 'number' && Number.isFinite(valueArg) ? valueArg : typeof valueArg === 'string' && valueArg.trim() && Number.isFinite(Number(valueArg)) ? Number(valueArg) : undefined;
478
- }
479
-
480
- private static cleanAttributes(attributesArg: Record<string, unknown>): Record<string, unknown> {
481
- return Object.fromEntries(Object.entries(attributesArg).filter(([, valueArg]) => valueArg !== undefined));
75
+ const mapping = configArg.mappings.find((entry) => entry.id === feature.id);
76
+ if (!mapping) throw new TypeError('Modbus feature is outside the explicit owner mapping.');
77
+ return modbusCommand({ type: mapping.kind === 'coil' ? 'write_coil' : 'write_register', mappingId: mapping.id, value: request.value }, configArg);
482
78
  }
483
79
 
484
- private static slug(valueArg: string): string {
485
- return valueArg.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '') || modbusDomain;
80
+ private static writable(observationArg: IModbusObservation): boolean {
81
+ const mapping = observationArg.mapping;
82
+ return mapping.kind === 'coil' && mapping.write === true || mapping.kind === 'holding' && mapping.write !== undefined;
486
83
  }
487
84
  }