@smarthome.exchange/integrations 0.1.0 → 1.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.
- package/changelog.md +131 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/cli/classes.cliruntime.d.ts +1 -1
- package/dist_ts/cli/commands.discover.js +1 -1
- package/dist_ts/cli/commands.setup.d.ts +1 -1
- package/dist_ts/core/classes.configrecord.d.ts +15 -0
- package/dist_ts/core/classes.configrecord.js +93 -0
- package/dist_ts/core/classes.configstore.d.ts +38 -10
- package/dist_ts/core/classes.configstore.js +298 -32
- package/dist_ts/core/classes.discoveryengine.js +12 -2
- package/dist_ts/core/classes.runtimemanager.d.ts +6 -2
- package/dist_ts/core/classes.runtimemanager.js +74 -39
- package/dist_ts/core/classes.simplelocalintegration.js +1 -1
- package/dist_ts/core/errors.d.ts +2 -2
- package/dist_ts/core/errors.js +1 -1
- package/dist_ts/core/types.d.ts +13 -4
- package/dist_ts/index.d.ts +4 -1
- package/dist_ts/index.js +7 -1
- package/dist_ts/integrations/adguard/adguard.classes.client.js +1 -1
- package/dist_ts/integrations/adguard/adguard.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/adguard/adguard.classes.integration.js +1 -1
- package/dist_ts/integrations/adguard/adguard.discovery.d.ts +1 -1
- package/dist_ts/integrations/adguard/adguard.mapper.js +1 -1
- package/dist_ts/integrations/agent_dvr/agent_dvr.classes.client.js +1 -1
- package/dist_ts/integrations/agent_dvr/agent_dvr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/agent_dvr/agent_dvr.classes.integration.js +1 -1
- package/dist_ts/integrations/agent_dvr/agent_dvr.discovery.d.ts +3 -3
- package/dist_ts/integrations/agent_dvr/agent_dvr.mapper.js +1 -1
- package/dist_ts/integrations/agent_dvr/agent_dvr.types.d.ts +1 -1
- package/dist_ts/integrations/airgradient/airgradient.classes.client.js +1 -1
- package/dist_ts/integrations/airgradient/airgradient.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/airgradient/airgradient.classes.integration.js +1 -1
- package/dist_ts/integrations/airgradient/airgradient.discovery.d.ts +2 -2
- package/dist_ts/integrations/airos/airos.classes.client.js +1 -1
- package/dist_ts/integrations/airos/airos.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/airos/airos.classes.integration.js +1 -1
- package/dist_ts/integrations/airos/airos.discovery.d.ts +4 -4
- package/dist_ts/integrations/airos/airos.discovery.js +1 -1
- package/dist_ts/integrations/airos/airos.mapper.js +1 -1
- package/dist_ts/integrations/amcrest/amcrest.classes.client.js +1 -1
- package/dist_ts/integrations/amcrest/amcrest.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/amcrest/amcrest.classes.integration.js +1 -1
- package/dist_ts/integrations/amcrest/amcrest.discovery.d.ts +3 -3
- package/dist_ts/integrations/amcrest/amcrest.types.d.ts +5 -5
- package/dist_ts/integrations/android_ip_webcam/android_ip_webcam.classes.client.js +1 -1
- package/dist_ts/integrations/android_ip_webcam/android_ip_webcam.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/android_ip_webcam/android_ip_webcam.classes.integration.js +1 -1
- package/dist_ts/integrations/android_ip_webcam/android_ip_webcam.discovery.d.ts +1 -1
- package/dist_ts/integrations/androidtv/androidtv.classes.client.js +1 -1
- package/dist_ts/integrations/androidtv/androidtv.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/androidtv/androidtv.classes.integration.js +1 -1
- package/dist_ts/integrations/androidtv/androidtv.discovery.d.ts +3 -3
- package/dist_ts/integrations/androidtv_remote/androidtv_remote.classes.client.js +1 -1
- package/dist_ts/integrations/androidtv_remote/androidtv_remote.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/androidtv_remote/androidtv_remote.classes.integration.js +1 -1
- package/dist_ts/integrations/androidtv_remote/androidtv_remote.discovery.d.ts +2 -2
- package/dist_ts/integrations/apcupsd/apcupsd.classes.client.js +1 -1
- package/dist_ts/integrations/apcupsd/apcupsd.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/apcupsd/apcupsd.classes.integration.js +1 -1
- package/dist_ts/integrations/apcupsd/apcupsd.discovery.d.ts +1 -1
- package/dist_ts/integrations/apcupsd/apcupsd.mapper.js +1 -1
- package/dist_ts/integrations/arcam_fmj/arcam_fmj.classes.client.js +1 -1
- package/dist_ts/integrations/arcam_fmj/arcam_fmj.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/arcam_fmj/arcam_fmj.classes.integration.js +1 -1
- package/dist_ts/integrations/arcam_fmj/arcam_fmj.discovery.d.ts +2 -2
- package/dist_ts/integrations/asuswrt/asuswrt.classes.client.js +1 -1
- package/dist_ts/integrations/asuswrt/asuswrt.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/asuswrt/asuswrt.classes.integration.js +1 -1
- package/dist_ts/integrations/asuswrt/asuswrt.discovery.d.ts +1 -1
- package/dist_ts/integrations/asuswrt/asuswrt.mapper.js +1 -1
- package/dist_ts/integrations/axis/axis.classes.client.js +1 -1
- package/dist_ts/integrations/axis/axis.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/axis/axis.classes.integration.js +1 -1
- package/dist_ts/integrations/axis/axis.discovery.d.ts +3 -3
- package/dist_ts/integrations/blebox/blebox.classes.client.js +1 -1
- package/dist_ts/integrations/blebox/blebox.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/blebox/blebox.classes.integration.js +1 -1
- package/dist_ts/integrations/blebox/blebox.discovery.d.ts +2 -2
- package/dist_ts/integrations/bluesound/bluesound.classes.client.d.ts +9 -4
- package/dist_ts/integrations/bluesound/bluesound.classes.client.js +1 -1
- package/dist_ts/integrations/bluesound/bluesound.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/bluesound/bluesound.classes.integration.js +1 -1
- package/dist_ts/integrations/bluesound/bluesound.discovery.d.ts +2 -2
- package/dist_ts/integrations/bluetooth_le_tracker/bluetooth_le_tracker.classes.client.js +1 -1
- package/dist_ts/integrations/bluetooth_le_tracker/bluetooth_le_tracker.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/bluetooth_le_tracker/bluetooth_le_tracker.classes.integration.js +1 -1
- package/dist_ts/integrations/bluetooth_le_tracker/bluetooth_le_tracker.discovery.d.ts +2 -2
- package/dist_ts/integrations/bluetooth_le_tracker/bluetooth_le_tracker.mapper.js +1 -1
- package/dist_ts/integrations/bond/bond.classes.client.js +1 -1
- package/dist_ts/integrations/bond/bond.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/bond/bond.classes.integration.js +1 -1
- package/dist_ts/integrations/bond/bond.discovery.d.ts +3 -3
- package/dist_ts/integrations/bond/bond.mapper.js +1 -1
- package/dist_ts/integrations/bond/bond.types.d.ts +71 -71
- package/dist_ts/integrations/bosch_shc/bosch_shc.classes.client.js +1 -1
- package/dist_ts/integrations/bosch_shc/bosch_shc.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/bosch_shc/bosch_shc.classes.integration.js +1 -1
- package/dist_ts/integrations/bosch_shc/bosch_shc.discovery.d.ts +2 -2
- package/dist_ts/integrations/bosch_shc/bosch_shc.mapper.js +1 -1
- package/dist_ts/integrations/braviatv/braviatv.classes.client.js +1 -1
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +1 -1
- package/dist_ts/integrations/braviatv/braviatv.discovery.d.ts +3 -3
- package/dist_ts/integrations/broadlink/broadlink.classes.client.js +1 -1
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +1 -1
- package/dist_ts/integrations/broadlink/broadlink.discovery.d.ts +3 -3
- package/dist_ts/integrations/broadlink/broadlink.mapper.js +1 -1
- package/dist_ts/integrations/broadlink/broadlink.packet.d.ts +2 -2
- package/dist_ts/integrations/broadlink/broadlink.packet.js +1 -1
- package/dist_ts/integrations/brother/brother.classes.client.js +1 -1
- package/dist_ts/integrations/brother/brother.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/brother/brother.classes.integration.js +1 -1
- package/dist_ts/integrations/brother/brother.constants.d.ts +12 -12
- package/dist_ts/integrations/brother/brother.discovery.d.ts +2 -2
- package/dist_ts/integrations/brother/brother.mapper.js +1 -1
- package/dist_ts/integrations/cast/cast.classes.client.js +1 -1
- package/dist_ts/integrations/cast/cast.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/cast/cast.classes.integration.js +1 -1
- package/dist_ts/integrations/cast/cast.discovery.d.ts +2 -2
- package/dist_ts/integrations/channels/channels.classes.client.js +1 -1
- package/dist_ts/integrations/channels/channels.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/channels/channels.classes.integration.js +1 -1
- package/dist_ts/integrations/channels/channels.discovery.d.ts +2 -2
- package/dist_ts/integrations/cisco_ios/cisco_ios.classes.client.js +1 -1
- package/dist_ts/integrations/cisco_ios/cisco_ios.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/cisco_ios/cisco_ios.classes.integration.js +1 -1
- package/dist_ts/integrations/cisco_ios/cisco_ios.discovery.d.ts +2 -2
- package/dist_ts/integrations/cisco_ios/cisco_ios.mapper.js +1 -1
- package/dist_ts/integrations/daikin/daikin.classes.client.js +1 -1
- package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/daikin/daikin.classes.integration.js +1 -1
- package/dist_ts/integrations/daikin/daikin.discovery.d.ts +5 -5
- package/dist_ts/integrations/daikin/daikin.mapper.js +1 -1
- package/dist_ts/integrations/ddwrt/ddwrt.classes.client.js +1 -1
- package/dist_ts/integrations/ddwrt/ddwrt.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/ddwrt/ddwrt.classes.integration.js +1 -1
- package/dist_ts/integrations/ddwrt/ddwrt.discovery.d.ts +3 -3
- package/dist_ts/integrations/ddwrt/ddwrt.mapper.js +1 -1
- package/dist_ts/integrations/deconz/deconz.classes.client.d.ts +31 -22
- package/dist_ts/integrations/deconz/deconz.classes.client.js +302 -153
- package/dist_ts/integrations/deconz/deconz.classes.configflow.js +43 -26
- package/dist_ts/integrations/deconz/deconz.classes.integration.d.ts +3 -1
- package/dist_ts/integrations/deconz/deconz.classes.integration.js +133 -20
- package/dist_ts/integrations/deconz/deconz.discovery.d.ts +4 -4
- package/dist_ts/integrations/deconz/deconz.mapper.d.ts +2 -1
- package/dist_ts/integrations/deconz/deconz.mapper.js +23 -18
- package/dist_ts/integrations/deconz/deconz.types.d.ts +34 -3
- package/dist_ts/integrations/deconz/deconz.validation.d.ts +14 -0
- package/dist_ts/integrations/deconz/deconz.validation.js +269 -0
- package/dist_ts/integrations/deluge/deluge.classes.client.js +1 -1
- package/dist_ts/integrations/deluge/deluge.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/deluge/deluge.classes.integration.js +1 -1
- package/dist_ts/integrations/deluge/deluge.discovery.d.ts +2 -2
- package/dist_ts/integrations/denon/denon.classes.client.js +1 -1
- package/dist_ts/integrations/denon/denon.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/denon/denon.classes.integration.js +1 -1
- package/dist_ts/integrations/denon/denon.discovery.d.ts +1 -1
- package/dist_ts/integrations/denonavr/denonavr.classes.client.js +1 -1
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +1 -1
- package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +3 -3
- package/dist_ts/integrations/devolo_home_network/devolo_home_network.classes.client.js +1 -1
- package/dist_ts/integrations/devolo_home_network/devolo_home_network.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/devolo_home_network/devolo_home_network.classes.integration.js +1 -1
- package/dist_ts/integrations/devolo_home_network/devolo_home_network.discovery.d.ts +3 -3
- package/dist_ts/integrations/devolo_home_network/devolo_home_network.mapper.js +1 -1
- package/dist_ts/integrations/directv/directv.classes.client.js +1 -1
- package/dist_ts/integrations/directv/directv.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/directv/directv.classes.integration.js +1 -1
- package/dist_ts/integrations/directv/directv.discovery.d.ts +2 -2
- package/dist_ts/integrations/directv/directv.types.d.ts +1 -1
- package/dist_ts/integrations/dlink/dlink.classes.client.d.ts +6 -3
- package/dist_ts/integrations/dlink/dlink.classes.client.js +1 -1
- package/dist_ts/integrations/dlink/dlink.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/dlink/dlink.classes.integration.js +1 -1
- package/dist_ts/integrations/dlink/dlink.discovery.d.ts +2 -2
- package/dist_ts/integrations/dlink/dlink.mapper.js +1 -1
- package/dist_ts/integrations/dlna_dmr/dlna_dmr.classes.client.js +1 -1
- package/dist_ts/integrations/dlna_dmr/dlna_dmr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/dlna_dmr/dlna_dmr.classes.integration.js +1 -1
- package/dist_ts/integrations/dlna_dmr/dlna_dmr.discovery.d.ts +2 -2
- package/dist_ts/integrations/dlna_dms/dlna_dms.classes.client.js +1 -1
- package/dist_ts/integrations/dlna_dms/dlna_dms.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/dlna_dms/dlna_dms.classes.integration.js +1 -1
- package/dist_ts/integrations/dlna_dms/dlna_dms.discovery.d.ts +2 -2
- package/dist_ts/integrations/doorbird/doorbird.classes.client.js +1 -1
- package/dist_ts/integrations/doorbird/doorbird.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/doorbird/doorbird.classes.integration.js +1 -1
- package/dist_ts/integrations/doorbird/doorbird.discovery.d.ts +2 -2
- package/dist_ts/integrations/dsmr/dsmr.classes.client.js +1 -1
- package/dist_ts/integrations/dsmr/dsmr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/dsmr/dsmr.classes.integration.js +1 -1
- package/dist_ts/integrations/dsmr/dsmr.discovery.d.ts +1 -1
- package/dist_ts/integrations/dsmr/dsmr.parser.js +1 -1
- package/dist_ts/integrations/dunehd/dunehd.classes.client.js +1 -1
- package/dist_ts/integrations/dunehd/dunehd.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/dunehd/dunehd.classes.integration.js +1 -1
- package/dist_ts/integrations/dunehd/dunehd.discovery.d.ts +3 -3
- package/dist_ts/integrations/edimax/edimax.classes.client.js +1 -1
- package/dist_ts/integrations/edl21/edl21.classes.client.js +1 -1
- package/dist_ts/integrations/egardia/egardia.classes.client.js +1 -1
- package/dist_ts/integrations/elgato/elgato.classes.client.js +1 -1
- package/dist_ts/integrations/elgato/elgato.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/elgato/elgato.classes.integration.js +1 -1
- package/dist_ts/integrations/elgato/elgato.discovery.d.ts +3 -3
- package/dist_ts/integrations/emby/emby.classes.client.js +1 -1
- package/dist_ts/integrations/emby/emby.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/emby/emby.classes.integration.js +1 -1
- package/dist_ts/integrations/emby/emby.discovery.d.ts +3 -3
- package/dist_ts/integrations/emoncms_history/emoncms_history.classes.client.js +1 -1
- package/dist_ts/integrations/emonitor/emonitor.classes.client.js +1 -1
- package/dist_ts/integrations/emulated_hue/emulated_hue.classes.client.js +1 -1
- package/dist_ts/integrations/emulated_kasa/emulated_kasa.classes.client.js +1 -1
- package/dist_ts/integrations/emulated_roku/emulated_roku.classes.client.js +1 -1
- package/dist_ts/integrations/energenie_power_sockets/energenie_power_sockets.classes.client.js +1 -1
- package/dist_ts/integrations/enigma2/enigma2.classes.client.js +1 -1
- package/dist_ts/integrations/enocean/enocean.classes.client.js +1 -1
- package/dist_ts/integrations/esphome/esphome.classes.client.d.ts +35 -18
- package/dist_ts/integrations/esphome/esphome.classes.client.js +267 -77
- package/dist_ts/integrations/esphome/esphome.classes.configflow.js +2 -4
- package/dist_ts/integrations/esphome/esphome.classes.integration.d.ts +22 -11
- package/dist_ts/integrations/esphome/esphome.classes.integration.js +68 -61
- package/dist_ts/integrations/esphome/esphome.discovery.d.ts +2 -2
- package/dist_ts/integrations/esphome/esphome.discovery.js +2 -2
- package/dist_ts/integrations/esphome/esphome.mapper.d.ts +1 -2
- package/dist_ts/integrations/esphome/esphome.mapper.js +79 -36
- package/dist_ts/integrations/esphome/esphome.types.d.ts +2 -0
- package/dist_ts/integrations/fibaro/fibaro.classes.client.js +1 -1
- package/dist_ts/integrations/file/file.classes.client.js +1 -1
- package/dist_ts/integrations/filesize/filesize.classes.client.js +1 -1
- package/dist_ts/integrations/flexit_bacnet/flexit_bacnet.classes.client.js +1 -1
- package/dist_ts/integrations/flic/flic.classes.client.js +1 -1
- package/dist_ts/integrations/flux_led/flux_led.classes.client.js +1 -1
- package/dist_ts/integrations/folder/folder.classes.client.js +1 -1
- package/dist_ts/integrations/folder_watcher/folder_watcher.classes.client.js +1 -1
- package/dist_ts/integrations/forked_daapd/forked_daapd.classes.client.js +1 -1
- package/dist_ts/integrations/forked_daapd/forked_daapd.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/forked_daapd/forked_daapd.classes.integration.js +1 -1
- package/dist_ts/integrations/forked_daapd/forked_daapd.discovery.d.ts +2 -2
- package/dist_ts/integrations/foscam/foscam.classes.client.js +1 -1
- package/dist_ts/integrations/foscam/foscam.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/foscam/foscam.classes.integration.js +1 -1
- package/dist_ts/integrations/foscam/foscam.discovery.d.ts +3 -3
- package/dist_ts/integrations/foscam/foscam.types.d.ts +2 -2
- package/dist_ts/integrations/freebox/freebox.classes.client.js +1 -1
- package/dist_ts/integrations/freebox/freebox.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/freebox/freebox.classes.integration.js +1 -1
- package/dist_ts/integrations/freebox/freebox.discovery.d.ts +2 -2
- package/dist_ts/integrations/freebox/freebox.mapper.js +1 -1
- package/dist_ts/integrations/freebox/freebox.types.d.ts +11 -11
- package/dist_ts/integrations/fritz/fritz.classes.client.js +1 -1
- package/dist_ts/integrations/fritz/fritz.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/fritz/fritz.classes.integration.js +1 -1
- package/dist_ts/integrations/fritz/fritz.discovery.d.ts +3 -3
- package/dist_ts/integrations/fritz/fritz.mapper.js +1 -1
- package/dist_ts/integrations/fritzbox_callmonitor/fritzbox_callmonitor.classes.client.js +1 -1
- package/dist_ts/integrations/fritzbox_callmonitor/fritzbox_callmonitor.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/fritzbox_callmonitor/fritzbox_callmonitor.classes.integration.js +1 -1
- package/dist_ts/integrations/fritzbox_callmonitor/fritzbox_callmonitor.discovery.d.ts +3 -3
- package/dist_ts/integrations/fritzbox_callmonitor/fritzbox_callmonitor.mapper.js +1 -1
- package/dist_ts/integrations/fronius/fronius.classes.client.js +1 -1
- package/dist_ts/integrations/fronius/fronius.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/fronius/fronius.classes.integration.js +1 -1
- package/dist_ts/integrations/fronius/fronius.discovery.d.ts +2 -2
- package/dist_ts/integrations/fronius/fronius.mapper.js +1 -1
- package/dist_ts/integrations/frontier_silicon/frontier_silicon.classes.client.js +1 -1
- package/dist_ts/integrations/frontier_silicon/frontier_silicon.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/frontier_silicon/frontier_silicon.classes.integration.js +1 -1
- package/dist_ts/integrations/frontier_silicon/frontier_silicon.discovery.d.ts +2 -2
- package/dist_ts/integrations/fully_kiosk/fully_kiosk.classes.client.js +1 -1
- package/dist_ts/integrations/fully_kiosk/fully_kiosk.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/fully_kiosk/fully_kiosk.classes.integration.js +1 -1
- package/dist_ts/integrations/fully_kiosk/fully_kiosk.discovery.d.ts +2 -2
- package/dist_ts/integrations/fully_kiosk/fully_kiosk.mapper.js +1 -1
- package/dist_ts/integrations/generated/index.d.ts +1 -1
- package/dist_ts/integrations/generated/index.js +5 -7
- package/dist_ts/integrations/generic/generic.classes.client.js +1 -1
- package/dist_ts/integrations/geniushub/geniushub.classes.client.js +1 -1
- package/dist_ts/integrations/glances/glances.classes.client.js +1 -1
- package/dist_ts/integrations/glances/glances.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/glances/glances.classes.integration.js +1 -1
- package/dist_ts/integrations/glances/glances.discovery.d.ts +2 -2
- package/dist_ts/integrations/go2rtc/go2rtc.classes.client.js +1 -1
- package/dist_ts/integrations/go2rtc/go2rtc.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/go2rtc/go2rtc.classes.integration.js +1 -1
- package/dist_ts/integrations/go2rtc/go2rtc.discovery.d.ts +2 -2
- package/dist_ts/integrations/go2rtc/go2rtc.mapper.js +1 -1
- package/dist_ts/integrations/goalzero/goalzero.classes.client.js +1 -1
- package/dist_ts/integrations/gogogate2/gogogate2.classes.client.js +1 -1
- package/dist_ts/integrations/goodwe/goodwe.classes.client.js +1 -1
- package/dist_ts/integrations/goodwe/goodwe.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/goodwe/goodwe.classes.integration.js +1 -1
- package/dist_ts/integrations/goodwe/goodwe.discovery.d.ts +1 -1
- package/dist_ts/integrations/goodwe/goodwe.types.d.ts +8 -8
- package/dist_ts/integrations/google_wifi/google_wifi.classes.client.js +1 -1
- package/dist_ts/integrations/govee_ble/govee_ble.classes.client.js +1 -1
- package/dist_ts/integrations/govee_light_local/govee_light_local.classes.client.js +1 -1
- package/dist_ts/integrations/gpsd/gpsd.classes.client.js +1 -1
- package/dist_ts/integrations/graphite/graphite.classes.client.js +1 -1
- package/dist_ts/integrations/gree/gree.classes.client.js +1 -1
- package/dist_ts/integrations/harman_kardon_avr/harman_kardon_avr.classes.client.js +1 -1
- package/dist_ts/integrations/harman_kardon_avr/harman_kardon_avr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/harman_kardon_avr/harman_kardon_avr.classes.integration.js +1 -1
- package/dist_ts/integrations/harman_kardon_avr/harman_kardon_avr.discovery.d.ts +1 -1
- package/dist_ts/integrations/harman_kardon_avr/harman_kardon_avr.types.d.ts +12 -12
- package/dist_ts/integrations/harmony/harmony.classes.client.js +1 -1
- package/dist_ts/integrations/harmony/harmony.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/harmony/harmony.classes.integration.js +1 -1
- package/dist_ts/integrations/harmony/harmony.discovery.d.ts +2 -2
- package/dist_ts/integrations/hddtemp/hddtemp.classes.client.js +1 -1
- package/dist_ts/integrations/hddtemp/hddtemp.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/hddtemp/hddtemp.classes.integration.js +1 -1
- package/dist_ts/integrations/hddtemp/hddtemp.discovery.d.ts +2 -2
- package/dist_ts/integrations/hdfury/hdfury.classes.client.js +1 -1
- package/dist_ts/integrations/hdmi_cec/hdmi_cec.classes.client.js +1 -1
- package/dist_ts/integrations/heatmiser/heatmiser.classes.client.js +1 -1
- package/dist_ts/integrations/hegel/hegel.classes.client.js +1 -1
- package/dist_ts/integrations/heos/heos.classes.client.js +1 -1
- package/dist_ts/integrations/heos/heos.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/heos/heos.classes.integration.js +1 -1
- package/dist_ts/integrations/heos/heos.discovery.d.ts +3 -3
- package/dist_ts/integrations/hikvision/hikvision.classes.client.js +1 -1
- package/dist_ts/integrations/hikvision/hikvision.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/hikvision/hikvision.classes.integration.js +1 -1
- package/dist_ts/integrations/hikvision/hikvision.discovery.d.ts +3 -3
- package/dist_ts/integrations/hikvisioncam/hikvisioncam.classes.client.js +1 -1
- package/dist_ts/integrations/hisense_aehw4a1/hisense_aehw4a1.classes.client.js +1 -1
- package/dist_ts/integrations/hitron_coda/hitron_coda.classes.client.js +1 -1
- package/dist_ts/integrations/hlk_sw16/hlk_sw16.classes.client.js +1 -1
- package/dist_ts/integrations/holiday/holiday.classes.client.js +1 -1
- package/dist_ts/integrations/homeassistant/homeassistant.classes.client.d.ts +7 -1
- package/dist_ts/integrations/homeassistant/homeassistant.classes.client.js +174 -50
- package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.js +1 -1
- package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.d.ts +2 -0
- package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.js +35 -3
- package/dist_ts/integrations/homeassistant/homeassistant.mapper.d.ts +4 -4
- package/dist_ts/integrations/homeassistant/homeassistant.mapper.js +25 -36
- package/dist_ts/integrations/homeassistant/homeassistant.types.d.ts +10 -0
- package/dist_ts/integrations/homeassistant/homeassistant.validation.d.ts +9 -0
- package/dist_ts/integrations/homeassistant/homeassistant.validation.js +137 -0
- package/dist_ts/integrations/homee/homee.classes.client.js +1 -1
- package/dist_ts/integrations/homekit_controller/homekit_controller.classes.client.js +1 -1
- package/dist_ts/integrations/homekit_controller/homekit_controller.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/homekit_controller/homekit_controller.classes.integration.js +1 -1
- package/dist_ts/integrations/homekit_controller/homekit_controller.discovery.d.ts +2 -2
- package/dist_ts/integrations/homekit_controller/homekit_controller.mapper.js +1 -1
- package/dist_ts/integrations/homematic/homematic.classes.client.d.ts +2 -2
- package/dist_ts/integrations/homematic/homematic.classes.client.js +1 -1
- package/dist_ts/integrations/homematic/homematic.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/homematic/homematic.classes.integration.js +1 -1
- package/dist_ts/integrations/homematic/homematic.constants.d.ts +2 -2
- package/dist_ts/integrations/homematic/homematic.discovery.d.ts +2 -2
- package/dist_ts/integrations/homewizard/homewizard.classes.client.js +1 -1
- package/dist_ts/integrations/homewizard/homewizard.classes.integration.d.ts +3 -3
- package/dist_ts/integrations/homewizard/homewizard.classes.integration.js +1 -1
- package/dist_ts/integrations/homewizard/homewizard.discovery.d.ts +3 -3
- package/dist_ts/integrations/homewizard/homewizard.mapper.js +1 -1
- package/dist_ts/integrations/homewizard/homewizard.types.d.ts +10 -10
- package/dist_ts/integrations/huawei_lte/huawei_lte.classes.client.js +1 -1
- package/dist_ts/integrations/huawei_lte/huawei_lte.classes.integration.d.ts +2 -2
- package/dist_ts/integrations/huawei_lte/huawei_lte.classes.integration.js +1 -1
- package/dist_ts/integrations/huawei_lte/huawei_lte.discovery.d.ts +3 -3
- package/dist_ts/integrations/huawei_lte/huawei_lte.mapper.js +1 -1
- package/dist_ts/integrations/huawei_lte/huawei_lte.types.d.ts +1 -1
- package/dist_ts/integrations/hue/hue.classes.client.d.ts +13 -5
- package/dist_ts/integrations/hue/hue.classes.client.js +278 -23
- package/dist_ts/integrations/hue/hue.classes.configflow.js +34 -14
- package/dist_ts/integrations/hue/hue.classes.integration.d.ts +2 -1
- package/dist_ts/integrations/hue/hue.classes.integration.js +85 -25
- package/dist_ts/integrations/hue/hue.discovery.d.ts +2 -2
- package/dist_ts/integrations/hue/hue.discovery.js +79 -26
- package/dist_ts/integrations/hue/hue.mapper.d.ts +0 -1
- package/dist_ts/integrations/hue/hue.mapper.js +26 -54
- package/dist_ts/integrations/hue/hue.types.d.ts +14 -7
- package/dist_ts/integrations/hue/hue.validation.d.ts +11 -0
- package/dist_ts/integrations/hue/hue.validation.js +160 -0
- package/dist_ts/integrations/hunterdouglas_powerview/hunterdouglas_powerview.classes.client.js +1 -1
- package/dist_ts/integrations/hunterdouglas_powerview/hunterdouglas_powerview.classes.integration.d.ts +2 -2
- package/dist_ts/integrations/hunterdouglas_powerview/hunterdouglas_powerview.classes.integration.js +1 -1
- package/dist_ts/integrations/hunterdouglas_powerview/hunterdouglas_powerview.discovery.d.ts +3 -3
- package/dist_ts/integrations/hunterdouglas_powerview/hunterdouglas_powerview.types.d.ts +1 -1
- package/dist_ts/integrations/hyperion/hyperion.classes.client.js +1 -1
- package/dist_ts/integrations/hyperion/hyperion.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/hyperion/hyperion.classes.integration.js +1 -1
- package/dist_ts/integrations/hyperion/hyperion.discovery.d.ts +3 -3
- package/dist_ts/integrations/hyperion/hyperion.types.d.ts +1 -1
- package/dist_ts/integrations/imeon_inverter/imeon_inverter.classes.client.js +1 -1
- package/dist_ts/integrations/immich/immich.classes.client.js +1 -1
- package/dist_ts/integrations/incomfort/incomfort.classes.integration.js +1 -1
- package/dist_ts/integrations/indevolt/indevolt.classes.integration.js +1 -1
- package/dist_ts/integrations/index.d.ts +4 -1
- package/dist_ts/integrations/index.js +5 -2
- package/dist_ts/integrations/influxdb/influxdb.classes.client.js +1 -1
- package/dist_ts/integrations/intellifire/intellifire.classes.client.js +1 -1
- package/dist_ts/integrations/intellifire/intellifire.mapper.js +1 -1
- package/dist_ts/integrations/iometer/iometer.classes.client.js +1 -1
- package/dist_ts/integrations/iometer/iometer.mapper.js +1 -1
- package/dist_ts/integrations/iotawatt/iotawatt.classes.client.js +1 -1
- package/dist_ts/integrations/iperf3/iperf3.classes.client.js +1 -1
- package/dist_ts/integrations/ipp/ipp.classes.client.js +1 -1
- package/dist_ts/integrations/ipp/ipp.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/ipp/ipp.classes.integration.js +1 -1
- package/dist_ts/integrations/ipp/ipp.discovery.d.ts +2 -2
- package/dist_ts/integrations/iron_os/iron_os.classes.client.js +1 -1
- package/dist_ts/integrations/iskra/iskra.classes.client.js +1 -1
- package/dist_ts/integrations/iskra/iskra.mapper.js +1 -1
- package/dist_ts/integrations/itunes/itunes.classes.client.js +1 -1
- package/dist_ts/integrations/jellyfin/jellyfin.classes.client.js +1 -1
- package/dist_ts/integrations/jellyfin/jellyfin.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/jellyfin/jellyfin.classes.integration.js +1 -1
- package/dist_ts/integrations/jellyfin/jellyfin.discovery.d.ts +3 -3
- package/dist_ts/integrations/jvc_projector/jvc_projector.classes.client.js +1 -1
- package/dist_ts/integrations/kaleidescape/kaleidescape.classes.client.js +1 -1
- package/dist_ts/integrations/kankun/kankun.classes.client.js +1 -1
- package/dist_ts/integrations/keenetic_ndms2/keenetic_ndms2.classes.client.js +1 -1
- package/dist_ts/integrations/kef/kef.classes.client.js +1 -1
- package/dist_ts/integrations/kiosker/kiosker.classes.client.js +1 -1
- package/dist_ts/integrations/kira/kira.classes.client.js +1 -1
- package/dist_ts/integrations/kmtronic/kmtronic.classes.client.js +1 -1
- package/dist_ts/integrations/knx/knx.classes.client.js +1 -1
- package/dist_ts/integrations/knx/knx.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/knx/knx.classes.integration.js +1 -1
- package/dist_ts/integrations/knx/knx.discovery.d.ts +3 -3
- package/dist_ts/integrations/knx/knx.mapper.d.ts +1 -1
- package/dist_ts/integrations/knx/knx.mapper.js +1 -1
- package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +2 -2
- package/dist_ts/integrations/kodi/kodi.classes.client.js +1 -1
- package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/kodi/kodi.classes.integration.js +1 -1
- package/dist_ts/integrations/kodi/kodi.discovery.d.ts +2 -2
- package/dist_ts/integrations/konnected/konnected.classes.client.js +1 -1
- package/dist_ts/integrations/kostal_plenticore/kostal_plenticore.classes.client.js +1 -1
- package/dist_ts/integrations/kostal_plenticore/kostal_plenticore.mapper.js +1 -1
- package/dist_ts/integrations/kwb/kwb.classes.client.js +1 -1
- package/dist_ts/integrations/kwb/kwb.mapper.js +1 -1
- package/dist_ts/integrations/lametric/lametric.classes.client.js +1 -1
- package/dist_ts/integrations/landisgyr_heat_meter/landisgyr_heat_meter.mapper.js +1 -1
- package/dist_ts/integrations/lcn/lcn.classes.client.js +1 -1
- package/dist_ts/integrations/lektrico/lektrico.classes.client.js +1 -1
- package/dist_ts/integrations/lektrico/lektrico.types.d.ts +4 -4
- package/dist_ts/integrations/lg_netcast/lg_netcast.classes.client.js +1 -1
- package/dist_ts/integrations/lg_soundbar/lg_soundbar.classes.client.js +1 -1
- package/dist_ts/integrations/libre_hardware_monitor/libre_hardware_monitor.classes.client.js +1 -1
- package/dist_ts/integrations/lidarr/lidarr.classes.client.js +1 -1
- package/dist_ts/integrations/lifx/lifx.classes.client.d.ts +10 -4
- package/dist_ts/integrations/lifx/lifx.classes.client.js +94 -6
- package/dist_ts/integrations/lifx/lifx.classes.configflow.d.ts +3 -3
- package/dist_ts/integrations/lifx/lifx.classes.configflow.js +37 -6
- package/dist_ts/integrations/lifx/lifx.classes.integration.d.ts +19 -4
- package/dist_ts/integrations/lifx/lifx.classes.integration.js +152 -7
- package/dist_ts/integrations/lifx/lifx.discovery.d.ts +2 -1
- package/dist_ts/integrations/lifx/lifx.discovery.js +26 -4
- package/dist_ts/integrations/lifx/lifx.mapper.d.ts +7 -8
- package/dist_ts/integrations/lifx/lifx.mapper.js +42 -12
- package/dist_ts/integrations/lifx/lifx.types.d.ts +61 -9
- package/dist_ts/integrations/lifx/lifx.types.js +9 -116
- package/dist_ts/integrations/lifx/lifx.validation.d.ts +10 -0
- package/dist_ts/integrations/lifx/lifx.validation.js +83 -0
- package/dist_ts/integrations/linkplay/linkplay.classes.client.js +1 -1
- package/dist_ts/integrations/linkplay/linkplay.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/linkplay/linkplay.classes.integration.js +1 -1
- package/dist_ts/integrations/linkplay/linkplay.discovery.d.ts +3 -3
- package/dist_ts/integrations/linksys_smart/linksys_smart.classes.client.js +1 -1
- package/dist_ts/integrations/livisi/livisi.classes.client.js +1 -1
- package/dist_ts/integrations/local_calendar/local_calendar.classes.client.js +1 -1
- package/dist_ts/integrations/local_file/local_file.classes.client.js +1 -1
- package/dist_ts/integrations/local_ip/local_ip.classes.client.js +1 -1
- package/dist_ts/integrations/local_todo/local_todo.classes.client.js +1 -1
- package/dist_ts/integrations/lookin/lookin.classes.client.js +1 -1
- package/dist_ts/integrations/loqed/loqed.classes.client.js +1 -1
- package/dist_ts/integrations/loqed/loqed.mapper.d.ts +1 -1
- package/dist_ts/integrations/loqed/loqed.mapper.js +1 -1
- package/dist_ts/integrations/luci/luci.classes.client.js +1 -1
- package/dist_ts/integrations/luci/luci.mapper.js +1 -1
- package/dist_ts/integrations/lunatone/lunatone.classes.client.js +1 -1
- package/dist_ts/integrations/lunatone/lunatone.mapper.js +1 -1
- package/dist_ts/integrations/madvr/madvr.classes.client.js +1 -1
- package/dist_ts/integrations/madvr/madvr.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/madvr/madvr.classes.integration.js +1 -1
- package/dist_ts/integrations/madvr/madvr.discovery.d.ts +2 -2
- package/dist_ts/integrations/marytts/marytts.classes.client.js +1 -1
- package/dist_ts/integrations/marytts/marytts.classes.integration.js +1 -1
- package/dist_ts/integrations/matter/matter.classes.client.js +1 -1
- package/dist_ts/integrations/matter/matter.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/matter/matter.classes.integration.js +1 -1
- package/dist_ts/integrations/matter/matter.discovery.d.ts +2 -2
- package/dist_ts/integrations/matter/matter.mapper.js +1 -1
- package/dist_ts/integrations/maxcube/maxcube.classes.client.js +1 -1
- package/dist_ts/integrations/mcp/mcp.classes.client.js +1 -1
- package/dist_ts/integrations/mcp_server/mcp_server.classes.client.js +1 -1
- package/dist_ts/integrations/mealie/mealie.classes.client.js +1 -1
- package/dist_ts/integrations/mealie/mealie.mapper.js +1 -1
- package/dist_ts/integrations/medcom_ble/medcom_ble.classes.client.js +1 -1
- package/dist_ts/integrations/medcom_ble/medcom_ble.mapper.js +1 -1
- package/dist_ts/integrations/mediaroom/mediaroom.classes.client.js +1 -1
- package/dist_ts/integrations/mediaroom/mediaroom.mapper.js +1 -1
- package/dist_ts/integrations/mfi/mfi.mapper.js +1 -1
- package/dist_ts/integrations/mikrotik/mikrotik.classes.client.js +1 -1
- package/dist_ts/integrations/mikrotik/mikrotik.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/mikrotik/mikrotik.classes.integration.js +1 -1
- package/dist_ts/integrations/mikrotik/mikrotik.discovery.d.ts +1 -1
- package/dist_ts/integrations/mikrotik/mikrotik.mapper.js +1 -1
- package/dist_ts/integrations/mill/mill.classes.client.js +1 -1
- package/dist_ts/integrations/mill/mill.mapper.js +1 -1
- package/dist_ts/integrations/minecraft_server/minecraft_server.classes.client.js +1 -1
- package/dist_ts/integrations/mjpeg/mjpeg.classes.client.js +1 -1
- package/dist_ts/integrations/mobile_app/mobile_app.classes.client.js +1 -1
- package/dist_ts/integrations/mochad/mochad.classes.client.js +1 -1
- package/dist_ts/integrations/modbus/modbus.classes.client.js +1 -1
- package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/modbus/modbus.classes.integration.js +1 -1
- package/dist_ts/integrations/modbus/modbus.discovery.d.ts +1 -1
- package/dist_ts/integrations/modern_forms/modern_forms.classes.client.js +1 -1
- package/dist_ts/integrations/moehlenhoff_alpha2/moehlenhoff_alpha2.classes.client.js +1 -1
- package/dist_ts/integrations/monoprice/monoprice.classes.client.js +1 -1
- package/dist_ts/integrations/motioneye/motioneye.classes.client.js +1 -1
- package/dist_ts/integrations/motioneye/motioneye.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/motioneye/motioneye.classes.integration.js +1 -1
- package/dist_ts/integrations/motioneye/motioneye.discovery.d.ts +2 -2
- package/dist_ts/integrations/motioneye/motioneye.types.d.ts +1 -1
- package/dist_ts/integrations/motionmount/motionmount.classes.client.js +1 -1
- package/dist_ts/integrations/mpd/mpd.classes.client.js +1 -1
- package/dist_ts/integrations/mpd/mpd.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/mpd/mpd.classes.integration.js +1 -1
- package/dist_ts/integrations/mpd/mpd.discovery.d.ts +2 -2
- package/dist_ts/integrations/mqtt/mqtt.classes.client.d.ts +54 -9
- package/dist_ts/integrations/mqtt/mqtt.classes.client.js +443 -352
- package/dist_ts/integrations/mqtt/mqtt.classes.configflow.d.ts +0 -1
- package/dist_ts/integrations/mqtt/mqtt.classes.configflow.js +23 -18
- package/dist_ts/integrations/mqtt/mqtt.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/mqtt/mqtt.classes.integration.js +140 -37
- package/dist_ts/integrations/mqtt/mqtt.discovery.d.ts +2 -2
- package/dist_ts/integrations/mqtt/mqtt.mapper.d.ts +7 -1
- package/dist_ts/integrations/mqtt/mqtt.mapper.js +161 -48
- package/dist_ts/integrations/mqtt/mqtt.types.d.ts +17 -0
- package/dist_ts/integrations/mqtt_eventstream/mqtt_eventstream.classes.client.js +1 -1
- package/dist_ts/integrations/mqtt_json/mqtt_json.classes.client.js +1 -1
- package/dist_ts/integrations/mqtt_room/mqtt_room.classes.client.js +1 -1
- package/dist_ts/integrations/music_assistant/music_assistant.classes.client.js +1 -1
- package/dist_ts/integrations/music_assistant/music_assistant.mapper.js +1 -1
- package/dist_ts/integrations/mutesync/mutesync.classes.client.js +1 -1
- package/dist_ts/integrations/mutesync/mutesync.mapper.js +1 -1
- package/dist_ts/integrations/mycroft/mycroft.classes.client.js +1 -1
- package/dist_ts/integrations/mysensors/mysensors.classes.client.js +1 -1
- package/dist_ts/integrations/mystrom/mystrom.classes.client.js +1 -1
- package/dist_ts/integrations/nad/nad.classes.client.js +1 -1
- package/dist_ts/integrations/nam/nam.classes.client.js +1 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +1 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +1 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.discovery.d.ts +3 -3
- package/dist_ts/integrations/nasweb/nasweb.classes.client.js +1 -1
- package/dist_ts/integrations/netdata/netdata.classes.client.js +1 -1
- package/dist_ts/integrations/nibe_heatpump/nibe_heatpump.classes.client.js +1 -1
- package/dist_ts/integrations/niko_home_control/niko_home_control.classes.client.js +1 -1
- package/dist_ts/integrations/nobo_hub/nobo_hub.classes.client.js +1 -1
- package/dist_ts/integrations/nrgkick/nrgkick.classes.client.js +1 -1
- package/dist_ts/integrations/nuki/nuki.classes.client.js +1 -1
- package/dist_ts/integrations/nut/nut.classes.client.js +1 -1
- package/dist_ts/integrations/nut/nut.classes.integration.js +1 -1
- package/dist_ts/integrations/nx584/nx584.classes.client.js +1 -1
- package/dist_ts/integrations/nx584/nx584.classes.integration.js +1 -1
- package/dist_ts/integrations/nzbget/nzbget.classes.client.js +1 -1
- package/dist_ts/integrations/nzbget/nzbget.mapper.js +1 -1
- package/dist_ts/integrations/obihai/obihai.classes.client.js +1 -1
- package/dist_ts/integrations/octoprint/octoprint.classes.client.js +1 -1
- package/dist_ts/integrations/octoprint/octoprint.mapper.js +1 -1
- package/dist_ts/integrations/oem/oem.classes.client.js +1 -1
- package/dist_ts/integrations/ollama/ollama.classes.client.js +1 -1
- package/dist_ts/integrations/ombi/ombi.classes.client.js +1 -1
- package/dist_ts/integrations/onewire/onewire.classes.client.js +1 -1
- package/dist_ts/integrations/onkyo/onkyo.classes.client.js +1 -1
- package/dist_ts/integrations/onvif/onvif.classes.client.js +1 -1
- package/dist_ts/integrations/onvif/onvif.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/onvif/onvif.classes.integration.js +1 -1
- package/dist_ts/integrations/onvif/onvif.discovery.d.ts +3 -3
- package/dist_ts/integrations/onvif/onvif.mapper.js +1 -1
- package/dist_ts/integrations/openevse/openevse.classes.client.js +1 -1
- package/dist_ts/integrations/openevse/openevse.mapper.js +1 -1
- package/dist_ts/integrations/opengarage/opengarage.classes.client.js +1 -1
- package/dist_ts/integrations/opengarage/opengarage.mapper.js +1 -1
- package/dist_ts/integrations/openhardwaremonitor/openhardwaremonitor.classes.client.js +1 -1
- package/dist_ts/integrations/openhome/openhome.classes.client.d.ts +2 -1
- package/dist_ts/integrations/openhome/openhome.classes.client.js +21 -19
- package/dist_ts/integrations/openrgb/openrgb.classes.client.js +1 -1
- package/dist_ts/integrations/openrgb/openrgb.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/openrgb/openrgb.classes.integration.js +1 -1
- package/dist_ts/integrations/openrgb/openrgb.discovery.d.ts +2 -2
- package/dist_ts/integrations/openrgb/openrgb.mapper.js +1 -1
- package/dist_ts/integrations/opentherm_gw/opentherm_gw.classes.client.d.ts +1 -1
- package/dist_ts/integrations/opentherm_gw/opentherm_gw.classes.client.js +1 -1
- package/dist_ts/integrations/opentherm_gw/opentherm_gw.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/opentherm_gw/opentherm_gw.classes.integration.js +1 -1
- package/dist_ts/integrations/opentherm_gw/opentherm_gw.discovery.d.ts +1 -1
- package/dist_ts/integrations/opnsense/opnsense.classes.client.js +1 -1
- package/dist_ts/integrations/opnsense/opnsense.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/opnsense/opnsense.classes.integration.js +1 -1
- package/dist_ts/integrations/opnsense/opnsense.discovery.d.ts +1 -1
- package/dist_ts/integrations/opnsense/opnsense.mapper.js +1 -1
- package/dist_ts/integrations/orvibo/orvibo.classes.client.js +1 -1
- package/dist_ts/integrations/osramlightify/osramlightify.classes.client.js +1 -1
- package/dist_ts/integrations/otbr/otbr.classes.client.js +1 -1
- package/dist_ts/integrations/overkiz/overkiz.classes.client.js +1 -1
- package/dist_ts/integrations/overseerr/overseerr.classes.client.js +1 -1
- package/dist_ts/integrations/owntracks/owntracks.classes.client.js +1 -1
- package/dist_ts/integrations/p1_monitor/p1_monitor.classes.client.js +1 -1
- package/dist_ts/integrations/palazzetti/palazzetti.classes.client.js +1 -1
- package/dist_ts/integrations/panasonic_bluray/panasonic_bluray.classes.client.js +1 -1
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +1 -1
- package/dist_ts/integrations/paperless_ngx/paperless_ngx.classes.client.js +1 -1
- package/dist_ts/integrations/paperless_ngx/paperless_ngx.mapper.js +1 -1
- package/dist_ts/integrations/peblar/peblar.classes.client.js +1 -1
- package/dist_ts/integrations/peblar/peblar.mapper.js +1 -1
- package/dist_ts/integrations/pencom/pencom.classes.client.js +1 -1
- package/dist_ts/integrations/philips_js/philips_js.classes.client.js +1 -1
- package/dist_ts/integrations/pi_hole/pi_hole.classes.client.js +1 -1
- package/dist_ts/integrations/pi_hole/pi_hole.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/pi_hole/pi_hole.classes.integration.js +1 -1
- package/dist_ts/integrations/pi_hole/pi_hole.discovery.d.ts +2 -2
- package/dist_ts/integrations/pi_hole/pi_hole.mapper.js +1 -1
- package/dist_ts/integrations/picotts/picotts.classes.client.js +1 -1
- package/dist_ts/integrations/pilight/pilight.classes.client.js +1 -1
- package/dist_ts/integrations/pilight/pilight.classes.integration.js +1 -1
- package/dist_ts/integrations/ping/ping.classes.client.js +1 -1
- package/dist_ts/integrations/pioneer/pioneer.classes.client.js +1 -1
- package/dist_ts/integrations/pjlink/pjlink.classes.client.js +1 -1
- package/dist_ts/integrations/plex/plex.classes.client.d.ts +1 -1
- package/dist_ts/integrations/plex/plex.classes.client.js +1 -1
- package/dist_ts/integrations/plex/plex.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/plex/plex.classes.integration.js +1 -1
- package/dist_ts/integrations/plex/plex.discovery.d.ts +5 -5
- package/dist_ts/integrations/plugwise/plugwise.classes.client.js +1 -1
- package/dist_ts/integrations/prusalink/prusalink.classes.client.js +1 -1
- package/dist_ts/integrations/prusalink/prusalink.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/prusalink/prusalink.classes.integration.js +1 -1
- package/dist_ts/integrations/prusalink/prusalink.discovery.d.ts +2 -2
- package/dist_ts/integrations/rainbird/rainbird.classes.client.js +1 -1
- package/dist_ts/integrations/rainbird/rainbird.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/rainbird/rainbird.classes.integration.js +1 -1
- package/dist_ts/integrations/rainbird/rainbird.discovery.d.ts +1 -1
- package/dist_ts/integrations/rflink/rflink.classes.client.js +1 -1
- package/dist_ts/integrations/rflink/rflink.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/rflink/rflink.classes.integration.js +1 -1
- package/dist_ts/integrations/rflink/rflink.discovery.d.ts +1 -1
- package/dist_ts/integrations/roku/roku.classes.client.d.ts +27 -14
- package/dist_ts/integrations/roku/roku.classes.client.js +213 -132
- package/dist_ts/integrations/roku/roku.classes.configflow.js +23 -14
- package/dist_ts/integrations/roku/roku.classes.integration.d.ts +4 -1
- package/dist_ts/integrations/roku/roku.classes.integration.js +74 -91
- package/dist_ts/integrations/roku/roku.discovery.d.ts +8 -8
- package/dist_ts/integrations/roku/roku.discovery.js +82 -65
- package/dist_ts/integrations/roku/roku.mapper.d.ts +0 -3
- package/dist_ts/integrations/roku/roku.mapper.js +18 -50
- package/dist_ts/integrations/roku/roku.types.d.ts +21 -12
- package/dist_ts/integrations/roku/roku.validation.d.ts +9 -0
- package/dist_ts/integrations/roku/roku.validation.js +74 -0
- package/dist_ts/integrations/samsungtv/samsungtv.classes.client.d.ts +9 -38
- package/dist_ts/integrations/samsungtv/samsungtv.classes.client.js +113 -417
- package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.js +31 -29
- package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.d.ts +8 -7
- package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.js +122 -117
- package/dist_ts/integrations/samsungtv/samsungtv.discovery.d.ts +11 -11
- package/dist_ts/integrations/samsungtv/samsungtv.discovery.js +120 -143
- package/dist_ts/integrations/samsungtv/samsungtv.mapper.d.ts +3 -11
- package/dist_ts/integrations/samsungtv/samsungtv.mapper.js +18 -117
- package/dist_ts/integrations/samsungtv/samsungtv.types.d.ts +18 -85
- package/dist_ts/integrations/samsungtv/samsungtv.validation.d.ts +7 -0
- package/dist_ts/integrations/samsungtv/samsungtv.validation.js +83 -0
- package/dist_ts/integrations/shelly/shelly.classes.client.d.ts +29 -14
- package/dist_ts/integrations/shelly/shelly.classes.client.js +310 -126
- package/dist_ts/integrations/shelly/shelly.classes.configflow.js +29 -11
- package/dist_ts/integrations/shelly/shelly.classes.integration.d.ts +4 -1
- package/dist_ts/integrations/shelly/shelly.classes.integration.js +120 -27
- package/dist_ts/integrations/shelly/shelly.classes.subscription.d.ts +47 -0
- package/dist_ts/integrations/shelly/shelly.classes.subscription.js +206 -0
- package/dist_ts/integrations/shelly/shelly.discovery.d.ts +2 -2
- package/dist_ts/integrations/shelly/shelly.discovery.js +6 -3
- package/dist_ts/integrations/shelly/shelly.rpc.d.ts +21 -0
- package/dist_ts/integrations/shelly/shelly.rpc.js +210 -0
- package/dist_ts/integrations/shelly/shelly.types.d.ts +26 -4
- package/dist_ts/integrations/snapcast/snapcast.classes.client.js +1 -1
- package/dist_ts/integrations/snapcast/snapcast.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/snapcast/snapcast.classes.integration.js +1 -1
- package/dist_ts/integrations/snapcast/snapcast.discovery.d.ts +2 -2
- package/dist_ts/integrations/sonos/index.d.ts +3 -0
- package/dist_ts/integrations/sonos/index.js +4 -1
- package/dist_ts/integrations/sonos/sonos.classes.client.d.ts +30 -29
- package/dist_ts/integrations/sonos/sonos.classes.client.js +162 -208
- package/dist_ts/integrations/sonos/sonos.classes.configflow.js +27 -9
- package/dist_ts/integrations/sonos/sonos.classes.integration.d.ts +6 -5
- package/dist_ts/integrations/sonos/sonos.classes.integration.js +280 -61
- package/dist_ts/integrations/sonos/sonos.classes.ssdpprobe.d.ts +17 -0
- package/dist_ts/integrations/sonos/sonos.classes.ssdpprobe.js +88 -0
- package/dist_ts/integrations/sonos/sonos.config.d.ts +12 -0
- package/dist_ts/integrations/sonos/sonos.config.js +52 -0
- package/dist_ts/integrations/sonos/sonos.discovery.d.ts +1 -25
- package/dist_ts/integrations/sonos/sonos.discovery.js +6 -114
- package/dist_ts/integrations/sonos/sonos.mapper.d.ts +2 -1
- package/dist_ts/integrations/sonos/sonos.mapper.js +33 -13
- package/dist_ts/integrations/sonos/sonos.matchers.d.ts +25 -0
- package/dist_ts/integrations/sonos/sonos.matchers.js +82 -0
- package/dist_ts/integrations/sonos/sonos.topology.d.ts +2 -0
- package/dist_ts/integrations/sonos/sonos.topology.js +59 -0
- package/dist_ts/integrations/sonos/sonos.types.d.ts +18 -8
- package/dist_ts/integrations/sonos/sonos.xml.d.ts +3 -0
- package/dist_ts/integrations/sonos/sonos.xml.js +21 -0
- package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +1 -1
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +1 -1
- package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -2
- package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +1 -1
- package/dist_ts/integrations/squeezebox/squeezebox.classes.client.js +1 -1
- package/dist_ts/integrations/squeezebox/squeezebox.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/squeezebox/squeezebox.classes.integration.js +1 -1
- package/dist_ts/integrations/squeezebox/squeezebox.discovery.d.ts +3 -3
- package/dist_ts/integrations/synology_dsm/synology_dsm.classes.client.js +1 -1
- package/dist_ts/integrations/synology_dsm/synology_dsm.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/synology_dsm/synology_dsm.classes.integration.js +1 -1
- package/dist_ts/integrations/synology_dsm/synology_dsm.discovery.d.ts +4 -4
- package/dist_ts/integrations/synology_dsm/synology_dsm.mapper.js +1 -1
- package/dist_ts/integrations/synology_srm/synology_srm.classes.client.js +1 -1
- package/dist_ts/integrations/synology_srm/synology_srm.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/synology_srm/synology_srm.classes.integration.js +1 -1
- package/dist_ts/integrations/synology_srm/synology_srm.discovery.d.ts +2 -2
- package/dist_ts/integrations/synology_srm/synology_srm.mapper.js +1 -1
- package/dist_ts/integrations/tasmota/index.d.ts +4 -0
- package/dist_ts/integrations/tasmota/index.js +5 -1
- package/dist_ts/integrations/tasmota/tasmota.classes.integration.d.ts +21 -3
- package/dist_ts/integrations/tasmota/tasmota.classes.integration.js +24 -25
- package/dist_ts/integrations/tasmota/tasmota.classes.runtime.d.ts +36 -0
- package/dist_ts/integrations/tasmota/tasmota.classes.runtime.js +292 -0
- package/dist_ts/integrations/tasmota/tasmota.config.d.ts +2 -0
- package/dist_ts/integrations/tasmota/tasmota.config.js +78 -0
- package/dist_ts/integrations/tasmota/tasmota.discovery.d.ts +7 -0
- package/dist_ts/integrations/tasmota/tasmota.discovery.js +85 -0
- package/dist_ts/integrations/tasmota/tasmota.mapper.d.ts +12 -0
- package/dist_ts/integrations/tasmota/tasmota.mapper.js +91 -0
- package/dist_ts/integrations/tasmota/tasmota.types.d.ts +51 -1
- package/dist_ts/integrations/tplink/index.d.ts +3 -0
- package/dist_ts/integrations/tplink/index.js +4 -1
- package/dist_ts/integrations/tplink/tplink.classes.client.d.ts +8 -14
- package/dist_ts/integrations/tplink/tplink.classes.client.js +64 -64
- package/dist_ts/integrations/tplink/tplink.classes.configflow.d.ts +3 -8
- package/dist_ts/integrations/tplink/tplink.classes.configflow.js +53 -89
- package/dist_ts/integrations/tplink/tplink.classes.integration.d.ts +8 -13
- package/dist_ts/integrations/tplink/tplink.classes.integration.js +136 -37
- package/dist_ts/integrations/tplink/tplink.discovery.d.ts +11 -14
- package/dist_ts/integrations/tplink/tplink.discovery.js +125 -210
- package/dist_ts/integrations/tplink/tplink.mapper.js +1 -1
- package/dist_ts/integrations/tplink/tplink.native.mapper.d.ts +11 -0
- package/dist_ts/integrations/tplink/tplink.native.mapper.js +61 -0
- package/dist_ts/integrations/tplink/tplink.native.types.d.ts +32 -0
- package/dist_ts/integrations/tplink/tplink.native.types.js +2 -0
- package/dist_ts/integrations/tplink/tplink.validation.d.ts +4 -0
- package/dist_ts/integrations/tplink/tplink.validation.js +48 -0
- package/dist_ts/integrations/tradfri/tradfri.classes.client.js +1 -1
- package/dist_ts/integrations/tradfri/tradfri.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/tradfri/tradfri.classes.integration.js +1 -1
- package/dist_ts/integrations/tradfri/tradfri.discovery.d.ts +2 -3
- package/dist_ts/integrations/tradfri/tradfri.discovery.js +52 -26
- package/dist_ts/integrations/tradfri/tradfri.mapper.js +1 -1
- package/dist_ts/integrations/tuya/tuya.classes.integration.d.ts +21 -3
- package/dist_ts/integrations/tuya/tuya.classes.integration.js +139 -28
- package/dist_ts/integrations/tuya/tuya.classes.runtime.d.ts +15 -0
- package/dist_ts/integrations/tuya/tuya.classes.runtime.js +189 -0
- package/dist_ts/integrations/tuya/tuya.mapper.d.ts +13 -0
- package/dist_ts/integrations/tuya/tuya.mapper.js +30 -0
- package/dist_ts/integrations/tuya/tuya.types.d.ts +40 -1
- package/dist_ts/integrations/tuya/tuya.validation.d.ts +10 -0
- package/dist_ts/integrations/tuya/tuya.validation.js +122 -0
- package/dist_ts/integrations/unifi/unifi.classes.client.js +1 -1
- package/dist_ts/integrations/unifi/unifi.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/unifi/unifi.classes.integration.js +1 -1
- package/dist_ts/integrations/unifi/unifi.discovery.d.ts +4 -4
- package/dist_ts/integrations/unifi/unifi.mapper.js +6 -6
- package/dist_ts/integrations/velbus/velbus.classes.client.js +1 -1
- package/dist_ts/integrations/velbus/velbus.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/velbus/velbus.classes.integration.js +1 -1
- package/dist_ts/integrations/velbus/velbus.discovery.d.ts +2 -2
- package/dist_ts/integrations/volumio/volumio.classes.client.js +1 -1
- package/dist_ts/integrations/volumio/volumio.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/volumio/volumio.classes.integration.js +1 -1
- package/dist_ts/integrations/volumio/volumio.discovery.d.ts +2 -2
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.classes.client.js +1 -1
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.classes.integration.js +1 -1
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.discovery.d.ts +2 -2
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.mapper.js +1 -1
- package/dist_ts/integrations/wake_on_lan/wake_on_lan.packet.js +1 -1
- package/dist_ts/integrations/webostv/webostv.classes.client.d.ts +10 -4
- package/dist_ts/integrations/webostv/webostv.classes.client.js +370 -6
- package/dist_ts/integrations/webostv/webostv.classes.configflow.d.ts +3 -3
- package/dist_ts/integrations/webostv/webostv.classes.configflow.js +23 -6
- package/dist_ts/integrations/webostv/webostv.classes.integration.d.ts +20 -5
- package/dist_ts/integrations/webostv/webostv.classes.integration.js +138 -7
- package/dist_ts/integrations/webostv/webostv.discovery.d.ts +2 -1
- package/dist_ts/integrations/webostv/webostv.discovery.js +26 -4
- package/dist_ts/integrations/webostv/webostv.mapper.d.ts +6 -8
- package/dist_ts/integrations/webostv/webostv.mapper.js +24 -13
- package/dist_ts/integrations/webostv/webostv.types.d.ts +61 -5
- package/dist_ts/integrations/webostv/webostv.types.js +5 -96
- package/dist_ts/integrations/webostv/webostv.validation.d.ts +6 -0
- package/dist_ts/integrations/webostv/webostv.validation.js +54 -0
- package/dist_ts/integrations/wiz/wiz.classes.client.js +1 -1
- package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +7 -7
- package/dist_ts/integrations/wiz/wiz.classes.integration.js +1 -1
- package/dist_ts/integrations/wiz/wiz.discovery.d.ts +4 -4
- package/dist_ts/integrations/wiz/wiz.mapper.js +1 -1
- package/dist_ts/integrations/wled/index.d.ts +1 -0
- package/dist_ts/integrations/wled/index.js +2 -1
- package/dist_ts/integrations/wled/wled.classes.client.d.ts +27 -4
- package/dist_ts/integrations/wled/wled.classes.client.js +231 -6
- package/dist_ts/integrations/wled/wled.classes.configflow.d.ts +3 -3
- package/dist_ts/integrations/wled/wled.classes.configflow.js +33 -6
- package/dist_ts/integrations/wled/wled.classes.integration.d.ts +24 -4
- package/dist_ts/integrations/wled/wled.classes.integration.js +171 -7
- package/dist_ts/integrations/wled/wled.classes.subscription.d.ts +37 -0
- package/dist_ts/integrations/wled/wled.classes.subscription.js +116 -0
- package/dist_ts/integrations/wled/wled.commands.d.ts +4 -0
- package/dist_ts/integrations/wled/wled.commands.js +65 -0
- package/dist_ts/integrations/wled/wled.discovery.d.ts +17 -1
- package/dist_ts/integrations/wled/wled.discovery.js +68 -4
- package/dist_ts/integrations/wled/wled.errors.d.ts +5 -0
- package/dist_ts/integrations/wled/wled.errors.js +9 -0
- package/dist_ts/integrations/wled/wled.mapper.d.ts +8 -8
- package/dist_ts/integrations/wled/wled.mapper.js +40 -16
- package/dist_ts/integrations/wled/wled.types.d.ts +75 -6
- package/dist_ts/integrations/wled/wled.types.js +12 -82
- package/dist_ts/integrations/wled/wled.validation.d.ts +7 -0
- package/dist_ts/integrations/wled/wled.validation.js +85 -0
- package/dist_ts/integrations/wolf_smartset/wolf_smartset.classes.client.js +1 -1
- package/dist_ts/integrations/wolf_smartset/wolf_smartset.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/wolf_smartset/wolf_smartset.discovery.d.ts +1 -1
- package/dist_ts/integrations/xiaomi_miio/xiaomi_miio.classes.client.js +1 -1
- package/dist_ts/integrations/xiaomi_miio/xiaomi_miio.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/xiaomi_miio/xiaomi_miio.classes.integration.js +1 -1
- package/dist_ts/integrations/xiaomi_miio/xiaomi_miio.discovery.d.ts +3 -3
- package/dist_ts/integrations/xiaomi_miio/xiaomi_miio.mapper.js +1 -1
- package/dist_ts/integrations/yamaha_musiccast/yamaha_musiccast.classes.client.js +1 -1
- package/dist_ts/integrations/yamaha_musiccast/yamaha_musiccast.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/yamaha_musiccast/yamaha_musiccast.classes.integration.js +1 -1
- package/dist_ts/integrations/yamaha_musiccast/yamaha_musiccast.discovery.d.ts +3 -3
- package/dist_ts/integrations/yeelight/yeelight.classes.client.d.ts +34 -26
- package/dist_ts/integrations/yeelight/yeelight.classes.client.js +225 -275
- package/dist_ts/integrations/yeelight/yeelight.classes.configflow.d.ts +0 -2
- package/dist_ts/integrations/yeelight/yeelight.classes.configflow.js +29 -30
- package/dist_ts/integrations/yeelight/yeelight.classes.integration.d.ts +11 -5
- package/dist_ts/integrations/yeelight/yeelight.classes.integration.js +140 -80
- package/dist_ts/integrations/yeelight/yeelight.discovery.d.ts +11 -13
- package/dist_ts/integrations/yeelight/yeelight.discovery.js +90 -128
- package/dist_ts/integrations/yeelight/yeelight.mapper.d.ts +2 -10
- package/dist_ts/integrations/yeelight/yeelight.mapper.js +57 -178
- package/dist_ts/integrations/yeelight/yeelight.types.d.ts +37 -139
- package/dist_ts/integrations/yeelight/yeelight.validation.d.ts +10 -0
- package/dist_ts/integrations/yeelight/yeelight.validation.js +111 -0
- package/dist_ts/integrations/zha/zha.classes.client.js +1 -1
- package/dist_ts/integrations/zha/zha.classes.integration.d.ts +1 -1
- package/dist_ts/integrations/zha/zha.classes.integration.js +1 -1
- package/dist_ts/integrations/zha/zha.discovery.d.ts +3 -12
- package/dist_ts/integrations/zha/zha.discovery.js +102 -222
- package/dist_ts/integrations/zha/zha.discoveryvalidation.d.ts +10 -0
- package/dist_ts/integrations/zha/zha.discoveryvalidation.js +71 -0
- package/dist_ts/integrations/zha/zha.mapper.js +1 -1
- package/dist_ts/integrations/zigbee2mqtt/index.d.ts +5 -0
- package/dist_ts/integrations/zigbee2mqtt/index.js +6 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.d.ts +5 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.js +27 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.d.ts +19 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.js +19 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.d.ts +55 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.js +464 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.d.ts +15 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.js +186 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.d.ts +57 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.js +2 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.d.ts +5 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.js +66 -0
- package/dist_ts/integrations/zwave_js/zwave_js.classes.client.d.ts +19 -21
- package/dist_ts/integrations/zwave_js/zwave_js.classes.client.js +303 -134
- package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.d.ts +0 -3
- package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.js +31 -26
- package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.d.ts +2 -1
- package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.js +71 -76
- package/dist_ts/integrations/zwave_js/zwave_js.discovery.d.ts +3 -3
- package/dist_ts/integrations/zwave_js/zwave_js.discovery.js +120 -16
- package/dist_ts/integrations/zwave_js/zwave_js.mapper.d.ts +13 -14
- package/dist_ts/integrations/zwave_js/zwave_js.mapper.js +140 -257
- package/dist_ts/integrations/zwave_js/zwave_js.types.d.ts +30 -19
- package/dist_ts/integrations/zwave_js/zwave_js.validation.d.ts +15 -0
- package/dist_ts/integrations/zwave_js/zwave_js.validation.js +191 -0
- package/dist_ts/plugins.d.ts +10 -2
- package/dist_ts/plugins.js +11 -3
- package/dist_ts_migration/001.import-json-config.d.ts +10 -0
- package/dist_ts_migration/001.import-json-config.js +147 -0
- package/dist_ts_migration/index.d.ts +1 -0
- package/dist_ts_migration/index.js +2 -0
- package/package.json +20 -11
- package/readme.md +49 -10
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/classes.configrecord.ts +23 -0
- package/ts/core/classes.configstore.ts +324 -25
- package/ts/core/classes.discoveryengine.ts +11 -1
- package/ts/core/classes.runtimemanager.ts +88 -44
- package/ts/core/types.ts +15 -4
- package/ts/index.ts +6 -0
- package/ts/integrations/deconz/deconz.classes.client.ts +243 -190
- package/ts/integrations/deconz/deconz.classes.configflow.ts +34 -25
- package/ts/integrations/deconz/deconz.classes.integration.ts +105 -22
- package/ts/integrations/deconz/deconz.mapper.ts +24 -18
- package/ts/integrations/deconz/deconz.types.ts +38 -3
- package/ts/integrations/deconz/deconz.validation.ts +261 -0
- package/ts/integrations/deconz/readme.md +44 -0
- package/ts/integrations/esphome/esphome.classes.client.ts +254 -74
- package/ts/integrations/esphome/esphome.classes.configflow.ts +1 -3
- package/ts/integrations/esphome/esphome.classes.integration.ts +61 -66
- package/ts/integrations/esphome/esphome.discovery.ts +1 -1
- package/ts/integrations/esphome/esphome.mapper.ts +71 -37
- package/ts/integrations/esphome/esphome.types.ts +2 -0
- package/ts/integrations/esphome/readme.md +66 -0
- package/ts/integrations/generated/index.ts +4 -6
- package/ts/integrations/homeassistant/homeassistant.classes.client.ts +166 -63
- package/ts/integrations/homeassistant/homeassistant.classes.runtime.ts +41 -3
- package/ts/integrations/homeassistant/homeassistant.mapper.ts +32 -36
- package/ts/integrations/homeassistant/homeassistant.types.ts +11 -0
- package/ts/integrations/homeassistant/homeassistant.validation.ts +139 -0
- package/ts/integrations/homeassistant/readme.md +40 -0
- package/ts/integrations/hue/hue.classes.client.ts +251 -21
- package/ts/integrations/hue/hue.classes.configflow.ts +26 -13
- package/ts/integrations/hue/hue.classes.integration.ts +76 -30
- package/ts/integrations/hue/hue.discovery.ts +61 -26
- package/ts/integrations/hue/hue.mapper.ts +28 -60
- package/ts/integrations/hue/hue.types.ts +12 -18
- package/ts/integrations/hue/hue.validation.ts +154 -0
- package/ts/integrations/hue/readme.md +71 -0
- package/ts/integrations/index.ts +5 -1
- package/ts/integrations/lifx/lifx.classes.client.ts +95 -6
- package/ts/integrations/lifx/lifx.classes.configflow.ts +32 -5
- package/ts/integrations/lifx/lifx.classes.integration.ts +142 -7
- package/ts/integrations/lifx/lifx.discovery.ts +26 -3
- package/ts/integrations/lifx/lifx.mapper.ts +45 -17
- package/ts/integrations/lifx/lifx.types.ts +51 -125
- package/ts/integrations/lifx/lifx.validation.ts +86 -0
- package/ts/integrations/lifx/readme.md +55 -0
- package/ts/integrations/mqtt/mqtt.classes.client.ts +394 -366
- package/ts/integrations/mqtt/mqtt.classes.configflow.ts +22 -18
- package/ts/integrations/mqtt/mqtt.classes.integration.ts +119 -44
- package/ts/integrations/mqtt/mqtt.mapper.ts +139 -47
- package/ts/integrations/mqtt/mqtt.types.ts +19 -0
- package/ts/integrations/mqtt/readme.md +28 -0
- package/ts/integrations/openhome/openhome.classes.client.ts +22 -18
- package/ts/integrations/roku/readme.md +95 -0
- package/ts/integrations/roku/roku.classes.client.ts +194 -131
- package/ts/integrations/roku/roku.classes.configflow.ts +20 -13
- package/ts/integrations/roku/roku.classes.integration.ts +69 -98
- package/ts/integrations/roku/roku.discovery.ts +68 -71
- package/ts/integrations/roku/roku.mapper.ts +17 -52
- package/ts/integrations/roku/roku.types.ts +23 -14
- package/ts/integrations/roku/roku.validation.ts +79 -0
- package/ts/integrations/samsungtv/readme.md +30 -0
- package/ts/integrations/samsungtv/samsungtv.classes.client.ts +107 -481
- package/ts/integrations/samsungtv/samsungtv.classes.configflow.ts +28 -29
- package/ts/integrations/samsungtv/samsungtv.classes.integration.ts +108 -132
- package/ts/integrations/samsungtv/samsungtv.discovery.ts +101 -165
- package/ts/integrations/samsungtv/samsungtv.mapper.ts +20 -127
- package/ts/integrations/samsungtv/samsungtv.types.ts +18 -95
- package/ts/integrations/samsungtv/samsungtv.validation.ts +84 -0
- package/ts/integrations/shelly/readme.md +34 -0
- package/ts/integrations/shelly/shelly.classes.client.ts +275 -137
- package/ts/integrations/shelly/shelly.classes.configflow.ts +24 -10
- package/ts/integrations/shelly/shelly.classes.integration.ts +109 -32
- package/ts/integrations/shelly/shelly.classes.subscription.ts +218 -0
- package/ts/integrations/shelly/shelly.discovery.ts +5 -2
- package/ts/integrations/shelly/shelly.rpc.ts +190 -0
- package/ts/integrations/shelly/shelly.types.ts +16 -4
- package/ts/integrations/sonos/index.ts +3 -0
- package/ts/integrations/sonos/readme.md +74 -0
- package/ts/integrations/sonos/sonos.classes.client.ts +153 -225
- package/ts/integrations/sonos/sonos.classes.configflow.ts +21 -8
- package/ts/integrations/sonos/sonos.classes.integration.ts +234 -72
- package/ts/integrations/sonos/sonos.classes.ssdpprobe.ts +85 -0
- package/ts/integrations/sonos/sonos.config.ts +57 -0
- package/ts/integrations/sonos/sonos.discovery.ts +5 -123
- package/ts/integrations/sonos/sonos.mapper.ts +29 -13
- package/ts/integrations/sonos/sonos.matchers.ts +83 -0
- package/ts/integrations/sonos/sonos.topology.ts +54 -0
- package/ts/integrations/sonos/sonos.types.ts +20 -8
- package/ts/integrations/sonos/sonos.xml.ts +19 -0
- package/ts/integrations/tasmota/index.ts +4 -0
- package/ts/integrations/tasmota/readme.md +33 -0
- package/ts/integrations/tasmota/tasmota.classes.integration.ts +27 -24
- package/ts/integrations/tasmota/tasmota.classes.runtime.ts +274 -0
- package/ts/integrations/tasmota/tasmota.config.ts +69 -0
- package/ts/integrations/tasmota/tasmota.discovery.ts +84 -0
- package/ts/integrations/tasmota/tasmota.mapper.ts +88 -0
- package/ts/integrations/tasmota/tasmota.types.ts +48 -2
- package/ts/integrations/tplink/index.ts +3 -0
- package/ts/integrations/tplink/readme.md +38 -0
- package/ts/integrations/tplink/tplink.classes.client.ts +56 -75
- package/ts/integrations/tplink/tplink.classes.configflow.ts +48 -100
- package/ts/integrations/tplink/tplink.classes.integration.ts +118 -40
- package/ts/integrations/tplink/tplink.discovery.ts +106 -235
- package/ts/integrations/tplink/tplink.native.mapper.ts +67 -0
- package/ts/integrations/tplink/tplink.native.types.ts +32 -0
- package/ts/integrations/tplink/tplink.validation.ts +50 -0
- package/ts/integrations/tradfri/tradfri.discovery.ts +52 -26
- package/ts/integrations/tuya/readme.md +106 -0
- package/ts/integrations/tuya/tuya.classes.integration.ts +127 -28
- package/ts/integrations/tuya/tuya.classes.runtime.ts +166 -0
- package/ts/integrations/tuya/tuya.mapper.ts +47 -0
- package/ts/integrations/tuya/tuya.types.ts +47 -2
- package/ts/integrations/tuya/tuya.validation.ts +118 -0
- package/ts/integrations/unifi/unifi.mapper.ts +8 -5
- package/ts/integrations/webostv/readme.md +48 -0
- package/ts/integrations/webostv/webostv.classes.client.ts +297 -6
- package/ts/integrations/webostv/webostv.classes.configflow.ts +18 -5
- package/ts/integrations/webostv/webostv.classes.integration.ts +92 -7
- package/ts/integrations/webostv/webostv.discovery.ts +22 -3
- package/ts/integrations/webostv/webostv.mapper.ts +27 -18
- package/ts/integrations/webostv/webostv.types.ts +47 -101
- package/ts/integrations/webostv/webostv.validation.ts +48 -0
- package/ts/integrations/wled/index.ts +1 -0
- package/ts/integrations/wled/readme.md +83 -0
- package/ts/integrations/wled/wled.classes.client.ts +208 -6
- package/ts/integrations/wled/wled.classes.configflow.ts +26 -5
- package/ts/integrations/wled/wled.classes.integration.ts +142 -7
- package/ts/integrations/wled/wled.classes.subscription.ts +122 -0
- package/ts/integrations/wled/wled.commands.ts +54 -0
- package/ts/integrations/wled/wled.discovery.ts +52 -3
- package/ts/integrations/wled/wled.errors.ts +9 -0
- package/ts/integrations/wled/wled.mapper.ts +39 -19
- package/ts/integrations/wled/wled.types.ts +59 -87
- package/ts/integrations/wled/wled.validation.ts +72 -0
- package/ts/integrations/yeelight/readme.md +47 -0
- package/ts/integrations/yeelight/yeelight.classes.client.ts +201 -302
- package/ts/integrations/yeelight/yeelight.classes.configflow.ts +23 -32
- package/ts/integrations/yeelight/yeelight.classes.integration.ts +115 -87
- package/ts/integrations/yeelight/yeelight.discovery.ts +78 -140
- package/ts/integrations/yeelight/yeelight.mapper.ts +61 -191
- package/ts/integrations/yeelight/yeelight.types.ts +31 -162
- package/ts/integrations/yeelight/yeelight.validation.ts +112 -0
- package/ts/integrations/zha/readme.md +23 -0
- package/ts/integrations/zha/zha.discovery.ts +92 -232
- package/ts/integrations/zha/zha.discoveryvalidation.ts +67 -0
- package/ts/integrations/zigbee2mqtt/index.ts +5 -0
- package/ts/integrations/zigbee2mqtt/readme.md +40 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.ts +26 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.ts +23 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.ts +414 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.ts +172 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.types.ts +63 -0
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.ts +65 -0
- package/ts/integrations/zwave_js/readme.md +23 -0
- package/ts/integrations/zwave_js/zwave_js.classes.client.ts +256 -136
- package/ts/integrations/zwave_js/zwave_js.classes.configflow.ts +26 -28
- package/ts/integrations/zwave_js/zwave_js.classes.integration.ts +65 -81
- package/ts/integrations/zwave_js/zwave_js.discovery.ts +100 -15
- package/ts/integrations/zwave_js/zwave_js.mapper.ts +129 -256
- package/ts/integrations/zwave_js/zwave_js.types.ts +32 -19
- package/ts/integrations/zwave_js/zwave_js.validation.ts +191 -0
- package/ts/plugins.ts +12 -3
- package/ts_migration/001.import-json-config.ts +81 -0
- package/ts_migration/index.ts +1 -0
- package/ts/integrations/tasmota/.generated-by-smarthome-exchange +0 -1
- package/ts/integrations/tuya/.generated-by-smarthome-exchange +0 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import { DeviceCommunicationError } from '../../core/errors.js';
|
|
3
|
+
import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IIntegrationEvent, IIntegrationRuntime, IServiceCallResult } from '../../core/types.js';
|
|
4
|
+
import { MqttClient } from '../mqtt/mqtt.classes.client.js';
|
|
5
|
+
import type { IMqttMessage } from '../mqtt/mqtt.types.js';
|
|
6
|
+
import { parseTasmotaRecord, tasmotaRecord, TasmotaMapper } from './tasmota.mapper.js';
|
|
7
|
+
import { normalizeTasmotaConfig } from './tasmota.config.js';
|
|
8
|
+
import type { IHomeAssistantTasmotaConfig, ITasmotaConfig, ITasmotaDeviceState, ITasmotaSelectedDevice } from './tasmota.types.js';
|
|
9
|
+
|
|
10
|
+
export class TasmotaRuntime implements IIntegrationRuntime {
|
|
11
|
+
public readonly domain = 'tasmota';
|
|
12
|
+
private readonly config: ITasmotaConfig;
|
|
13
|
+
private readonly client: MqttClient;
|
|
14
|
+
private readonly lifetime = new AbortController();
|
|
15
|
+
private readonly states = new Map<string, ITasmotaDeviceState>();
|
|
16
|
+
private readonly listeners = new Set<(eventArg: IIntegrationEvent) => void>();
|
|
17
|
+
private readonly changed = new Set<() => void>();
|
|
18
|
+
private readonly subscriptionCleanups = new Set<() => void>();
|
|
19
|
+
private readonly stopConnectionListener: () => void;
|
|
20
|
+
private initializing = true;
|
|
21
|
+
private started = false;
|
|
22
|
+
private destroyed = false;
|
|
23
|
+
private destroyPromise?: Promise<void>;
|
|
24
|
+
|
|
25
|
+
constructor(configArg: IHomeAssistantTasmotaConfig) {
|
|
26
|
+
this.config = normalizeTasmotaConfig(configArg);
|
|
27
|
+
this.client = new MqttClient(this.config.broker);
|
|
28
|
+
for (const device of this.config.devices) this.states.set(device.id, { generation: 0, ready: false, online: false, queryPending: false, updatedAt: new Date(0).toISOString(), controls: {}, sensors: {} });
|
|
29
|
+
this.stopConnectionListener = this.client.onConnectionState((stateArg) => {
|
|
30
|
+
if (this.destroyed) return;
|
|
31
|
+
if (!stateArg.connected) {
|
|
32
|
+
for (const device of this.config.devices) this.markOffline(device);
|
|
33
|
+
} else if (!this.initializing) {
|
|
34
|
+
this.refreshInBackground(this.config.devices);
|
|
35
|
+
}
|
|
36
|
+
if (stateArg.error) this.emit({ type: 'error', data: { message: stateArg.error.message } });
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async start(abortSignalArg?: AbortSignal): Promise<void> {
|
|
41
|
+
this.checkActive(abortSignalArg);
|
|
42
|
+
if (this.started) throw new DeviceCommunicationError('Tasmota runtime has already started.');
|
|
43
|
+
this.started = true;
|
|
44
|
+
try {
|
|
45
|
+
await this.withDeadline(async (signalArg) => {
|
|
46
|
+
await this.client.start(signalArg);
|
|
47
|
+
for (const device of this.config.devices) {
|
|
48
|
+
await this.client.subscribe(`${device.statusBase}#`, (messageArg) => this.receive(device, messageArg), signalArg);
|
|
49
|
+
await this.client.subscribe(`${device.telemetryBase}#`, (messageArg) => this.receive(device, messageArg), signalArg);
|
|
50
|
+
}
|
|
51
|
+
await this.refresh(this.config.devices, signalArg);
|
|
52
|
+
}, abortSignalArg);
|
|
53
|
+
this.initializing = false;
|
|
54
|
+
} catch (errorArg) {
|
|
55
|
+
await this.destroy();
|
|
56
|
+
throw errorArg;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public isHealthy(): boolean {
|
|
61
|
+
return !this.destroyed && this.client.isHealthy() && this.config.devices.every((deviceArg) => this.ready(deviceArg));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public async devices(abortSignalArg?: AbortSignal): Promise<plugins.shxInterfaces.data.IDeviceDefinition[]> {
|
|
65
|
+
this.checkActive(abortSignalArg);
|
|
66
|
+
return this.config.devices.map((deviceArg) => TasmotaMapper.device(deviceArg, this.state(deviceArg), this.client.connected));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public async entities(): Promise<IIntegrationEntity[]> {
|
|
70
|
+
return (await this.devices()).flatMap((deviceArg) => TasmotaMapper.entities(deviceArg));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public async subscribe(handlerArg: (eventArg: IIntegrationEvent) => void, abortSignalArg?: AbortSignal): Promise<() => Promise<void>> {
|
|
74
|
+
this.checkActive(abortSignalArg);
|
|
75
|
+
const listener = (eventArg: IIntegrationEvent): void => handlerArg(eventArg);
|
|
76
|
+
this.listeners.add(listener);
|
|
77
|
+
const cleanup = (): void => {
|
|
78
|
+
this.listeners.delete(listener);
|
|
79
|
+
abortSignalArg?.removeEventListener('abort', cleanup);
|
|
80
|
+
this.subscriptionCleanups.delete(cleanup);
|
|
81
|
+
};
|
|
82
|
+
this.subscriptionCleanups.add(cleanup);
|
|
83
|
+
abortSignalArg?.addEventListener('abort', cleanup, { once: true });
|
|
84
|
+
return async () => cleanup();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async writeFeature(requestArg: IDeviceFeatureWriteRequest, abortSignalArg?: AbortSignal): Promise<IServiceCallResult> {
|
|
88
|
+
this.checkActive(abortSignalArg);
|
|
89
|
+
if (requestArg.device.integrationDomain !== this.domain) return { success: false, error: 'Tasmota device is not selected.' };
|
|
90
|
+
const device = this.config.devices.find((deviceArg) => deviceArg.id === requestArg.device.id);
|
|
91
|
+
if (!device) return { success: false, error: 'Tasmota device is not selected.' };
|
|
92
|
+
if (!this.client.isHealthy() || !this.ready(device)) return { success: false, error: 'Tasmota device has no fresh online state.' };
|
|
93
|
+
const featureId = requestArg.feature.id;
|
|
94
|
+
let command: string;
|
|
95
|
+
let payload: string;
|
|
96
|
+
const relay = device.relays.find((relayArg) => featureId === `power_${relayArg}`);
|
|
97
|
+
if (relay !== undefined && typeof requestArg.value === 'boolean') {
|
|
98
|
+
command = `POWER${relay}`;
|
|
99
|
+
payload = requestArg.value ? 'ON' : 'OFF';
|
|
100
|
+
} else if (featureId === 'brightness' && device.brightness && typeof requestArg.value === 'number' && Number.isInteger(requestArg.value) && requestArg.value >= 0 && requestArg.value <= 100) {
|
|
101
|
+
command = 'Dimmer';
|
|
102
|
+
payload = String(requestArg.value);
|
|
103
|
+
} else {
|
|
104
|
+
return { success: false, error: 'Tasmota write requires a selected relay boolean or brightness integer from 0 through 100.' };
|
|
105
|
+
}
|
|
106
|
+
await this.client.publish({ topic: `${device.commandBase}${command}`, payload, qos: 0, retain: false }, abortSignalArg);
|
|
107
|
+
return { success: true, data: { accepted: true } };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public destroy(): Promise<void> {
|
|
111
|
+
if (this.destroyPromise) return this.destroyPromise;
|
|
112
|
+
this.destroyed = true;
|
|
113
|
+
this.stopConnectionListener();
|
|
114
|
+
this.lifetime.abort(new DeviceCommunicationError('Tasmota runtime destroyed.'));
|
|
115
|
+
for (const cleanup of [...this.subscriptionCleanups]) cleanup();
|
|
116
|
+
this.listeners.clear();
|
|
117
|
+
this.changed.clear();
|
|
118
|
+
this.destroyPromise = this.client.destroy();
|
|
119
|
+
return this.destroyPromise;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private state(deviceArg: ITasmotaSelectedDevice): ITasmotaDeviceState {
|
|
123
|
+
const state = this.states.get(deviceArg.id);
|
|
124
|
+
if (!state) throw new DeviceCommunicationError('Selected Tasmota device state is missing.');
|
|
125
|
+
return state;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private ready(deviceArg: ITasmotaSelectedDevice): boolean {
|
|
129
|
+
const state = this.state(deviceArg);
|
|
130
|
+
return state.ready && state.online;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private checkActive(abortSignalArg?: AbortSignal): void {
|
|
134
|
+
abortSignalArg?.throwIfAborted();
|
|
135
|
+
this.lifetime.signal.throwIfAborted();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private async withDeadline<TValue>(operationArg: (signalArg: AbortSignal) => Promise<TValue>, abortSignalArg?: AbortSignal): Promise<TValue> {
|
|
139
|
+
const deadline = new AbortController();
|
|
140
|
+
const timer = setTimeout(() => deadline.abort(new DeviceCommunicationError('Tasmota fresh state deadline exceeded.')), this.config.initialSnapshotTimeoutMs);
|
|
141
|
+
const signal = AbortSignal.any([this.lifetime.signal, deadline.signal, ...(abortSignalArg ? [abortSignalArg] : [])]);
|
|
142
|
+
try {
|
|
143
|
+
signal.throwIfAborted();
|
|
144
|
+
return await operationArg(signal);
|
|
145
|
+
} finally {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
deadline.abort();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private async refresh(devicesArg: ITasmotaSelectedDevice[], signalArg: AbortSignal, generationsArg = new Map<string, number>()): Promise<void> {
|
|
152
|
+
for (const device of devicesArg) {
|
|
153
|
+
const state = this.state(device);
|
|
154
|
+
state.ready = false;
|
|
155
|
+
state.queryPending = true;
|
|
156
|
+
state.generation += 1;
|
|
157
|
+
generationsArg.set(device.id, state.generation);
|
|
158
|
+
}
|
|
159
|
+
for (const handler of this.changed) handler();
|
|
160
|
+
const fresh = this.waitForFresh(devicesArg, generationsArg, signalArg);
|
|
161
|
+
const queries = async (): Promise<void> => {
|
|
162
|
+
for (const device of devicesArg) {
|
|
163
|
+
await this.client.publish({ topic: `${device.commandBase}State`, payload: '', qos: 0, retain: false }, signalArg);
|
|
164
|
+
await this.client.publish({ topic: `${device.commandBase}Status`, payload: '10', qos: 0, retain: false }, signalArg);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
await Promise.all([fresh, queries()]);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private refreshInBackground(devicesArg: ITasmotaSelectedDevice[]): void {
|
|
171
|
+
const generations = new Map<string, number>();
|
|
172
|
+
void this.withDeadline((signalArg) => this.refresh(devicesArg, signalArg, generations)).catch((errorArg: unknown) => {
|
|
173
|
+
if (this.destroyed) return;
|
|
174
|
+
const currentDevices = devicesArg.filter((deviceArg) => this.state(deviceArg).generation === generations.get(deviceArg.id));
|
|
175
|
+
if (!currentDevices.length) return;
|
|
176
|
+
for (const device of currentDevices) this.markOffline(device);
|
|
177
|
+
this.emit({ type: 'error', data: { message: errorArg instanceof Error ? errorArg.message : 'Tasmota state refresh failed.' } });
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private waitForFresh(devicesArg: ITasmotaSelectedDevice[], generationsArg: Map<string, number>, signalArg: AbortSignal): Promise<void> {
|
|
182
|
+
return new Promise<void>((resolve, reject) => {
|
|
183
|
+
const cleanup = (): void => {
|
|
184
|
+
this.changed.delete(check);
|
|
185
|
+
signalArg.removeEventListener('abort', aborted);
|
|
186
|
+
};
|
|
187
|
+
const check = (): void => {
|
|
188
|
+
if (devicesArg.some((deviceArg) => this.state(deviceArg).generation !== generationsArg.get(deviceArg.id))) {
|
|
189
|
+
cleanup();
|
|
190
|
+
reject(new DeviceCommunicationError('Tasmota state refresh superseded by a connection or availability change.'));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (this.client.connected && devicesArg.every((deviceArg) => this.ready(deviceArg))) {
|
|
194
|
+
cleanup();
|
|
195
|
+
resolve();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
const aborted = (): void => {
|
|
199
|
+
cleanup();
|
|
200
|
+
reject(signalArg.reason);
|
|
201
|
+
};
|
|
202
|
+
this.changed.add(check);
|
|
203
|
+
signalArg.addEventListener('abort', aborted, { once: true });
|
|
204
|
+
if (signalArg.aborted) aborted();
|
|
205
|
+
else check();
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private markOffline(deviceArg: ITasmotaSelectedDevice): void {
|
|
210
|
+
const state = this.state(deviceArg);
|
|
211
|
+
const wasOnline = this.ready(deviceArg);
|
|
212
|
+
state.ready = false;
|
|
213
|
+
state.online = false;
|
|
214
|
+
state.queryPending = false;
|
|
215
|
+
state.generation += 1;
|
|
216
|
+
if (wasOnline) this.emit({ type: 'availability_changed', deviceId: deviceArg.id, data: { online: false } });
|
|
217
|
+
for (const handler of this.changed) handler();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private receive(deviceArg: ITasmotaSelectedDevice, messageArg: IMqttMessage): void {
|
|
221
|
+
if (this.destroyed) return;
|
|
222
|
+
const status = messageArg.topic.startsWith(deviceArg.statusBase);
|
|
223
|
+
const suffix = messageArg.topic.slice((status ? deviceArg.statusBase : deviceArg.telemetryBase).length);
|
|
224
|
+
const state = this.state(deviceArg);
|
|
225
|
+
if (!status && suffix === 'LWT') {
|
|
226
|
+
if (messageArg.payload === 'Offline') this.markOffline(deviceArg);
|
|
227
|
+
else if (messageArg.payload === 'Online' && !this.ready(deviceArg) && !state.queryPending && !this.initializing) this.refreshInBackground([deviceArg]);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (messageArg.retain && state.ready) return;
|
|
231
|
+
let record = parseTasmotaRecord(messageArg.payload);
|
|
232
|
+
if (status && /^POWER(?:[1-9]\d*)?$/u.test(suffix) && typeof messageArg.payload === 'string') record = { [suffix]: messageArg.payload };
|
|
233
|
+
if (!record) {
|
|
234
|
+
if (['RESULT', 'STATE', 'SENSOR', 'STATUS10', 'STATUS11'].includes(suffix)) this.emit({ type: 'error', deviceId: deviceArg.id, data: { message: 'Invalid Tasmota JSON state message.' } });
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const sensorRecord = suffix === 'STATUS10' ? tasmotaRecord(record.StatusSNS) : suffix === 'SENSOR' ? record : undefined;
|
|
238
|
+
if (sensorRecord) {
|
|
239
|
+
state.sensors = TasmotaMapper.sensors(sensorRecord);
|
|
240
|
+
state.updatedAt = new Date().toISOString();
|
|
241
|
+
} else if (['RESULT', 'STATE', 'STATUS11'].includes(suffix) || /^POWER(?:[1-9]\d*)?$/u.test(suffix)) {
|
|
242
|
+
const controlRecord = suffix === 'STATUS11' ? tasmotaRecord(record.StatusSTS) : record;
|
|
243
|
+
if (!controlRecord) return;
|
|
244
|
+
const controls = TasmotaMapper.controls(deviceArg, controlRecord);
|
|
245
|
+
state.updatedAt = new Date().toISOString();
|
|
246
|
+
const fullState = suffix === 'STATE' || suffix === 'STATUS11' || (suffix === 'RESULT' && (typeof controlRecord.Time === 'string' || typeof controlRecord.Uptime === 'string' || typeof controlRecord.UptimeSec === 'number'));
|
|
247
|
+
const invalidRelay = deviceArg.relays.some((relayArg) => (controlRecord[`POWER${relayArg}`] !== undefined || (relayArg === 1 && controlRecord.POWER !== undefined)) && controls[`power_${relayArg}`] === undefined);
|
|
248
|
+
const invalidDimmer = deviceArg.brightness && controlRecord.Dimmer !== undefined && controls.brightness === undefined;
|
|
249
|
+
if ((fullState && !TasmotaMapper.completeControls(deviceArg, controls)) || invalidRelay || invalidDimmer) {
|
|
250
|
+
state.controls = controls;
|
|
251
|
+
this.markOffline(deviceArg);
|
|
252
|
+
this.emit({ type: 'error', deviceId: deviceArg.id, data: { message: 'Tasmota state does not report valid configured controls.' } });
|
|
253
|
+
this.emit({ type: 'state_changed', deviceId: deviceArg.id });
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (fullState) state.controls = controls;
|
|
257
|
+
else Object.assign(state.controls, controls);
|
|
258
|
+
if (fullState && !messageArg.retain && state.queryPending && TasmotaMapper.completeControls(deviceArg, controls)) {
|
|
259
|
+
state.ready = true;
|
|
260
|
+
state.online = true;
|
|
261
|
+
state.queryPending = false;
|
|
262
|
+
this.emit({ type: 'availability_changed', deviceId: deviceArg.id, data: { online: true } });
|
|
263
|
+
}
|
|
264
|
+
} else return;
|
|
265
|
+
this.emit({ type: 'state_changed', deviceId: deviceArg.id });
|
|
266
|
+
for (const handler of this.changed) handler();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private emit(eventArg: Omit<IIntegrationEvent, 'integrationDomain' | 'timestamp'>): void {
|
|
270
|
+
if (this.destroyed) return;
|
|
271
|
+
const event: IIntegrationEvent = { ...eventArg, integrationDomain: this.domain, timestamp: Date.now() };
|
|
272
|
+
for (const handler of this.listeners) handler(event);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { IntegrationError } from '../../core/errors.js';
|
|
2
|
+
import type { IHomeAssistantTasmotaConfig, ITasmotaConfig, ITasmotaDeviceConfig, ITasmotaSelectedDevice } from './tasmota.types.js';
|
|
3
|
+
|
|
4
|
+
const fail = (messageArg: string): never => {
|
|
5
|
+
throw new IntegrationError(messageArg, 'INVALID_TASMOTA_CONFIG');
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const topicPart = (valueArg: unknown, labelArg: string): string => {
|
|
9
|
+
if (typeof valueArg !== 'string' || !valueArg.trim() || /[+#\u0000-\u001f\u007f]/u.test(valueArg) || valueArg !== valueArg.trim()) {
|
|
10
|
+
return fail(`${labelArg} must be a nonempty MQTT topic without wildcards or control characters.`);
|
|
11
|
+
}
|
|
12
|
+
return valueArg;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const selectedDevice = (deviceArg: ITasmotaDeviceConfig): ITasmotaSelectedDevice => {
|
|
16
|
+
if (!deviceArg || typeof deviceArg !== 'object') return fail('Every Tasmota device must be a config object.');
|
|
17
|
+
const topic = topicPart(deviceArg.topic, 'Tasmota topic');
|
|
18
|
+
const fullTopic = deviceArg.fullTopic ?? '%prefix%/%topic%/';
|
|
19
|
+
if (typeof fullTopic !== 'string' || fullTopic.length > 100 || !fullTopic.endsWith('/') || fullTopic.split('%prefix%').length !== 2 || fullTopic.split('%topic%').length !== 2 || /%/u.test(fullTopic.replace('%prefix%', '').replace('%topic%', ''))) {
|
|
20
|
+
return fail('FullTopic must end in / and contain exactly one %prefix% and one %topic%; other tokens are unsupported.');
|
|
21
|
+
}
|
|
22
|
+
const prefixes = deviceArg.prefixes ?? { command: 'cmnd', status: 'stat', telemetry: 'tele' };
|
|
23
|
+
if (!prefixes || typeof prefixes !== 'object') return fail('Tasmota prefixes must specify command, status and telemetry strings.');
|
|
24
|
+
if (deviceArg.name !== undefined && (typeof deviceArg.name !== 'string' || !deviceArg.name.trim())) return fail('Tasmota name must be a nonempty string.');
|
|
25
|
+
if (deviceArg.model !== undefined && typeof deviceArg.model !== 'string') return fail('Tasmota model must be a string.');
|
|
26
|
+
const base = (prefixArg: string): string => {
|
|
27
|
+
const prefix = topicPart(prefixArg, 'Tasmota prefix');
|
|
28
|
+
return topicPart(fullTopic.replace(/%prefix%|%topic%/gu, (tokenArg) => tokenArg === '%prefix%' ? prefix : topic), 'Tasmota FullTopic');
|
|
29
|
+
};
|
|
30
|
+
const relays = deviceArg.relays ?? [1];
|
|
31
|
+
if (!Array.isArray(relays) || relays.some((relayArg) => !Number.isInteger(relayArg) || relayArg < 1 || relayArg > 32) || new Set(relays).size !== relays.length) {
|
|
32
|
+
return fail('Tasmota relays must be unique integers from 1 through 32.');
|
|
33
|
+
}
|
|
34
|
+
if (deviceArg.brightness !== undefined && typeof deviceArg.brightness !== 'boolean') return fail('Tasmota brightness must be boolean.');
|
|
35
|
+
const powerOnPayload = deviceArg.powerOnPayload ?? 'ON';
|
|
36
|
+
const powerOffPayload = deviceArg.powerOffPayload ?? 'OFF';
|
|
37
|
+
if (typeof powerOnPayload !== 'string' || !powerOnPayload || typeof powerOffPayload !== 'string' || !powerOffPayload || powerOnPayload === powerOffPayload) return fail('Tasmota power state texts must be distinct nonempty strings.');
|
|
38
|
+
return {
|
|
39
|
+
id: deviceArg.id === undefined ? `tasmota:${encodeURIComponent(topic)}` : topicPart(deviceArg.id, 'Tasmota device id'),
|
|
40
|
+
topic,
|
|
41
|
+
name: deviceArg.name ?? topic,
|
|
42
|
+
model: deviceArg.model,
|
|
43
|
+
commandBase: base(prefixes.command),
|
|
44
|
+
statusBase: base(prefixes.status),
|
|
45
|
+
telemetryBase: base(prefixes.telemetry),
|
|
46
|
+
relays: [...relays].sort((leftArg, rightArg) => leftArg - rightArg),
|
|
47
|
+
brightness: deviceArg.brightness ?? false,
|
|
48
|
+
powerOnPayload,
|
|
49
|
+
powerOffPayload,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const normalizeTasmotaConfig = (configArg: IHomeAssistantTasmotaConfig): ITasmotaConfig => {
|
|
54
|
+
if (!configArg || typeof configArg !== 'object' || !configArg.broker || typeof configArg.broker.host !== 'string' || !configArg.broker.host.trim() || configArg.broker.host !== configArg.broker.host.trim()) return fail('Tasmota requires a real MQTT broker host without surrounding whitespace.');
|
|
55
|
+
if (configArg.broker.port !== undefined && (!Number.isInteger(configArg.broker.port) || configArg.broker.port < 1 || configArg.broker.port > 65_535)) return fail('Tasmota broker port must be an integer from 1 through 65535.');
|
|
56
|
+
if (configArg.broker.protocol !== undefined && configArg.broker.protocol !== 'mqtt' && configArg.broker.protocol !== 'mqtts') return fail('Tasmota broker protocol must be mqtt or mqtts.');
|
|
57
|
+
if (!Array.isArray(configArg.devices) || !configArg.devices.length || configArg.devices.length > 128) return fail('Select from 1 through 128 Tasmota devices.');
|
|
58
|
+
const devices = configArg.devices.map(selectedDevice);
|
|
59
|
+
if (new Set(devices.map((deviceArg) => deviceArg.id)).size !== devices.length) return fail('Selected Tasmota device ids must be unique.');
|
|
60
|
+
const bases = devices.flatMap((deviceArg) => [deviceArg.commandBase, deviceArg.statusBase, deviceArg.telemetryBase]);
|
|
61
|
+
if (bases.some((baseArg, indexArg) => bases.some((otherArg, otherIndexArg) => indexArg !== otherIndexArg && baseArg.startsWith(otherArg)))) return fail('Selected Tasmota FullTopics and prefixes must not overlap.');
|
|
62
|
+
const initialSnapshotTimeoutMs = configArg.initialSnapshotTimeoutMs ?? 10_000;
|
|
63
|
+
if (!Number.isInteger(initialSnapshotTimeoutMs) || initialSnapshotTimeoutMs < 1 || initialSnapshotTimeoutMs > 2_147_483_647) return fail('initialSnapshotTimeoutMs must be a timer-safe positive integer.');
|
|
64
|
+
return {
|
|
65
|
+
devices,
|
|
66
|
+
initialSnapshotTimeoutMs,
|
|
67
|
+
broker: { ...configArg.broker, discovery: false, birthMessage: false, willMessage: false, subscriptions: [], entities: [], discoveryMessages: [], retainedMessages: [] },
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { DiscoveryDescriptor } from '../../core/classes.discoverydescriptor.js';
|
|
2
|
+
import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate, IDiscoveryMatch, IDiscoveryMatcher, IDiscoveryValidator } from '../../core/types.js';
|
|
3
|
+
import { normalizeTasmotaConfig } from './tasmota.config.js';
|
|
4
|
+
import type { IHomeAssistantTasmotaConfig } from './tasmota.types.js';
|
|
5
|
+
|
|
6
|
+
class TasmotaManualMatcher implements IDiscoveryMatcher<IDiscoveryCandidate> {
|
|
7
|
+
public readonly id = 'tasmota-selected-device';
|
|
8
|
+
public readonly source = 'manual' as const;
|
|
9
|
+
|
|
10
|
+
public async matches(candidateArg: IDiscoveryCandidate): Promise<IDiscoveryMatch> {
|
|
11
|
+
const topic = candidateArg.metadata?.topic;
|
|
12
|
+
const matched = candidateArg.integrationDomain === 'tasmota' && typeof candidateArg.host === 'string' && Boolean(candidateArg.host) && typeof topic === 'string' && Boolean(topic);
|
|
13
|
+
return {
|
|
14
|
+
matched,
|
|
15
|
+
confidence: matched ? 'high' : 'low',
|
|
16
|
+
reason: matched ? 'Selected Tasmota device has a broker host and device topic; setup verifies live state.' : 'Tasmota requires an explicit broker host and device topic.',
|
|
17
|
+
candidate: matched ? candidateArg : undefined,
|
|
18
|
+
normalizedDeviceId: matched ? `tasmota:${encodeURIComponent(topic)}` : undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class TasmotaCandidateValidator implements IDiscoveryValidator {
|
|
24
|
+
public readonly id = 'tasmota-selected-device-validator';
|
|
25
|
+
|
|
26
|
+
public async validate(candidateArg: IDiscoveryCandidate): Promise<IDiscoveryMatch> {
|
|
27
|
+
return new TasmotaManualMatcher().matches(candidateArg);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const createTasmotaDiscoveryDescriptor = (): DiscoveryDescriptor => {
|
|
32
|
+
return new DiscoveryDescriptor({ integrationDomain: 'tasmota', displayName: 'Tasmota' })
|
|
33
|
+
.addMatcher(new TasmotaManualMatcher())
|
|
34
|
+
.addValidator(new TasmotaCandidateValidator());
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export class TasmotaConfigFlow implements IConfigFlow<IHomeAssistantTasmotaConfig> {
|
|
38
|
+
public async start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IHomeAssistantTasmotaConfig>> {
|
|
39
|
+
void contextArg;
|
|
40
|
+
return {
|
|
41
|
+
kind: 'form',
|
|
42
|
+
title: 'Connect a selected Tasmota device',
|
|
43
|
+
description: 'Use the device MQTT broker, unique Topic and FullTopic. The device must already be configured for this broker.',
|
|
44
|
+
fields: [
|
|
45
|
+
{ name: 'host', label: 'MQTT broker host', type: 'text', required: true },
|
|
46
|
+
{ name: 'port', label: 'MQTT broker port', type: 'number' },
|
|
47
|
+
{ name: 'useTls', label: 'Use MQTT TLS', type: 'boolean' },
|
|
48
|
+
{ name: 'username', label: 'Broker username', type: 'text' },
|
|
49
|
+
{ name: 'password', label: 'Broker password', type: 'password' },
|
|
50
|
+
{ name: 'topic', label: 'Device Topic', type: 'text', required: true },
|
|
51
|
+
{ name: 'fullTopic', label: 'FullTopic', type: 'text' },
|
|
52
|
+
{ name: 'relayCount', label: 'Relay count (0 through 32)', type: 'number' },
|
|
53
|
+
{ name: 'brightness', label: 'Single-channel Dimmer', type: 'boolean' },
|
|
54
|
+
],
|
|
55
|
+
submit: async (valuesArg) => {
|
|
56
|
+
try {
|
|
57
|
+
for (const field of ['username', 'password', 'fullTopic']) if (valuesArg[field] !== undefined && typeof valuesArg[field] !== 'string') throw new Error(`${field} must be a string.`);
|
|
58
|
+
for (const field of ['useTls', 'brightness']) if (valuesArg[field] !== undefined && typeof valuesArg[field] !== 'boolean') throw new Error(`${field} must be boolean.`);
|
|
59
|
+
const relayCount = valuesArg.relayCount ?? 1;
|
|
60
|
+
if (typeof relayCount !== 'number' || !Number.isInteger(relayCount) || relayCount < 0 || relayCount > 32) throw new Error('relayCount must be an integer from 0 through 32.');
|
|
61
|
+
const host = valuesArg.host ?? candidateArg.host;
|
|
62
|
+
const topic = valuesArg.topic ?? candidateArg.metadata?.topic;
|
|
63
|
+
if (typeof host !== 'string' || typeof topic !== 'string') throw new Error('Broker host and device topic are required.');
|
|
64
|
+
const port = valuesArg.port ?? candidateArg.port;
|
|
65
|
+
if (port !== undefined && (typeof port !== 'number' || !Number.isInteger(port) || port < 1 || port > 65_535)) throw new Error('Broker port must be an integer from 1 through 65535.');
|
|
66
|
+
const config: IHomeAssistantTasmotaConfig = {
|
|
67
|
+
broker: {
|
|
68
|
+
host,
|
|
69
|
+
port,
|
|
70
|
+
protocol: valuesArg.useTls === true ? 'mqtts' : 'mqtt',
|
|
71
|
+
username: typeof valuesArg.username === 'string' ? valuesArg.username : undefined,
|
|
72
|
+
password: typeof valuesArg.password === 'string' ? valuesArg.password : undefined,
|
|
73
|
+
},
|
|
74
|
+
devices: [{ topic, fullTopic: typeof valuesArg.fullTopic === 'string' && valuesArg.fullTopic ? valuesArg.fullTopic : undefined, relays: Array.from({ length: relayCount }, (_, indexArg) => indexArg + 1), brightness: valuesArg.brightness === true }],
|
|
75
|
+
};
|
|
76
|
+
normalizeTasmotaConfig(config);
|
|
77
|
+
return { kind: 'done', title: 'Selected Tasmota device configured', config };
|
|
78
|
+
} catch (errorArg) {
|
|
79
|
+
return { kind: 'error', error: errorArg instanceof Error ? errorArg.message : 'Invalid Tasmota configuration.' };
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import type { IIntegrationEntity } from '../../core/types.js';
|
|
3
|
+
import type { ITasmotaDeviceState, ITasmotaSelectedDevice } from './tasmota.types.js';
|
|
4
|
+
|
|
5
|
+
export const tasmotaRecord = (valueArg: unknown): Record<string, unknown> | undefined => {
|
|
6
|
+
return valueArg !== null && typeof valueArg === 'object' && !Array.isArray(valueArg) ? valueArg as Record<string, unknown> : undefined;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const parseTasmotaRecord = (payloadArg: unknown): Record<string, unknown> | undefined => {
|
|
10
|
+
if (typeof payloadArg !== 'string') return tasmotaRecord(payloadArg);
|
|
11
|
+
try {
|
|
12
|
+
return tasmotaRecord(JSON.parse(payloadArg));
|
|
13
|
+
} catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class TasmotaMapper {
|
|
19
|
+
public static controls(deviceArg: ITasmotaSelectedDevice, recordArg: Record<string, unknown>): Record<string, boolean | number> {
|
|
20
|
+
const controls: Record<string, boolean | number> = {};
|
|
21
|
+
for (const relay of deviceArg.relays) {
|
|
22
|
+
const value = recordArg[`POWER${relay}`] ?? (relay === 1 ? recordArg.POWER : undefined);
|
|
23
|
+
if (value === deviceArg.powerOnPayload) controls[`power_${relay}`] = true;
|
|
24
|
+
if (value === deviceArg.powerOffPayload) controls[`power_${relay}`] = false;
|
|
25
|
+
}
|
|
26
|
+
if (deviceArg.brightness && typeof recordArg.Dimmer === 'number' && Number.isInteger(recordArg.Dimmer) && recordArg.Dimmer >= 0 && recordArg.Dimmer <= 100) controls.brightness = recordArg.Dimmer;
|
|
27
|
+
return controls;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public static completeControls(deviceArg: ITasmotaSelectedDevice, controlsArg: Record<string, boolean | number>): boolean {
|
|
31
|
+
return deviceArg.relays.every((relayArg) => typeof controlsArg[`power_${relayArg}`] === 'boolean') && (!deviceArg.brightness || typeof controlsArg.brightness === 'number');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public static sensors(recordArg: Record<string, unknown>): Record<string, number | boolean | string> {
|
|
35
|
+
const sensors: Record<string, number | boolean | string> = {};
|
|
36
|
+
const visit = (recordArg: Record<string, unknown>, pathArg: string[], depthArg: number): void => {
|
|
37
|
+
if (depthArg > 6) return;
|
|
38
|
+
for (const [key, value] of Object.entries(recordArg)) {
|
|
39
|
+
if (!pathArg.length && ['Time', 'TempUnit', 'PressureUnit'].includes(key)) continue;
|
|
40
|
+
const path = [...pathArg, key];
|
|
41
|
+
const child = tasmotaRecord(value);
|
|
42
|
+
if (child) visit(child, path, depthArg + 1);
|
|
43
|
+
else if (typeof value === 'boolean' || typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))) {
|
|
44
|
+
if (Object.keys(sensors).length >= 256) return;
|
|
45
|
+
sensors[`sensor_${path.map(encodeURIComponent).join('/')}`] = value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
visit(recordArg, [], 0);
|
|
50
|
+
return sensors;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static device(deviceArg: ITasmotaSelectedDevice, stateArg: ITasmotaDeviceState, connectedArg: boolean): plugins.shxInterfaces.data.IDeviceDefinition {
|
|
54
|
+
const features: plugins.shxInterfaces.data.IDeviceFeature[] = deviceArg.relays.map((relayArg) => ({ id: `power_${relayArg}`, capability: 'switch', name: `Relay ${relayArg}`, readable: true, writable: true }));
|
|
55
|
+
if (deviceArg.brightness) features.push({ id: 'brightness', capability: 'light', name: 'Brightness', readable: true, writable: true, unit: '%' });
|
|
56
|
+
for (const id of Object.keys(stateArg.sensors).sort()) features.push({ id, capability: id.startsWith('sensor_ENERGY/') ? 'energy' : 'sensor', name: id.slice('sensor_'.length).split('/').map(decodeURIComponent).join(' '), readable: true, writable: false });
|
|
57
|
+
const values = { ...stateArg.controls, ...stateArg.sensors };
|
|
58
|
+
return {
|
|
59
|
+
id: deviceArg.id,
|
|
60
|
+
integrationDomain: 'tasmota',
|
|
61
|
+
name: deviceArg.name,
|
|
62
|
+
protocol: 'mqtt',
|
|
63
|
+
manufacturer: 'Tasmota',
|
|
64
|
+
model: deviceArg.model,
|
|
65
|
+
online: connectedArg && stateArg.ready && stateArg.online,
|
|
66
|
+
features,
|
|
67
|
+
state: features.map((featureArg) => ({ featureId: featureArg.id, value: values[featureArg.id] ?? null, updatedAt: stateArg.updatedAt })),
|
|
68
|
+
metadata: { topic: deviceArg.topic, stateSource: 'tasmota-mqtt', fresh: stateArg.ready },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public static entities(deviceArg: plugins.shxInterfaces.data.IDeviceDefinition): IIntegrationEntity[] {
|
|
73
|
+
return deviceArg.features.map((featureArg) => {
|
|
74
|
+
const platform = featureArg.capability === 'switch' ? 'switch' : featureArg.capability === 'light' ? 'light' : 'sensor';
|
|
75
|
+
return {
|
|
76
|
+
id: `${platform}.${encodeURIComponent(deviceArg.id)}.${encodeURIComponent(featureArg.id)}`,
|
|
77
|
+
uniqueId: `${deviceArg.id}:${featureArg.id}`,
|
|
78
|
+
integrationDomain: 'tasmota',
|
|
79
|
+
deviceId: deviceArg.id,
|
|
80
|
+
platform,
|
|
81
|
+
name: `${deviceArg.name} ${featureArg.name}`,
|
|
82
|
+
state: deviceArg.state.find((stateArg) => stateArg.featureId === featureArg.id)?.value ?? null,
|
|
83
|
+
available: deviceArg.online,
|
|
84
|
+
attributes: { featureId: featureArg.id, unit: featureArg.unit },
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -1,4 +1,50 @@
|
|
|
1
|
+
import type { IMqttConfig } from '../mqtt/mqtt.types.js';
|
|
2
|
+
|
|
3
|
+
export interface ITasmotaDeviceConfig {
|
|
4
|
+
topic: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
fullTopic?: string;
|
|
9
|
+
prefixes?: { command: string; status: string; telemetry: string };
|
|
10
|
+
relays?: number[];
|
|
11
|
+
brightness?: boolean;
|
|
12
|
+
powerOnPayload?: string;
|
|
13
|
+
powerOffPayload?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
1
16
|
export interface IHomeAssistantTasmotaConfig {
|
|
2
|
-
|
|
3
|
-
|
|
17
|
+
broker: IMqttConfig & { host: string };
|
|
18
|
+
devices: ITasmotaDeviceConfig[];
|
|
19
|
+
initialSnapshotTimeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ITasmotaSelectedDevice {
|
|
23
|
+
id: string;
|
|
24
|
+
topic: string;
|
|
25
|
+
name: string;
|
|
26
|
+
model?: string;
|
|
27
|
+
commandBase: string;
|
|
28
|
+
statusBase: string;
|
|
29
|
+
telemetryBase: string;
|
|
30
|
+
relays: number[];
|
|
31
|
+
brightness: boolean;
|
|
32
|
+
powerOnPayload: string;
|
|
33
|
+
powerOffPayload: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ITasmotaConfig {
|
|
37
|
+
broker: IMqttConfig & { host: string };
|
|
38
|
+
devices: ITasmotaSelectedDevice[];
|
|
39
|
+
initialSnapshotTimeoutMs: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ITasmotaDeviceState {
|
|
43
|
+
generation: number;
|
|
44
|
+
ready: boolean;
|
|
45
|
+
online: boolean;
|
|
46
|
+
queryPending: boolean;
|
|
47
|
+
updatedAt: string;
|
|
48
|
+
controls: Record<string, boolean | number>;
|
|
49
|
+
sensors: Record<string, number | boolean | string>;
|
|
4
50
|
}
|
|
@@ -4,3 +4,6 @@ export * from './tplink.classes.integration.js';
|
|
|
4
4
|
export * from './tplink.discovery.js';
|
|
5
5
|
export * from './tplink.mapper.js';
|
|
6
6
|
export * from './tplink.types.js';
|
|
7
|
+
export * from './tplink.native.types.js';
|
|
8
|
+
export * from './tplink.native.mapper.js';
|
|
9
|
+
export * from './tplink.validation.js';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# TP-Link legacy Kasa
|
|
2
|
+
|
|
3
|
+
`TplinkIntegration` provides a native local TCP runtime for the single relay advertised by legacy `IOT.SMARTPLUGSWITCH` devices. The integration delegates legacy XOR framing, same-connection identity and capability preflight, bounded operation queues, cancellation, and terminal socket cleanup to `@ecobridge.xyz/devicemanager` `KasaProtocol` (available from version `4.3.0`).
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { TplinkIntegration } from '@smarthome.exchange/integrations';
|
|
7
|
+
|
|
8
|
+
const integration = new TplinkIntegration();
|
|
9
|
+
const runtime = await integration.setup({
|
|
10
|
+
homeId: 'your-home-id',
|
|
11
|
+
transport: 'legacy-kasa',
|
|
12
|
+
host: '192.168.1.40',
|
|
13
|
+
expectedDeviceId: '800611223344556677889900AABBCCDDEEFF001122',
|
|
14
|
+
}, {});
|
|
15
|
+
try {
|
|
16
|
+
const [device] = await runtime.devices();
|
|
17
|
+
const [entity] = await runtime.entities();
|
|
18
|
+
const result = await runtime.callService!({
|
|
19
|
+
domain: 'switch', service: 'turn_on', target: { entityId: entity.id },
|
|
20
|
+
});
|
|
21
|
+
console.log(result);
|
|
22
|
+
console.log((await runtime.devices())[0].state);
|
|
23
|
+
} finally {
|
|
24
|
+
await integration.destroy();
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Configuration requires an explicit home ID, literal unicast IP address, expected legacy device ID, and `transport: 'legacy-kasa'`. Port defaults to `9999`; `timeoutMs` defaults to `5000` and covers queue admission, connection, identity preflight and the response. Resource limits are `maxResponseBytes` (default `65536`, range `128–1048576`) and `maxPendingOperations` (default `16`, range `1–128`). The deadline range is `1–30000` ms. Discovery advertisements are hints: actual legacy system information must verify identity and single-relay support before setup succeeds.
|
|
29
|
+
|
|
30
|
+
The runtime exposes one writable `power` switch feature and one switch entity. IDs contain both the home and observed device identity. It admits only exact owned targets, `switch.turn_on`, `switch.turn_off`, or a boolean `power` feature write. Toggle, broadcast targets, additional service data and unsupported features are rejected before any write. `devices()` and `entities()` obtain fresh authoritative system information. Subscriptions observe these explicit reads; the integration does not claim a push protocol or run automatic polling.
|
|
31
|
+
|
|
32
|
+
A successful write reports `outcome: 'accepted'` and `physicalStateConfirmed: false`. A protocol acknowledgment confirms acceptance only, never physical completion. Subsequent reads remain authoritative; there is no optimistic state update. Rejections report `not-sent`, `rejected` or `indeterminate`; an indeterminate effect must not be retried automatically. No command is retried or automatically reconnected. Destroy is terminal and idempotent, cancels queued and active work, drains owned sockets, and releases subscriptions.
|
|
33
|
+
|
|
34
|
+
Legacy Kasa takes no credentials and performs no authentication. Its XOR obfuscation is not cryptographic encryption; an observed device-ID match does not authenticate the peer. Configure only an owner-controlled network endpoint. No secrets or filesystem application state are stored. If a caller provides a config store, it must be an encrypted `NoSqlConfigStore` scoped to the configured home and `tplink`; the integration does not own or close that store.
|
|
35
|
+
|
|
36
|
+
Tapo, SMART/AES/KLAP, cloud login, bulbs, dimmer settings, energy-meter features, schedules, discovery broadcasts and child power strips are unsupported. These devices fail admission rather than falling back to snapshots or another transport. The existing `TplinkMapper` remains an offline snapshot mapping utility; supplying snapshots or `commandExecutor` to the native runtime is no longer supported. Migrate runtime configuration to the explicit native schema above.
|
|
37
|
+
|
|
38
|
+
Verified against local TCP protocol fixtures only. Physical hardware, vendor credentials and firmware-specific behavior remain unverified. See the owning package's Kasa documentation and the [Home Assistant TP-Link integration](https://www.home-assistant.io/integrations/tplink/) for ecosystem coverage; that broader coverage does not define this runtime's admitted subset.
|