@smarthome.exchange/integrations 1.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +84 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/classes.configstore.d.ts +2 -0
- package/dist_ts/core/classes.configstore.js +84 -27
- package/dist_ts/core/classes.nativehomeadmission.d.ts +19 -0
- package/dist_ts/core/classes.nativehomeadmission.js +84 -0
- package/dist_ts/core/classes.nativeintegrationowner.d.ts +81 -0
- package/dist_ts/core/classes.nativeintegrationowner.js +273 -0
- package/dist_ts/core/classes.runtimemanager.d.ts +2 -0
- package/dist_ts/core/classes.runtimemanager.js +11 -3
- package/dist_ts/core/index.d.ts +2 -0
- package/dist_ts/core/index.js +3 -1
- package/dist_ts/core/types.d.ts +16 -0
- package/dist_ts/integrations/braviatv/braviatv.classes.client.d.ts +23 -72
- package/dist_ts/integrations/braviatv/braviatv.classes.client.js +265 -625
- package/dist_ts/integrations/braviatv/braviatv.classes.configflow.d.ts +7 -7
- package/dist_ts/integrations/braviatv/braviatv.classes.configflow.js +51 -68
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.d.ts +8 -11
- package/dist_ts/integrations/braviatv/braviatv.classes.integration.js +186 -135
- package/dist_ts/integrations/braviatv/braviatv.discovery.js +12 -11
- package/dist_ts/integrations/braviatv/braviatv.mapper.d.ts +6 -14
- package/dist_ts/integrations/braviatv/braviatv.mapper.js +37 -131
- package/dist_ts/integrations/braviatv/braviatv.types.d.ts +55 -133
- package/dist_ts/integrations/braviatv/braviatv.validation.d.ts +7 -0
- package/dist_ts/integrations/braviatv/braviatv.validation.js +72 -0
- package/dist_ts/integrations/broadlink/broadlink.actions.d.ts +2 -0
- package/dist_ts/integrations/broadlink/broadlink.actions.js +36 -0
- package/dist_ts/integrations/broadlink/broadlink.classes.client.d.ts +21 -19
- package/dist_ts/integrations/broadlink/broadlink.classes.client.js +185 -124
- package/dist_ts/integrations/broadlink/broadlink.classes.configflow.d.ts +5 -4
- package/dist_ts/integrations/broadlink/broadlink.classes.configflow.js +64 -83
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.d.ts +16 -19
- package/dist_ts/integrations/broadlink/broadlink.classes.integration.js +114 -59
- package/dist_ts/integrations/broadlink/broadlink.mapper.d.ts +3 -2
- package/dist_ts/integrations/broadlink/broadlink.mapper.js +2 -1
- package/dist_ts/integrations/broadlink/broadlink.selected.mapper.d.ts +10 -0
- package/dist_ts/integrations/broadlink/broadlink.selected.mapper.js +41 -0
- package/dist_ts/integrations/broadlink/broadlink.types.d.ts +43 -7
- package/dist_ts/integrations/broadlink/broadlink.validation.d.ts +7 -0
- package/dist_ts/integrations/broadlink/broadlink.validation.js +63 -0
- package/dist_ts/integrations/daikin/daikin.classes.client.d.ts +10 -52
- package/dist_ts/integrations/daikin/daikin.classes.client.js +55 -614
- package/dist_ts/integrations/daikin/daikin.classes.configflow.d.ts +8 -12
- package/dist_ts/integrations/daikin/daikin.classes.configflow.js +77 -138
- package/dist_ts/integrations/daikin/daikin.classes.integration.d.ts +7 -24
- package/dist_ts/integrations/daikin/daikin.classes.integration.js +175 -67
- package/dist_ts/integrations/daikin/daikin.discovery.d.ts +11 -24
- package/dist_ts/integrations/daikin/daikin.discovery.js +98 -305
- package/dist_ts/integrations/daikin/daikin.mapper.d.ts +6 -7
- package/dist_ts/integrations/daikin/daikin.mapper.js +95 -155
- package/dist_ts/integrations/daikin/daikin.types.d.ts +24 -44
- package/dist_ts/integrations/daikin/daikin.types.js +1 -1
- package/dist_ts/integrations/daikin/daikin.validation.d.ts +5 -0
- package/dist_ts/integrations/daikin/daikin.validation.js +53 -0
- package/dist_ts/integrations/deconz/deconz.classes.client.d.ts +37 -29
- package/dist_ts/integrations/deconz/deconz.classes.client.js +521 -294
- package/dist_ts/integrations/deconz/deconz.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/deconz/deconz.classes.configflow.js +63 -33
- package/dist_ts/integrations/deconz/deconz.classes.integration.d.ts +4 -3
- package/dist_ts/integrations/deconz/deconz.classes.integration.js +85 -40
- package/dist_ts/integrations/deconz/deconz.mapper.d.ts +1 -0
- package/dist_ts/integrations/deconz/deconz.mapper.js +24 -6
- package/dist_ts/integrations/deconz/deconz.types.d.ts +43 -6
- package/dist_ts/integrations/deconz/deconz.validation.d.ts +7 -1
- package/dist_ts/integrations/deconz/deconz.validation.js +215 -4
- package/dist_ts/integrations/denonavr/denonavr.classes.client.d.ts +31 -40
- package/dist_ts/integrations/denonavr/denonavr.classes.client.js +149 -404
- package/dist_ts/integrations/denonavr/denonavr.classes.configflow.d.ts +7 -2
- package/dist_ts/integrations/denonavr/denonavr.classes.configflow.js +44 -36
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.d.ts +6 -11
- package/dist_ts/integrations/denonavr/denonavr.classes.integration.js +192 -113
- package/dist_ts/integrations/denonavr/denonavr.discovery.d.ts +10 -18
- package/dist_ts/integrations/denonavr/denonavr.discovery.js +71 -193
- package/dist_ts/integrations/denonavr/denonavr.mapper.d.ts +5 -13
- package/dist_ts/integrations/denonavr/denonavr.mapper.js +35 -159
- package/dist_ts/integrations/denonavr/denonavr.types.d.ts +55 -90
- package/dist_ts/integrations/denonavr/denonavr.validation.d.ts +10 -0
- package/dist_ts/integrations/denonavr/denonavr.validation.js +86 -0
- package/dist_ts/integrations/esphome/esphome.classes.client.d.ts +19 -7
- package/dist_ts/integrations/esphome/esphome.classes.client.js +183 -89
- package/dist_ts/integrations/esphome/esphome.classes.configflow.d.ts +5 -2
- package/dist_ts/integrations/esphome/esphome.classes.configflow.js +43 -33
- package/dist_ts/integrations/esphome/esphome.classes.integration.d.ts +8 -6
- package/dist_ts/integrations/esphome/esphome.classes.integration.js +71 -43
- package/dist_ts/integrations/esphome/esphome.discovery.js +4 -12
- package/dist_ts/integrations/esphome/esphome.mapper.d.ts +2 -2
- package/dist_ts/integrations/esphome/esphome.mapper.js +6 -4
- package/dist_ts/integrations/esphome/esphome.types.d.ts +31 -6
- package/dist_ts/integrations/esphome/esphome.types.js +1 -1
- package/dist_ts/integrations/esphome/esphome.validation.d.ts +7 -0
- package/dist_ts/integrations/esphome/esphome.validation.js +66 -0
- package/dist_ts/integrations/homeassistant/homeassistant.classes.client.d.ts +32 -4
- package/dist_ts/integrations/homeassistant/homeassistant.classes.client.js +345 -116
- package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.d.ts +8 -5
- package/dist_ts/integrations/homeassistant/homeassistant.classes.integration.js +34 -8
- package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.d.ts +7 -4
- package/dist_ts/integrations/homeassistant/homeassistant.classes.runtime.js +44 -56
- package/dist_ts/integrations/homeassistant/homeassistant.types.d.ts +12 -1
- package/dist_ts/integrations/hue/hue.classes.client.d.ts +6 -1
- package/dist_ts/integrations/hue/hue.classes.client.js +120 -45
- package/dist_ts/integrations/hue/hue.classes.configflow.js +16 -7
- package/dist_ts/integrations/hue/hue.classes.integration.d.ts +2 -0
- package/dist_ts/integrations/hue/hue.classes.integration.js +103 -30
- package/dist_ts/integrations/hue/hue.validation.d.ts +1 -0
- package/dist_ts/integrations/hue/hue.validation.js +14 -4
- package/dist_ts/integrations/kodi/kodi.classes.client.d.ts +11 -45
- package/dist_ts/integrations/kodi/kodi.classes.client.js +84 -310
- package/dist_ts/integrations/kodi/kodi.classes.configflow.d.ts +9 -8
- package/dist_ts/integrations/kodi/kodi.classes.configflow.js +53 -48
- package/dist_ts/integrations/kodi/kodi.classes.integration.d.ts +11 -11
- package/dist_ts/integrations/kodi/kodi.classes.integration.js +114 -171
- package/dist_ts/integrations/kodi/kodi.discovery.js +53 -29
- package/dist_ts/integrations/kodi/kodi.mapper.d.ts +7 -2
- package/dist_ts/integrations/kodi/kodi.mapper.js +48 -10
- package/dist_ts/integrations/kodi/kodi.types.d.ts +32 -28
- package/dist_ts/integrations/kodi/kodi.validation.d.ts +9 -0
- package/dist_ts/integrations/kodi/kodi.validation.js +62 -0
- package/dist_ts/integrations/modbus/modbus.classes.client.d.ts +15 -61
- package/dist_ts/integrations/modbus/modbus.classes.client.js +117 -776
- package/dist_ts/integrations/modbus/modbus.classes.configflow.d.ts +9 -5
- package/dist_ts/integrations/modbus/modbus.classes.configflow.js +70 -38
- package/dist_ts/integrations/modbus/modbus.classes.integration.d.ts +6 -17
- package/dist_ts/integrations/modbus/modbus.classes.integration.js +133 -57
- package/dist_ts/integrations/modbus/modbus.discovery.d.ts +5 -8
- package/dist_ts/integrations/modbus/modbus.discovery.js +38 -93
- package/dist_ts/integrations/modbus/modbus.mapper.d.ts +8 -32
- package/dist_ts/integrations/modbus/modbus.mapper.js +71 -431
- package/dist_ts/integrations/modbus/modbus.types.d.ts +82 -332
- package/dist_ts/integrations/modbus/modbus.validation.d.ts +10 -0
- package/dist_ts/integrations/modbus/modbus.validation.js +128 -0
- package/dist_ts/integrations/mqtt/mqtt.classes.client.d.ts +15 -2
- package/dist_ts/integrations/mqtt/mqtt.classes.client.js +173 -23
- package/dist_ts/integrations/mqtt/mqtt.classes.configflow.d.ts +5 -1
- package/dist_ts/integrations/mqtt/mqtt.classes.configflow.js +53 -33
- package/dist_ts/integrations/mqtt/mqtt.classes.integration.d.ts +4 -1
- package/dist_ts/integrations/mqtt/mqtt.classes.integration.js +127 -56
- package/dist_ts/integrations/mqtt/mqtt.classes.session.d.ts +13 -0
- package/dist_ts/integrations/mqtt/mqtt.classes.session.js +130 -0
- package/dist_ts/integrations/mqtt/mqtt.mapper.d.ts +3 -0
- package/dist_ts/integrations/mqtt/mqtt.mapper.js +44 -1
- package/dist_ts/integrations/mqtt/mqtt.types.d.ts +46 -0
- package/dist_ts/integrations/mqtt/mqtt.validation.d.ts +7 -0
- package/dist_ts/integrations/mqtt/mqtt.validation.js +180 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.d.ts +12 -34
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.client.js +143 -231
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.configflow.js +105 -18
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.d.ts +8 -8
- package/dist_ts/integrations/nanoleaf/nanoleaf.classes.integration.js +141 -155
- package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.d.ts +9 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.credentials.js +35 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.d.ts +6 -18
- package/dist_ts/integrations/nanoleaf/nanoleaf.mapper.js +45 -220
- package/dist_ts/integrations/nanoleaf/nanoleaf.types.d.ts +33 -147
- package/dist_ts/integrations/nanoleaf/nanoleaf.validation.d.ts +6 -0
- package/dist_ts/integrations/nanoleaf/nanoleaf.validation.js +82 -0
- package/dist_ts/integrations/onkyo/onkyo.classes.client.d.ts +15 -20
- package/dist_ts/integrations/onkyo/onkyo.classes.client.js +161 -404
- package/dist_ts/integrations/onkyo/onkyo.classes.configflow.d.ts +9 -4
- package/dist_ts/integrations/onkyo/onkyo.classes.configflow.js +51 -6
- package/dist_ts/integrations/onkyo/onkyo.classes.integration.d.ts +22 -6
- package/dist_ts/integrations/onkyo/onkyo.classes.integration.js +144 -11
- package/dist_ts/integrations/onkyo/onkyo.discovery.d.ts +6 -1
- package/dist_ts/integrations/onkyo/onkyo.discovery.js +40 -4
- package/dist_ts/integrations/onkyo/onkyo.mapper.d.ts +7 -8
- package/dist_ts/integrations/onkyo/onkyo.mapper.js +45 -12
- package/dist_ts/integrations/onkyo/onkyo.types.d.ts +58 -8
- package/dist_ts/integrations/onkyo/onkyo.types.js +13 -102
- package/dist_ts/integrations/onkyo/onkyo.validation.d.ts +16 -0
- package/dist_ts/integrations/onkyo/onkyo.validation.js +77 -0
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.d.ts +25 -25
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.client.js +116 -360
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.d.ts +11 -3
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.js +76 -6
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.d.ts +26 -4
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.classes.integration.js +142 -9
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.d.ts +2 -1
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.discovery.js +31 -4
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.d.ts +9 -9
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.mapper.js +31 -149
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.d.ts +51 -11
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.types.js +22 -87
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.d.ts +6 -0
- package/dist_ts/integrations/panasonic_viera/panasonic_viera.validation.js +56 -0
- package/dist_ts/integrations/pioneer/pioneer.classes.client.d.ts +31 -16
- package/dist_ts/integrations/pioneer/pioneer.classes.client.js +167 -409
- package/dist_ts/integrations/pioneer/pioneer.classes.configflow.d.ts +10 -3
- package/dist_ts/integrations/pioneer/pioneer.classes.configflow.js +66 -6
- package/dist_ts/integrations/pioneer/pioneer.classes.integration.d.ts +13 -5
- package/dist_ts/integrations/pioneer/pioneer.classes.integration.js +239 -11
- package/dist_ts/integrations/pioneer/pioneer.discovery.d.ts +14 -1
- package/dist_ts/integrations/pioneer/pioneer.discovery.js +51 -4
- package/dist_ts/integrations/pioneer/pioneer.mapper.d.ts +14 -8
- package/dist_ts/integrations/pioneer/pioneer.mapper.js +54 -12
- package/dist_ts/integrations/pioneer/pioneer.types.d.ts +79 -12
- package/dist_ts/integrations/pioneer/pioneer.types.js +12 -76
- package/dist_ts/integrations/pioneer/pioneer.validation.d.ts +10 -0
- package/dist_ts/integrations/pioneer/pioneer.validation.js +85 -0
- package/dist_ts/integrations/samsungtv/samsungtv.classes.client.d.ts +4 -2
- package/dist_ts/integrations/samsungtv/samsungtv.classes.client.js +41 -16
- package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.d.ts +5 -0
- package/dist_ts/integrations/samsungtv/samsungtv.classes.configflow.js +20 -7
- package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.d.ts +1 -0
- package/dist_ts/integrations/samsungtv/samsungtv.classes.integration.js +53 -50
- package/dist_ts/integrations/samsungtv/samsungtv.types.d.ts +4 -1
- package/dist_ts/integrations/shelly/shelly.classes.client.d.ts +26 -30
- package/dist_ts/integrations/shelly/shelly.classes.client.js +504 -276
- package/dist_ts/integrations/shelly/shelly.classes.configflow.d.ts +8 -3
- package/dist_ts/integrations/shelly/shelly.classes.configflow.js +43 -38
- package/dist_ts/integrations/shelly/shelly.classes.integration.d.ts +6 -6
- package/dist_ts/integrations/shelly/shelly.classes.integration.js +103 -101
- package/dist_ts/integrations/shelly/shelly.classes.subscription.d.ts +4 -0
- package/dist_ts/integrations/shelly/shelly.classes.subscription.js +24 -2
- package/dist_ts/integrations/shelly/shelly.mapper.d.ts +1 -2
- package/dist_ts/integrations/shelly/shelly.mapper.js +21 -20
- package/dist_ts/integrations/shelly/shelly.rpc.js +4 -1
- package/dist_ts/integrations/shelly/shelly.types.d.ts +42 -2
- package/dist_ts/integrations/shelly/shelly.types.js +11 -2
- package/dist_ts/integrations/shelly/shelly.validation.d.ts +7 -0
- package/dist_ts/integrations/shelly/shelly.validation.js +79 -0
- package/dist_ts/integrations/sonos/sonos.classes.client.d.ts +79 -22
- package/dist_ts/integrations/sonos/sonos.classes.client.js +427 -139
- package/dist_ts/integrations/sonos/sonos.classes.configflow.d.ts +9 -2
- package/dist_ts/integrations/sonos/sonos.classes.configflow.js +26 -28
- package/dist_ts/integrations/sonos/sonos.classes.integration.d.ts +7 -6
- package/dist_ts/integrations/sonos/sonos.classes.integration.js +289 -224
- package/dist_ts/integrations/sonos/sonos.config.d.ts +6 -1
- package/dist_ts/integrations/sonos/sonos.config.js +23 -2
- package/dist_ts/integrations/sonos/sonos.mapper.d.ts +1 -1
- package/dist_ts/integrations/sonos/sonos.mapper.js +14 -9
- package/dist_ts/integrations/sonos/sonos.matchers.js +3 -3
- package/dist_ts/integrations/sonos/sonos.types.d.ts +26 -1
- package/dist_ts/integrations/soundtouch/soundtouch.classes.client.d.ts +13 -36
- package/dist_ts/integrations/soundtouch/soundtouch.classes.client.js +179 -502
- package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/soundtouch/soundtouch.classes.configflow.js +50 -40
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.d.ts +14 -15
- package/dist_ts/integrations/soundtouch/soundtouch.classes.integration.js +108 -128
- package/dist_ts/integrations/soundtouch/soundtouch.discovery.d.ts +2 -20
- package/dist_ts/integrations/soundtouch/soundtouch.discovery.js +23 -113
- package/dist_ts/integrations/soundtouch/soundtouch.mapper.d.ts +3 -12
- package/dist_ts/integrations/soundtouch/soundtouch.mapper.js +35 -189
- package/dist_ts/integrations/soundtouch/soundtouch.types.d.ts +57 -142
- package/dist_ts/integrations/soundtouch/soundtouch.types.js +18 -3
- package/dist_ts/integrations/soundtouch/soundtouch.validation.d.ts +22 -0
- package/dist_ts/integrations/soundtouch/soundtouch.validation.js +65 -0
- package/dist_ts/integrations/tasmota/tasmota.classes.integration.d.ts +5 -0
- package/dist_ts/integrations/tasmota/tasmota.classes.integration.js +23 -7
- package/dist_ts/integrations/tasmota/tasmota.classes.runtime.d.ts +19 -5
- package/dist_ts/integrations/tasmota/tasmota.classes.runtime.js +115 -41
- package/dist_ts/integrations/tasmota/tasmota.config.js +23 -1
- package/dist_ts/integrations/tasmota/tasmota.credentials.d.ts +11 -0
- package/dist_ts/integrations/tasmota/tasmota.credentials.js +97 -0
- package/dist_ts/integrations/tasmota/tasmota.discovery.d.ts +7 -1
- package/dist_ts/integrations/tasmota/tasmota.discovery.js +108 -30
- package/dist_ts/integrations/tasmota/tasmota.mapper.d.ts +2 -2
- package/dist_ts/integrations/tasmota/tasmota.mapper.js +7 -7
- package/dist_ts/integrations/tasmota/tasmota.types.d.ts +41 -2
- package/dist_ts/integrations/tuya/tuya.classes.integration.d.ts +4 -1
- package/dist_ts/integrations/tuya/tuya.classes.integration.js +79 -110
- package/dist_ts/integrations/tuya/tuya.classes.runtime.d.ts +5 -2
- package/dist_ts/integrations/tuya/tuya.classes.runtime.js +73 -26
- package/dist_ts/integrations/tuya/tuya.mapper.js +2 -2
- package/dist_ts/integrations/tuya/tuya.types.d.ts +3 -0
- package/dist_ts/integrations/tuya/tuya.validation.d.ts +2 -2
- package/dist_ts/integrations/tuya/tuya.validation.js +6 -11
- package/dist_ts/integrations/webostv/webostv.classes.client.d.ts +6 -5
- package/dist_ts/integrations/webostv/webostv.classes.client.js +147 -76
- package/dist_ts/integrations/webostv/webostv.classes.configflow.d.ts +7 -2
- package/dist_ts/integrations/webostv/webostv.classes.configflow.js +36 -20
- package/dist_ts/integrations/webostv/webostv.classes.integration.d.ts +4 -4
- package/dist_ts/integrations/webostv/webostv.classes.integration.js +46 -54
- package/dist_ts/integrations/webostv/webostv.mapper.js +5 -5
- package/dist_ts/integrations/webostv/webostv.types.d.ts +16 -3
- package/dist_ts/integrations/webostv/webostv.types.js +1 -1
- package/dist_ts/integrations/webostv/webostv.validation.d.ts +3 -1
- package/dist_ts/integrations/webostv/webostv.validation.js +23 -1
- package/dist_ts/integrations/wiz/index.d.ts +1 -0
- package/dist_ts/integrations/wiz/index.js +2 -1
- package/dist_ts/integrations/wiz/wiz.classes.client.d.ts +14 -28
- package/dist_ts/integrations/wiz/wiz.classes.client.js +93 -229
- package/dist_ts/integrations/wiz/wiz.classes.configflow.d.ts +6 -4
- package/dist_ts/integrations/wiz/wiz.classes.configflow.js +38 -67
- package/dist_ts/integrations/wiz/wiz.classes.integration.d.ts +10 -21
- package/dist_ts/integrations/wiz/wiz.classes.integration.js +204 -44
- package/dist_ts/integrations/wiz/wiz.discovery.d.ts +10 -31
- package/dist_ts/integrations/wiz/wiz.discovery.js +48 -249
- package/dist_ts/integrations/wiz/wiz.mapper.d.ts +7 -51
- package/dist_ts/integrations/wiz/wiz.mapper.js +82 -668
- package/dist_ts/integrations/wiz/wiz.types.d.ts +34 -208
- package/dist_ts/integrations/wiz/wiz.validation.d.ts +8 -0
- package/dist_ts/integrations/wiz/wiz.validation.js +72 -0
- package/dist_ts/integrations/yamaha/index.d.ts +1 -0
- package/dist_ts/integrations/yamaha/index.js +2 -1
- package/dist_ts/integrations/yamaha/yamaha.classes.client.d.ts +30 -4
- package/dist_ts/integrations/yamaha/yamaha.classes.client.js +162 -6
- package/dist_ts/integrations/yamaha/yamaha.classes.configflow.d.ts +10 -3
- package/dist_ts/integrations/yamaha/yamaha.classes.configflow.js +106 -6
- package/dist_ts/integrations/yamaha/yamaha.classes.integration.d.ts +22 -4
- package/dist_ts/integrations/yamaha/yamaha.classes.integration.js +243 -8
- package/dist_ts/integrations/yamaha/yamaha.discovery.d.ts +13 -1
- package/dist_ts/integrations/yamaha/yamaha.discovery.js +57 -4
- package/dist_ts/integrations/yamaha/yamaha.mapper.d.ts +16 -8
- package/dist_ts/integrations/yamaha/yamaha.mapper.js +58 -12
- package/dist_ts/integrations/yamaha/yamaha.types.d.ts +73 -6
- package/dist_ts/integrations/yamaha/yamaha.types.js +8 -94
- package/dist_ts/integrations/yamaha/yamaha.validation.d.ts +12 -0
- package/dist_ts/integrations/yamaha/yamaha.validation.js +89 -0
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.js +18 -8
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.d.ts +4 -1
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.js +54 -6
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.d.ts +12 -6
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.js +73 -59
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.d.ts +3 -2
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.js +17 -12
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.types.d.ts +31 -2
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.d.ts +9 -1
- package/dist_ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.js +57 -7
- package/dist_ts/integrations/zwave_js/zwave_js.classes.client.d.ts +10 -4
- package/dist_ts/integrations/zwave_js/zwave_js.classes.client.js +167 -31
- package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.d.ts +6 -1
- package/dist_ts/integrations/zwave_js/zwave_js.classes.configflow.js +57 -35
- package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.d.ts +3 -1
- package/dist_ts/integrations/zwave_js/zwave_js.classes.integration.js +59 -37
- package/dist_ts/integrations/zwave_js/zwave_js.discovery.js +3 -3
- package/dist_ts/integrations/zwave_js/zwave_js.mapper.js +41 -24
- package/dist_ts/integrations/zwave_js/zwave_js.types.d.ts +25 -3
- package/dist_ts/integrations/zwave_js/zwave_js.validation.d.ts +6 -2
- package/dist_ts/integrations/zwave_js/zwave_js.validation.js +52 -17
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/package.json +9 -9
- package/readme.md +539 -8
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/classes.configstore.ts +84 -27
- package/ts/core/classes.nativehomeadmission.ts +96 -0
- package/ts/core/classes.nativeintegrationowner.ts +302 -0
- package/ts/core/classes.runtimemanager.ts +11 -2
- package/ts/core/index.ts +2 -0
- package/ts/core/types.ts +18 -0
- package/ts/integrations/braviatv/braviatv.classes.client.ts +245 -709
- package/ts/integrations/braviatv/braviatv.classes.configflow.ts +47 -76
- package/ts/integrations/braviatv/braviatv.classes.integration.ts +167 -147
- package/ts/integrations/braviatv/braviatv.discovery.ts +11 -10
- package/ts/integrations/braviatv/braviatv.mapper.ts +39 -142
- package/ts/integrations/braviatv/braviatv.types.ts +53 -173
- package/ts/integrations/braviatv/braviatv.validation.ts +68 -0
- package/ts/integrations/broadlink/broadlink.actions.ts +31 -0
- package/ts/integrations/broadlink/broadlink.classes.client.ts +170 -144
- package/ts/integrations/broadlink/broadlink.classes.configflow.ts +59 -89
- package/ts/integrations/broadlink/broadlink.classes.integration.ts +110 -64
- package/ts/integrations/broadlink/broadlink.mapper.ts +5 -4
- package/ts/integrations/broadlink/broadlink.selected.mapper.ts +46 -0
- package/ts/integrations/broadlink/broadlink.types.ts +48 -8
- package/ts/integrations/broadlink/broadlink.validation.ts +66 -0
- package/ts/integrations/daikin/daikin.classes.client.ts +52 -661
- package/ts/integrations/daikin/daikin.classes.configflow.ts +72 -152
- package/ts/integrations/daikin/daikin.classes.integration.ts +166 -71
- package/ts/integrations/daikin/daikin.discovery.ts +94 -346
- package/ts/integrations/daikin/daikin.mapper.ts +83 -166
- package/ts/integrations/daikin/daikin.types.ts +27 -48
- package/ts/integrations/daikin/daikin.validation.ts +51 -0
- package/ts/integrations/daikin/readme.md +83 -0
- package/ts/integrations/deconz/deconz.classes.client.ts +348 -252
- package/ts/integrations/deconz/deconz.classes.configflow.ts +57 -29
- package/ts/integrations/deconz/deconz.classes.integration.ts +69 -37
- package/ts/integrations/deconz/deconz.mapper.ts +22 -5
- package/ts/integrations/deconz/deconz.types.ts +49 -6
- package/ts/integrations/deconz/deconz.validation.ts +177 -4
- package/ts/integrations/deconz/readme.md +15 -1
- package/ts/integrations/denonavr/denonavr.classes.client.ts +132 -421
- package/ts/integrations/denonavr/denonavr.classes.configflow.ts +44 -37
- package/ts/integrations/denonavr/denonavr.classes.integration.ts +171 -117
- package/ts/integrations/denonavr/denonavr.discovery.ts +67 -220
- package/ts/integrations/denonavr/denonavr.mapper.ts +36 -182
- package/ts/integrations/denonavr/denonavr.types.ts +48 -111
- package/ts/integrations/denonavr/denonavr.validation.ts +87 -0
- package/ts/integrations/esphome/esphome.classes.client.ts +179 -94
- package/ts/integrations/esphome/esphome.classes.configflow.ts +40 -33
- package/ts/integrations/esphome/esphome.classes.integration.ts +63 -36
- package/ts/integrations/esphome/esphome.discovery.ts +3 -12
- package/ts/integrations/esphome/esphome.mapper.ts +9 -7
- package/ts/integrations/esphome/esphome.types.ts +35 -6
- package/ts/integrations/esphome/esphome.validation.ts +66 -0
- package/ts/integrations/esphome/readme.md +20 -6
- package/ts/integrations/homeassistant/homeassistant.classes.client.ts +353 -125
- package/ts/integrations/homeassistant/homeassistant.classes.integration.ts +35 -18
- package/ts/integrations/homeassistant/homeassistant.classes.runtime.ts +50 -63
- package/ts/integrations/homeassistant/homeassistant.types.ts +17 -1
- package/ts/integrations/homeassistant/readme.md +22 -6
- package/ts/integrations/hue/hue.classes.client.ts +110 -41
- package/ts/integrations/hue/hue.classes.configflow.ts +12 -6
- package/ts/integrations/hue/hue.classes.integration.ts +92 -26
- package/ts/integrations/hue/hue.validation.ts +13 -3
- package/ts/integrations/hue/readme.md +3 -3
- package/ts/integrations/kodi/kodi.classes.client.ts +72 -352
- package/ts/integrations/kodi/kodi.classes.configflow.ts +52 -55
- package/ts/integrations/kodi/kodi.classes.integration.ts +97 -178
- package/ts/integrations/kodi/kodi.discovery.ts +49 -28
- package/ts/integrations/kodi/kodi.mapper.ts +52 -10
- package/ts/integrations/kodi/kodi.types.ts +33 -58
- package/ts/integrations/kodi/kodi.validation.ts +60 -0
- package/ts/integrations/modbus/modbus.classes.client.ts +100 -842
- package/ts/integrations/modbus/modbus.classes.configflow.ts +70 -41
- package/ts/integrations/modbus/modbus.classes.integration.ts +115 -60
- package/ts/integrations/modbus/modbus.discovery.ts +38 -106
- package/ts/integrations/modbus/modbus.mapper.ts +64 -467
- package/ts/integrations/modbus/modbus.types.ts +64 -381
- package/ts/integrations/modbus/modbus.validation.ts +119 -0
- package/ts/integrations/mqtt/mqtt.classes.client.ts +136 -19
- package/ts/integrations/mqtt/mqtt.classes.configflow.ts +45 -32
- package/ts/integrations/mqtt/mqtt.classes.integration.ts +99 -38
- package/ts/integrations/mqtt/mqtt.classes.session.ts +118 -0
- package/ts/integrations/mqtt/mqtt.mapper.ts +43 -1
- package/ts/integrations/mqtt/mqtt.types.ts +52 -0
- package/ts/integrations/mqtt/mqtt.validation.ts +157 -0
- package/ts/integrations/mqtt/readme.md +12 -3
- package/ts/integrations/nanoleaf/nanoleaf.classes.client.ts +115 -249
- package/ts/integrations/nanoleaf/nanoleaf.classes.configflow.ts +90 -19
- package/ts/integrations/nanoleaf/nanoleaf.classes.integration.ts +130 -181
- package/ts/integrations/nanoleaf/nanoleaf.credentials.ts +39 -0
- package/ts/integrations/nanoleaf/nanoleaf.mapper.ts +47 -260
- package/ts/integrations/nanoleaf/nanoleaf.types.ts +29 -147
- package/ts/integrations/nanoleaf/nanoleaf.validation.ts +77 -0
- package/ts/integrations/onkyo/onkyo.classes.client.ts +148 -457
- package/ts/integrations/onkyo/onkyo.classes.configflow.ts +52 -6
- package/ts/integrations/onkyo/onkyo.classes.integration.ts +121 -12
- package/ts/integrations/onkyo/onkyo.discovery.ts +41 -3
- package/ts/integrations/onkyo/onkyo.mapper.ts +46 -19
- package/ts/integrations/onkyo/onkyo.types.ts +55 -110
- package/ts/integrations/onkyo/onkyo.validation.ts +85 -0
- package/ts/integrations/onkyo/readme.md +126 -0
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.client.ts +101 -398
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.configflow.ts +69 -5
- package/ts/integrations/panasonic_viera/panasonic_viera.classes.integration.ts +141 -9
- package/ts/integrations/panasonic_viera/panasonic_viera.discovery.ts +32 -3
- package/ts/integrations/panasonic_viera/panasonic_viera.mapper.ts +34 -161
- package/ts/integrations/panasonic_viera/panasonic_viera.types.ts +52 -96
- package/ts/integrations/panasonic_viera/panasonic_viera.validation.ts +56 -0
- package/ts/integrations/pioneer/pioneer.classes.client.ts +132 -428
- package/ts/integrations/pioneer/pioneer.classes.configflow.ts +67 -5
- package/ts/integrations/pioneer/pioneer.classes.integration.ts +225 -11
- package/ts/integrations/pioneer/pioneer.discovery.ts +45 -3
- package/ts/integrations/pioneer/pioneer.mapper.ts +57 -13
- package/ts/integrations/pioneer/pioneer.types.ts +87 -85
- package/ts/integrations/pioneer/pioneer.validation.ts +84 -0
- package/ts/integrations/samsungtv/readme.md +11 -5
- package/ts/integrations/samsungtv/samsungtv.classes.client.ts +40 -15
- package/ts/integrations/samsungtv/samsungtv.classes.configflow.ts +21 -6
- package/ts/integrations/samsungtv/samsungtv.classes.integration.ts +53 -38
- package/ts/integrations/samsungtv/samsungtv.types.ts +4 -1
- package/ts/integrations/shelly/readme.md +22 -7
- package/ts/integrations/shelly/shelly.classes.client.ts +386 -269
- package/ts/integrations/shelly/shelly.classes.configflow.ts +43 -38
- package/ts/integrations/shelly/shelly.classes.integration.ts +92 -111
- package/ts/integrations/shelly/shelly.classes.subscription.ts +24 -1
- package/ts/integrations/shelly/shelly.mapper.ts +19 -20
- package/ts/integrations/shelly/shelly.rpc.ts +2 -0
- package/ts/integrations/shelly/shelly.types.ts +50 -2
- package/ts/integrations/shelly/shelly.validation.ts +76 -0
- package/ts/integrations/sonos/readme.md +117 -38
- package/ts/integrations/sonos/sonos.classes.client.ts +392 -123
- package/ts/integrations/sonos/sonos.classes.configflow.ts +25 -28
- package/ts/integrations/sonos/sonos.classes.integration.ts +211 -186
- package/ts/integrations/sonos/sonos.config.ts +24 -2
- package/ts/integrations/sonos/sonos.mapper.ts +13 -8
- package/ts/integrations/sonos/sonos.matchers.ts +2 -2
- package/ts/integrations/sonos/sonos.types.ts +30 -1
- package/ts/integrations/soundtouch/soundtouch.classes.client.ts +152 -571
- package/ts/integrations/soundtouch/soundtouch.classes.configflow.ts +47 -42
- package/ts/integrations/soundtouch/soundtouch.classes.integration.ts +95 -150
- package/ts/integrations/soundtouch/soundtouch.discovery.ts +21 -133
- package/ts/integrations/soundtouch/soundtouch.mapper.ts +36 -207
- package/ts/integrations/soundtouch/soundtouch.types.ts +50 -195
- package/ts/integrations/soundtouch/soundtouch.validation.ts +60 -0
- package/ts/integrations/tasmota/readme.md +16 -5
- package/ts/integrations/tasmota/tasmota.classes.integration.ts +24 -6
- package/ts/integrations/tasmota/tasmota.classes.runtime.ts +112 -43
- package/ts/integrations/tasmota/tasmota.config.ts +17 -0
- package/ts/integrations/tasmota/tasmota.credentials.ts +92 -0
- package/ts/integrations/tasmota/tasmota.discovery.ts +87 -24
- package/ts/integrations/tasmota/tasmota.mapper.ts +6 -6
- package/ts/integrations/tasmota/tasmota.types.ts +43 -2
- package/ts/integrations/tuya/readme.md +52 -10
- package/ts/integrations/tuya/tuya.classes.integration.ts +69 -98
- package/ts/integrations/tuya/tuya.classes.runtime.ts +70 -24
- package/ts/integrations/tuya/tuya.mapper.ts +1 -1
- package/ts/integrations/tuya/tuya.types.ts +4 -0
- package/ts/integrations/tuya/tuya.validation.ts +5 -8
- package/ts/integrations/webostv/readme.md +115 -22
- package/ts/integrations/webostv/webostv.classes.client.ts +123 -50
- package/ts/integrations/webostv/webostv.classes.configflow.ts +35 -15
- package/ts/integrations/webostv/webostv.classes.integration.ts +44 -37
- package/ts/integrations/webostv/webostv.mapper.ts +4 -4
- package/ts/integrations/webostv/webostv.types.ts +18 -3
- package/ts/integrations/webostv/webostv.validation.ts +22 -1
- package/ts/integrations/wiz/index.ts +1 -0
- package/ts/integrations/wiz/wiz.classes.client.ts +84 -254
- package/ts/integrations/wiz/wiz.classes.configflow.ts +39 -70
- package/ts/integrations/wiz/wiz.classes.integration.ts +189 -45
- package/ts/integrations/wiz/wiz.discovery.ts +48 -291
- package/ts/integrations/wiz/wiz.mapper.ts +81 -754
- package/ts/integrations/wiz/wiz.types.ts +24 -224
- package/ts/integrations/wiz/wiz.validation.ts +73 -0
- package/ts/integrations/yamaha/index.ts +1 -0
- package/ts/integrations/yamaha/yamaha.classes.client.ts +150 -6
- package/ts/integrations/yamaha/yamaha.classes.configflow.ts +100 -5
- package/ts/integrations/yamaha/yamaha.classes.integration.ts +236 -8
- package/ts/integrations/yamaha/yamaha.discovery.ts +52 -3
- package/ts/integrations/yamaha/yamaha.mapper.ts +65 -13
- package/ts/integrations/yamaha/yamaha.types.ts +77 -97
- package/ts/integrations/yamaha/yamaha.validation.ts +86 -0
- package/ts/integrations/zigbee2mqtt/readme.md +22 -27
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.configflow.ts +16 -7
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.integration.ts +53 -6
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.classes.runtime.ts +62 -49
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.mapper.ts +17 -11
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.types.ts +35 -2
- package/ts/integrations/zigbee2mqtt/zigbee2mqtt.validation.ts +53 -7
- package/ts/integrations/zwave_js/readme.md +42 -9
- package/ts/integrations/zwave_js/zwave_js.classes.client.ts +155 -31
- package/ts/integrations/zwave_js/zwave_js.classes.configflow.ts +55 -31
- package/ts/integrations/zwave_js/zwave_js.classes.integration.ts +57 -35
- package/ts/integrations/zwave_js/zwave_js.discovery.ts +2 -2
- package/ts/integrations/zwave_js/zwave_js.mapper.ts +37 -23
- package/ts/integrations/zwave_js/zwave_js.types.ts +26 -3
- package/ts/integrations/zwave_js/zwave_js.validation.ts +52 -18
- package/ts/plugins.ts +2 -1
|
@@ -1,9 +1,73 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NativeIntegrationOwner, type INativeIntegrationOwnerOptions, type NativeIntegrationScope } from '../../core/classes.nativeintegrationowner.js';
|
|
2
|
+
import type { INativeAdmissionContext } from '../../core/classes.nativehomeadmission.js';
|
|
3
|
+
import type { IConfigFlow, IConfigFlowContext, IConfigFlowStep, IDiscoveryCandidate } from '../../core/types.js';
|
|
4
|
+
import { PanasonicVieraClient } from './panasonic_viera.classes.client.js';
|
|
5
|
+
import { createPanasonicVieraDiscoveryDescriptor } from './panasonic_viera.discovery.js';
|
|
2
6
|
import type { IPanasonicVieraConfig } from './panasonic_viera.types.js';
|
|
3
|
-
import {
|
|
7
|
+
import { normalizePanasonicVieraConfig, panasonicVieraRecord } from './panasonic_viera.validation.js';
|
|
4
8
|
|
|
5
|
-
export class PanasonicVieraConfigFlow
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
export class PanasonicVieraConfigFlow implements IConfigFlow<IPanasonicVieraConfig> {
|
|
10
|
+
private readonly scope: NativeIntegrationScope;
|
|
11
|
+
private readonly clients = new Set<PanasonicVieraClient>();
|
|
12
|
+
private submitting = false;
|
|
13
|
+
|
|
14
|
+
public constructor(optionsArg: INativeIntegrationOwnerOptions = {}, scopeArg?: NativeIntegrationScope) {
|
|
15
|
+
this.scope = scopeArg ?? new NativeIntegrationOwner('panasonic_viera', optionsArg).createFlowScope();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public start(candidateArg: IDiscoveryCandidate, contextArg: IConfigFlowContext): Promise<IConfigFlowStep<IPanasonicVieraConfig>> {
|
|
19
|
+
return this.scope.run(contextArg, undefined, async (lease) => {
|
|
20
|
+
const match = await createPanasonicVieraDiscoveryDescriptor().getValidators()[0].validate(candidateArg, {});
|
|
21
|
+
lease.assertOpen();
|
|
22
|
+
if (!match.matched || !match.candidate) return { kind: 'error', error: match.reason };
|
|
23
|
+
const host = match.candidate.host;
|
|
24
|
+
const context = lease.context;
|
|
25
|
+
return {
|
|
26
|
+
kind: 'form', title: 'Connect selected plaintext Panasonic NRC',
|
|
27
|
+
description: 'Select the exact description URL, UPnP UDN and model for the host-selected home. Only advertised keys are supported; encrypted/PIN TVs are refused.',
|
|
28
|
+
fields: [
|
|
29
|
+
{ name: 'descriptionUrl', label: 'Selected HTTP UPnP description URL', type: 'text', required: true },
|
|
30
|
+
{ name: 'expectedUdn', label: 'Selected UPnP UUID', type: 'text', required: true },
|
|
31
|
+
{ name: 'expectedModelName', label: 'Selected exact model name', type: 'text', required: true },
|
|
32
|
+
{ name: 'allowUnencryptedLan', label: 'Acknowledge unauthenticated plaintext LAN', type: 'boolean', required: true },
|
|
33
|
+
{ name: 'name', label: 'Name', type: 'text' },
|
|
34
|
+
],
|
|
35
|
+
submit: (valuesArg) => this.submit(host, valuesArg, context),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public destroy(): Promise<void> { return this.scope.close(); }
|
|
41
|
+
|
|
42
|
+
public retryCleanup(): Promise<void> { return this.scope.retryCleanup(); }
|
|
43
|
+
|
|
44
|
+
private async submit(hostArg: string | undefined, valuesArg: Record<string, unknown>, contextArg: INativeAdmissionContext): Promise<IConfigFlowStep<IPanasonicVieraConfig>> {
|
|
45
|
+
// Fence stale form closures even when another submission is in flight.
|
|
46
|
+
this.scope.admit(contextArg);
|
|
47
|
+
if (this.submitting) throw new Error('Panasonic Viera config-flow admission is already in progress.');
|
|
48
|
+
this.submitting = true;
|
|
49
|
+
try {
|
|
50
|
+
const values = panasonicVieraRecord(valuesArg, ['homeId', 'descriptionUrl', 'expectedUdn', 'expectedModelName', 'allowUnencryptedLan', 'name', 'timeoutMs', 'maxResponseBytes']);
|
|
51
|
+
if (values.homeId !== undefined && values.homeId !== contextArg.homeId) throw new Error('Panasonic Viera form home does not match the selected host home.');
|
|
52
|
+
const config = normalizePanasonicVieraConfig({ ...values, host: hostArg, homeId: contextArg.homeId });
|
|
53
|
+
return await this.scope.run(contextArg, config.homeId, async (lease) => {
|
|
54
|
+
const client = new PanasonicVieraClient(config, { ...lease.context, abortSignal: lease.signal });
|
|
55
|
+
this.clients.add(client);
|
|
56
|
+
let attemptedCleanup = false;
|
|
57
|
+
lease.own(async () => {
|
|
58
|
+
if (attemptedCleanup) await client.retryCleanup();
|
|
59
|
+
else { attemptedCleanup = true; await client.destroy(); }
|
|
60
|
+
this.clients.delete(client);
|
|
61
|
+
});
|
|
62
|
+
await client.start(lease.signal);
|
|
63
|
+
lease.assertOpen();
|
|
64
|
+
if (client.isClosed) throw new Error('Panasonic Viera config-flow admission was cancelled.');
|
|
65
|
+
return { kind: 'done', title: 'Selected Panasonic NRC admitted', config };
|
|
66
|
+
});
|
|
67
|
+
} catch (errorArg) {
|
|
68
|
+
// Cleanup rejection retains its original evidence and lease; admission errors are form results.
|
|
69
|
+
if (errorArg instanceof AggregateError) throw errorArg;
|
|
70
|
+
return { kind: 'error', error: errorArg instanceof Error ? errorArg.message : 'Panasonic Viera admission failed.' };
|
|
71
|
+
} finally { this.submitting = false; }
|
|
8
72
|
}
|
|
9
73
|
}
|
|
@@ -1,23 +1,155 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type * as plugins from '../../plugins.js';
|
|
2
|
+
import { BaseIntegration } from '../../core/classes.baseintegration.js';
|
|
3
|
+
import { NativeIntegrationOwner, type INativeIntegrationOwnerOptions, type INativeSetupLease } from '../../core/classes.nativeintegrationowner.js';
|
|
4
|
+
import type { IDeviceFeatureWriteRequest, IIntegrationEntity, IIntegrationRuntime, IIntegrationSetupContext, IServiceCallRequest, IServiceCallResult } from '../../core/types.js';
|
|
2
5
|
import { PanasonicVieraClient } from './panasonic_viera.classes.client.js';
|
|
3
6
|
import { PanasonicVieraConfigFlow } from './panasonic_viera.classes.configflow.js';
|
|
4
7
|
import { createPanasonicVieraDiscoveryDescriptor } from './panasonic_viera.discovery.js';
|
|
5
|
-
import
|
|
8
|
+
import { PanasonicVieraMapper } from './panasonic_viera.mapper.js';
|
|
9
|
+
import type { IPanasonicVieraConfig, IPanasonicVieraSnapshot, TPanasonicVieraKey } from './panasonic_viera.types.js';
|
|
6
10
|
import { panasonicVieraDomain, panasonicVieraProfile } from './panasonic_viera.types.js';
|
|
11
|
+
import { drainPanasonicVieraCleanup, normalizePanasonicVieraConfig, panasonicVieraRecord } from './panasonic_viera.validation.js';
|
|
7
12
|
|
|
8
|
-
export class PanasonicVieraIntegration extends
|
|
13
|
+
export class PanasonicVieraIntegration extends BaseIntegration<IPanasonicVieraConfig> {
|
|
9
14
|
public readonly domain = panasonicVieraDomain;
|
|
15
|
+
public readonly displayName = 'Panasonic Viera';
|
|
16
|
+
public readonly status = 'control-runtime';
|
|
10
17
|
public readonly discoveryDescriptor = createPanasonicVieraDiscoveryDescriptor();
|
|
11
|
-
public readonly configFlow
|
|
18
|
+
public readonly configFlow: PanasonicVieraConfigFlow;
|
|
19
|
+
public readonly metadata = panasonicVieraProfile.metadata;
|
|
20
|
+
private readonly owner: NativeIntegrationOwner;
|
|
21
|
+
// Failed cleanup stays in this map and on the shared owner's bounded lease.
|
|
22
|
+
private readonly clients = new Map<PanasonicVieraClient, PanasonicVieraRuntime | undefined>();
|
|
12
23
|
|
|
13
|
-
constructor() {
|
|
14
|
-
super(
|
|
24
|
+
public constructor(optionsArg: INativeIntegrationOwnerOptions = {}) {
|
|
25
|
+
super();
|
|
26
|
+
this.owner = new NativeIntegrationOwner(this.domain, optionsArg);
|
|
27
|
+
this.configFlow = new PanasonicVieraConfigFlow({}, this.owner.createFlowScope());
|
|
15
28
|
}
|
|
16
29
|
|
|
17
|
-
public
|
|
18
|
-
|
|
19
|
-
return
|
|
30
|
+
public setup(configArg: IPanasonicVieraConfig, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime> {
|
|
31
|
+
const config = normalizePanasonicVieraConfig(configArg);
|
|
32
|
+
return this.owner.runSetup(contextArg, config.homeId, async (lease) => {
|
|
33
|
+
const client = new PanasonicVieraClient(config, { ...lease.context, abortSignal: lease.signal });
|
|
34
|
+
this.clients.set(client, undefined);
|
|
35
|
+
let attemptedCleanup = false;
|
|
36
|
+
lease.own(async () => {
|
|
37
|
+
const runtime = this.clients.get(client);
|
|
38
|
+
if (attemptedCleanup) await (runtime ? runtime.retryCleanupOwned() : client.retryCleanup());
|
|
39
|
+
else {
|
|
40
|
+
attemptedCleanup = true;
|
|
41
|
+
await (runtime ? runtime.closeOwned() : client.destroy());
|
|
42
|
+
}
|
|
43
|
+
this.clients.delete(client);
|
|
44
|
+
});
|
|
45
|
+
const snapshot = await client.start(lease.signal);
|
|
46
|
+
lease.assertOpen();
|
|
47
|
+
if (client.isClosed) throw new Error('Panasonic Viera setup was cancelled.');
|
|
48
|
+
const runtime = new PanasonicVieraRuntime(client, snapshot, lease);
|
|
49
|
+
this.clients.set(client, runtime);
|
|
50
|
+
lease.promoteToRuntime();
|
|
51
|
+
return runtime;
|
|
52
|
+
});
|
|
20
53
|
}
|
|
54
|
+
|
|
55
|
+
public destroy(): Promise<void> { return this.owner.close(); }
|
|
56
|
+
|
|
57
|
+
public retryCleanup(): Promise<void> { return this.owner.retryCleanup(); }
|
|
21
58
|
}
|
|
22
59
|
|
|
23
60
|
export class HomeAssistantPanasonicVieraIntegration extends PanasonicVieraIntegration {}
|
|
61
|
+
|
|
62
|
+
class PanasonicVieraRuntime implements IIntegrationRuntime {
|
|
63
|
+
public readonly domain = panasonicVieraDomain;
|
|
64
|
+
private readonly deviceId: string;
|
|
65
|
+
private readonly operations = new Set<Promise<unknown>>();
|
|
66
|
+
private closePromise?: Promise<void>;
|
|
67
|
+
|
|
68
|
+
public constructor(private readonly client: PanasonicVieraClient, private readonly admittedSnapshot: IPanasonicVieraSnapshot, private readonly lease: INativeSetupLease) {
|
|
69
|
+
this.deviceId = PanasonicVieraMapper.deviceId(admittedSnapshot);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public isHealthy(): boolean { return this.client.isHealthy; }
|
|
73
|
+
|
|
74
|
+
public devices(abortSignalArg?: AbortSignal): Promise<plugins.shxInterfaces.data.IDeviceDefinition[]> {
|
|
75
|
+
return this.track(async () => PanasonicVieraMapper.toDevices(await this.client.getSnapshot(abortSignalArg)));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public entities(): Promise<IIntegrationEntity[]> {
|
|
79
|
+
return this.track(async () => PanasonicVieraMapper.toEntities(await this.client.getSnapshot()));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public callService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
|
|
83
|
+
return this.track(() => this.performService(requestArg));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private async performService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
|
|
87
|
+
const request = panasonicVieraRecord(requestArg, ['domain', 'service', 'target', 'data']);
|
|
88
|
+
if (request.domain !== this.domain && request.domain !== 'button' || request.service !== 'press') {
|
|
89
|
+
throw new TypeError('Panasonic Viera supports exact-target button.press only.');
|
|
90
|
+
}
|
|
91
|
+
const target = panasonicVieraRecord(request.target, ['deviceId', 'entityId']);
|
|
92
|
+
if (target.deviceId !== undefined && target.deviceId !== this.deviceId || target.deviceId === undefined && target.entityId === undefined) {
|
|
93
|
+
throw new TypeError('Panasonic Viera requires an exact connected target.');
|
|
94
|
+
}
|
|
95
|
+
const data = request.data === undefined ? {} : panasonicVieraRecord(request.data, ['key']);
|
|
96
|
+
const snapshot = await this.client.getSnapshot();
|
|
97
|
+
let key: TPanasonicVieraKey;
|
|
98
|
+
if (target.entityId !== undefined) {
|
|
99
|
+
const entityKey = snapshot.profile.keys.find((keyArg) => PanasonicVieraMapper.keyEntityId(snapshot, keyArg) === target.entityId);
|
|
100
|
+
if (!entityKey || data.key !== undefined && data.key !== entityKey) throw new TypeError('Panasonic Viera button target and key must agree.');
|
|
101
|
+
key = entityKey;
|
|
102
|
+
} else key = this.admittedKey(snapshot, data.key);
|
|
103
|
+
return { success: true, data: await this.client.sendKey(key) };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public writeFeature(requestArg: IDeviceFeatureWriteRequest, abortSignalArg?: AbortSignal): Promise<IServiceCallResult> {
|
|
107
|
+
return this.track(() => this.performWrite(requestArg, abortSignalArg));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private async performWrite(requestArg: IDeviceFeatureWriteRequest, abortSignalArg?: AbortSignal): Promise<IServiceCallResult> {
|
|
111
|
+
const request = panasonicVieraRecord(requestArg, ['device', 'feature', 'value']);
|
|
112
|
+
const device = panasonicVieraRecord(request.device, ['id', 'integrationDomain', 'name', 'room', 'protocol', 'manufacturer', 'model', 'online', 'features', 'state', 'metadata']);
|
|
113
|
+
if (device.id !== this.deviceId || device.integrationDomain !== this.domain) throw new TypeError('Panasonic Viera feature target belongs to another connection.');
|
|
114
|
+
if (device.metadata !== undefined && panasonicVieraRecord(device.metadata).homeId !== this.admittedSnapshot.homeId) {
|
|
115
|
+
throw new TypeError('Panasonic Viera feature target belongs to another home.');
|
|
116
|
+
}
|
|
117
|
+
const feature = panasonicVieraRecord(request.feature, ['id', 'capability', 'name', 'readable', 'writable', 'unit']);
|
|
118
|
+
if (feature.id !== 'remote_key' || feature.capability !== 'media' || feature.readable !== false || feature.writable !== true || feature.unit !== undefined) {
|
|
119
|
+
throw new TypeError('Panasonic Viera writes require the connected write-only remote_key feature.');
|
|
120
|
+
}
|
|
121
|
+
const snapshot = await this.client.getSnapshot(abortSignalArg);
|
|
122
|
+
return { success: true, data: await this.client.sendKey(this.admittedKey(snapshot, request.value), abortSignalArg) };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public destroy(): Promise<void> { return this.lease.close(); }
|
|
126
|
+
|
|
127
|
+
/** The lease owns this logical drain, including work beyond an individual protocol call. */
|
|
128
|
+
public closeOwned(): Promise<void> {
|
|
129
|
+
if (!this.closePromise) {
|
|
130
|
+
const operations = [...this.operations];
|
|
131
|
+
this.closePromise = Promise.resolve().then(() => drainPanasonicVieraCleanup([this.client.destroy()], operations,
|
|
132
|
+
'Panasonic Viera runtime cleanup failed.'));
|
|
133
|
+
}
|
|
134
|
+
return this.closePromise;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public retryCleanupOwned(): Promise<void> {
|
|
138
|
+
return drainPanasonicVieraCleanup([this.client.retryCleanup()], [...this.operations], 'Panasonic Viera runtime explicit cleanup retry failed.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private track<TResult>(executeArg: () => Promise<TResult>): Promise<TResult> {
|
|
142
|
+
try { this.lease.assertOpen(); } catch (errorArg) { return Promise.reject(errorArg); }
|
|
143
|
+
if (this.closePromise || this.client.isClosed) return Promise.reject(new Error('Panasonic Viera runtime is closed.'));
|
|
144
|
+
if (this.operations.size !== 0) return Promise.reject(new Error('Panasonic Viera runtime has an active operation.'));
|
|
145
|
+
const operation = Promise.resolve().then(executeArg).finally(() => this.operations.delete(operation));
|
|
146
|
+
this.operations.add(operation);
|
|
147
|
+
return operation;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private admittedKey(snapshotArg: IPanasonicVieraSnapshot, valueArg: unknown): TPanasonicVieraKey {
|
|
151
|
+
const key = snapshotArg.profile.keys.find((keyArg) => keyArg === valueArg);
|
|
152
|
+
if (!key) throw new TypeError('Panasonic Viera key was not admitted for this connection.');
|
|
153
|
+
return key;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DiscoveryDescriptor } from '../../core/classes.discoverydescriptor.js';
|
|
2
|
+
import type { IDiscoveryCandidate, IDiscoveryMatch, IDiscoveryMatcher, IDiscoveryValidator } from '../../core/types.js';
|
|
3
|
+
import { panasonicVieraRecord } from './panasonic_viera.validation.js';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
class PanasonicVieraManualMatcher implements IDiscoveryMatcher {
|
|
6
|
+
public readonly id = 'panasonic_viera-manual-match';
|
|
7
|
+
public readonly source = 'manual';
|
|
8
|
+
public async matches(inputArg: unknown): Promise<IDiscoveryMatch> {
|
|
9
|
+
try {
|
|
10
|
+
const input = panasonicVieraRecord(inputArg);
|
|
11
|
+
if (input.integrationDomain !== 'panasonic_viera' || typeof input.host !== 'string' || !input.host) {
|
|
12
|
+
return { matched: false, confidence: 'low', reason: 'Select an explicit Panasonic Viera manual endpoint.' };
|
|
13
|
+
}
|
|
14
|
+
const candidate: IDiscoveryCandidate = { source: 'manual', integrationDomain: 'panasonic_viera', host: input.host,
|
|
15
|
+
metadata: input.metadata === undefined ? undefined : panasonicVieraRecord(input.metadata) };
|
|
16
|
+
return { matched: true, confidence: 'low', reason: 'Manual endpoint hint only; setup must verify the selected description and current NRC service.', candidate };
|
|
17
|
+
} catch {
|
|
18
|
+
return { matched: false, confidence: 'low', reason: 'Invalid Panasonic Viera manual hint.' };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class PanasonicVieraCandidateValidator implements IDiscoveryValidator {
|
|
24
|
+
public readonly id = 'panasonic_viera-candidate-validator';
|
|
25
|
+
public async validate(candidateArg: IDiscoveryCandidate): Promise<IDiscoveryMatch> {
|
|
26
|
+
return new PanasonicVieraManualMatcher().matches(candidateArg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function createPanasonicVieraDiscoveryDescriptor(): DiscoveryDescriptor {
|
|
31
|
+
return new DiscoveryDescriptor({ integrationDomain: 'panasonic_viera', displayName: 'Panasonic Viera' })
|
|
32
|
+
.addMatcher(new PanasonicVieraManualMatcher()).addValidator(new PanasonicVieraCandidateValidator());
|
|
33
|
+
}
|
|
@@ -1,173 +1,46 @@
|
|
|
1
|
-
import type * as
|
|
2
|
-
import { SimpleLocalMapper
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
1
|
+
import type * as plugins from '../../plugins.js';
|
|
2
|
+
import { SimpleLocalMapper } from '../../core/classes.simplelocalintegration.js';
|
|
3
|
+
import type { IIntegrationEntity, ISimpleLocalSnapshot } from '../../core/index.js';
|
|
4
|
+
import type { IPanasonicVieraOfflineConfig, IPanasonicVieraSnapshot, TPanasonicVieraKey, TPanasonicVieraRawData } from './panasonic_viera.types.js';
|
|
5
|
+
import { panasonicVieraDomain } from './panasonic_viera.types.js';
|
|
5
6
|
|
|
6
7
|
export class PanasonicVieraMapper {
|
|
7
|
-
public static
|
|
8
|
-
return
|
|
8
|
+
public static deviceId(snapshotArg: Pick<IPanasonicVieraSnapshot, 'homeId' | 'profile'>): string {
|
|
9
|
+
return `panasonic_viera:${encodeURIComponent(snapshotArg.homeId)}:${encodeURIComponent(snapshotArg.profile.identity.udn)}`;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
public static
|
|
12
|
-
return this.
|
|
12
|
+
public static keyEntityId(snapshotArg: Pick<IPanasonicVieraSnapshot, 'homeId' | 'profile'>, keyArg: TPanasonicVieraKey): string {
|
|
13
|
+
return `${this.deviceId(snapshotArg)}:key:${keyArg}`;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
public static toDevices(snapshotArg:
|
|
16
|
-
|
|
16
|
+
public static toDevices(snapshotArg: IPanasonicVieraSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
|
|
17
|
+
const identity = snapshotArg.profile.identity;
|
|
18
|
+
return [{
|
|
19
|
+
id: this.deviceId(snapshotArg), integrationDomain: panasonicVieraDomain,
|
|
20
|
+
name: snapshotArg.name, manufacturer: identity.manufacturer, model: identity.modelName,
|
|
21
|
+
protocol: 'http', online: true,
|
|
22
|
+
features: [{ id: 'remote_key', capability: 'media', name: 'Remote key', readable: false, writable: snapshotArg.profile.keys.length > 0 }],
|
|
23
|
+
state: [],
|
|
24
|
+
metadata: { homeId: snapshotArg.homeId, udn: identity.udn, family: snapshotArg.profile.family,
|
|
25
|
+
advertisedKeys: [...snapshotArg.profile.keys], observedAt: identity.observedAt,
|
|
26
|
+
lanAuthenticated: false, confirmation: 'soap-response' },
|
|
27
|
+
}];
|
|
17
28
|
}
|
|
18
29
|
|
|
19
|
-
public static toEntities(snapshotArg:
|
|
20
|
-
return
|
|
30
|
+
public static toEntities(snapshotArg: IPanasonicVieraSnapshot): IIntegrationEntity<null>[] {
|
|
31
|
+
return snapshotArg.profile.keys.map((keyArg) => ({
|
|
32
|
+
id: this.keyEntityId(snapshotArg, keyArg), uniqueId: this.keyEntityId(snapshotArg, keyArg),
|
|
33
|
+
deviceId: this.deviceId(snapshotArg), integrationDomain: panasonicVieraDomain, platform: 'button',
|
|
34
|
+
name: `${snapshotArg.name} ${keyArg}`, state: null, available: true,
|
|
35
|
+
attributes: { key: keyArg, confirmation: 'soap-response', observedAt: snapshotArg.profile.identity.observedAt },
|
|
36
|
+
}));
|
|
21
37
|
}
|
|
22
38
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const rawObject = objectValue(parsedRawData);
|
|
30
|
-
if (!rawObject || rawObject.device || Array.isArray(rawObject.entities)) {
|
|
31
|
-
return parsedRawData;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const deviceInfo = objectValue(rawObject.deviceInfo);
|
|
35
|
-
if (!deviceInfo && rawObject.volume === undefined && rawObject.muted === undefined) {
|
|
36
|
-
return parsedRawData;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const host = configArg.host || hostFromUrl(configArg.url);
|
|
40
|
-
const port = configArg.port || (host ? panasonicVieraDefaultPort : undefined);
|
|
41
|
-
const name = configArg.name || stringValue(deviceInfo?.friendlyName) || stringValue(deviceInfo?.FriendlyName) || panasonicVieraDefaultName;
|
|
42
|
-
const manufacturer = stringValue(deviceInfo?.manufacturer) || stringValue(deviceInfo?.Manufacturer) || 'Panasonic';
|
|
43
|
-
const model = stringValue(deviceInfo?.modelNumber) || stringValue(deviceInfo?.modelName) || stringValue(deviceInfo?.ModelNumber) || 'Panasonic Viera';
|
|
44
|
-
const udn = stringValue(deviceInfo?.UDN) || stringValue(deviceInfo?.udn);
|
|
45
|
-
const volume = numberValue(rawObject.volume);
|
|
46
|
-
const muted = booleanValue(rawObject.muted);
|
|
47
|
-
const entities: ISimpleLocalEntitySnapshot[] = [
|
|
48
|
-
{
|
|
49
|
-
id: 'media_player',
|
|
50
|
-
name,
|
|
51
|
-
platform: 'media_player',
|
|
52
|
-
state: rawObject.state || 'on',
|
|
53
|
-
writable: true,
|
|
54
|
-
attributes: cleanAttributes({
|
|
55
|
-
volumeLevel: volume === undefined ? undefined : volume / 100,
|
|
56
|
-
volumePercent: volume,
|
|
57
|
-
muted,
|
|
58
|
-
tvType: rawObject.tvType,
|
|
59
|
-
}),
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
id: 'remote',
|
|
63
|
-
name: `${name} Remote`,
|
|
64
|
-
platform: 'button',
|
|
65
|
-
state: false,
|
|
66
|
-
writable: true,
|
|
67
|
-
attributes: { action: 'press' },
|
|
68
|
-
},
|
|
69
|
-
];
|
|
70
|
-
|
|
71
|
-
if (volume !== undefined) {
|
|
72
|
-
entities.push({
|
|
73
|
-
id: 'volume',
|
|
74
|
-
name: 'Volume',
|
|
75
|
-
platform: 'sensor',
|
|
76
|
-
state: volume,
|
|
77
|
-
unit: '%',
|
|
78
|
-
deviceClass: 'volume',
|
|
79
|
-
attributes: { source: 'RenderingControl.GetVolume' },
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
if (muted !== undefined) {
|
|
83
|
-
entities.push({
|
|
84
|
-
id: 'muted',
|
|
85
|
-
name: 'Muted',
|
|
86
|
-
platform: 'binary_sensor',
|
|
87
|
-
state: muted,
|
|
88
|
-
attributes: { source: 'RenderingControl.GetMute' },
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
device: {
|
|
94
|
-
id: configArg.uniqueId || configArg.deviceId || udn || (host ? `${host}:${port || panasonicVieraDefaultPort}` : undefined) || panasonicVieraDefaultName,
|
|
95
|
-
name,
|
|
96
|
-
manufacturer,
|
|
97
|
-
model,
|
|
98
|
-
serialNumber: udn,
|
|
99
|
-
host,
|
|
100
|
-
port,
|
|
101
|
-
protocol: 'http',
|
|
102
|
-
attributes: cleanAttributes({ udn, rawDeviceInfo: deviceInfo }),
|
|
103
|
-
},
|
|
104
|
-
entities,
|
|
105
|
-
online: true,
|
|
106
|
-
updatedAt: stringValue(rawObject.fetchedAt) || new Date().toISOString(),
|
|
107
|
-
source: 'http',
|
|
108
|
-
rawData: parsedRawData,
|
|
109
|
-
} satisfies ISimpleLocalSnapshot;
|
|
39
|
+
/** Pure conversion of supplied data; unavailable and read-only regardless of the input's claims. */
|
|
40
|
+
public static toSnapshotFromRaw(configArg: IPanasonicVieraOfflineConfig, rawDataArg: TPanasonicVieraRawData): ISimpleLocalSnapshot {
|
|
41
|
+
const profile = { domain: panasonicVieraDomain, displayName: 'Panasonic Viera offline data', status: 'read-only-runtime' as const,
|
|
42
|
+
platforms: ['sensor' as const], manufacturer: 'Panasonic', defaultName: 'Panasonic Viera offline data', metadata: {} };
|
|
43
|
+
const snapshot = SimpleLocalMapper.toSnapshot({ profile, config: configArg, rawData: rawDataArg, source: 'manual', online: false });
|
|
44
|
+
return { ...snapshot, online: false, source: 'manual', entities: snapshot.entities.map((entityArg) => ({ ...entityArg, available: false, writable: false })) };
|
|
110
45
|
}
|
|
111
46
|
}
|
|
112
|
-
|
|
113
|
-
const parseMaybeJson = (valueArg: unknown): unknown => {
|
|
114
|
-
if (typeof valueArg !== 'string') {
|
|
115
|
-
return valueArg;
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
return JSON.parse(valueArg) as IPanasonicVieraRawApiData;
|
|
119
|
-
} catch {
|
|
120
|
-
return valueArg;
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const objectValue = (valueArg: unknown): Record<string, unknown> | undefined => {
|
|
125
|
-
return valueArg && typeof valueArg === 'object' && !Array.isArray(valueArg) ? valueArg as Record<string, unknown> : undefined;
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
const stringValue = (valueArg: unknown): string | undefined => {
|
|
129
|
-
return typeof valueArg === 'string' && valueArg.trim() ? valueArg.trim() : undefined;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const numberValue = (valueArg: unknown): number | undefined => {
|
|
133
|
-
if (typeof valueArg === 'number' && Number.isFinite(valueArg)) {
|
|
134
|
-
return valueArg;
|
|
135
|
-
}
|
|
136
|
-
if (typeof valueArg === 'string' && valueArg.trim() && Number.isFinite(Number(valueArg))) {
|
|
137
|
-
return Number(valueArg);
|
|
138
|
-
}
|
|
139
|
-
return undefined;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const booleanValue = (valueArg: unknown): boolean | undefined => {
|
|
143
|
-
if (typeof valueArg === 'boolean') {
|
|
144
|
-
return valueArg;
|
|
145
|
-
}
|
|
146
|
-
if (typeof valueArg === 'number') {
|
|
147
|
-
return valueArg !== 0;
|
|
148
|
-
}
|
|
149
|
-
if (typeof valueArg === 'string') {
|
|
150
|
-
if (valueArg === '1' || valueArg.toLowerCase() === 'true') {
|
|
151
|
-
return true;
|
|
152
|
-
}
|
|
153
|
-
if (valueArg === '0' || valueArg.toLowerCase() === 'false') {
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return undefined;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const cleanAttributes = (attributesArg: Record<string, unknown>): Record<string, unknown> => {
|
|
161
|
-
return Object.fromEntries(Object.entries(attributesArg).filter(([, valueArg]) => valueArg !== undefined && valueArg !== null && valueArg !== ''));
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
const hostFromUrl = (urlArg: string | undefined): string | undefined => {
|
|
165
|
-
if (!urlArg) {
|
|
166
|
-
return undefined;
|
|
167
|
-
}
|
|
168
|
-
try {
|
|
169
|
-
return new URL(urlArg.includes('://') ? urlArg : `http://${urlArg}`).hostname;
|
|
170
|
-
} catch {
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
};
|
|
@@ -1,113 +1,69 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type * as plugins from '../../plugins.js';
|
|
2
|
+
import type { ISimpleLocalConfig, ISimpleLocalSnapshot, TSimpleLocalRawData } from '../../core/index.js';
|
|
3
|
+
import type { INativeIntegrationSetupContext } from '../../core/types.js';
|
|
2
4
|
|
|
3
|
-
export const panasonicVieraDomain =
|
|
4
|
-
export const panasonicVieraDefaultName =
|
|
5
|
+
export const panasonicVieraDomain = 'panasonic_viera';
|
|
6
|
+
export const panasonicVieraDefaultName = 'Panasonic Viera';
|
|
5
7
|
export const panasonicVieraDefaultPort = 55000;
|
|
6
8
|
export const panasonicVieraDefaultTimeoutMs = 5000;
|
|
7
9
|
|
|
10
|
+
export type TPanasonicVieraKey = plugins.ecobridgeDeviceManager.TPanasonicKey;
|
|
11
|
+
export type TPanasonicVieraKeyReceipt = plugins.ecobridgeDeviceManager.IPanasonicKeyReceipt;
|
|
12
|
+
|
|
13
|
+
export interface IPanasonicVieraConfig {
|
|
14
|
+
readonly homeId: string;
|
|
15
|
+
readonly host: string;
|
|
16
|
+
readonly descriptionUrl: string;
|
|
17
|
+
readonly expectedUdn: string;
|
|
18
|
+
readonly expectedModelName: string;
|
|
19
|
+
readonly allowUnencryptedLan: true;
|
|
20
|
+
readonly name?: string;
|
|
21
|
+
readonly timeoutMs?: number;
|
|
22
|
+
readonly maxResponseBytes?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IPanasonicVieraClientOptions extends INativeIntegrationSetupContext {
|
|
26
|
+
readonly onDestroyed?: () => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface IPanasonicVieraSnapshot {
|
|
30
|
+
readonly homeId: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly profile: plugins.ecobridgeDeviceManager.IPanasonicProfile;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Explicit data conversion only; this input cannot start the native integration. */
|
|
36
|
+
export interface IPanasonicVieraOfflineConfig extends ISimpleLocalConfig {}
|
|
8
37
|
export interface IPanasonicVieraRawApiData extends Record<string, unknown> {
|
|
9
38
|
deviceInfo?: Record<string, unknown>;
|
|
10
39
|
volume?: number | null;
|
|
11
40
|
muted?: boolean | null;
|
|
12
|
-
tvType?: 'encrypted' | 'non_encrypted' | 'unknown';
|
|
13
41
|
fetchedAt?: string;
|
|
14
42
|
}
|
|
15
43
|
export type TPanasonicVieraRawData = TSimpleLocalRawData | IPanasonicVieraRawApiData;
|
|
16
|
-
export interface
|
|
17
|
-
export interface IPanasonicVieraConfig extends ISimpleLocalConfig {
|
|
18
|
-
url?: string;
|
|
19
|
-
macAddress?: string;
|
|
20
|
-
deviceId?: string;
|
|
21
|
-
appId?: string;
|
|
22
|
-
encryptionKey?: string;
|
|
23
|
-
}
|
|
44
|
+
export interface IPanasonicVieraOfflineSnapshot extends ISimpleLocalSnapshot {}
|
|
24
45
|
export interface IHomeAssistantPanasonicVieraConfig extends IPanasonicVieraConfig {}
|
|
25
46
|
|
|
26
|
-
export const panasonicVieraProfile
|
|
47
|
+
export const panasonicVieraProfile = Object.freeze({
|
|
27
48
|
domain: panasonicVieraDomain,
|
|
28
|
-
displayName:
|
|
29
|
-
manufacturer:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
status: "control-runtime",
|
|
35
|
-
platforms: [
|
|
36
|
-
"button",
|
|
37
|
-
"media_player",
|
|
38
|
-
],
|
|
39
|
-
serviceDomains: [
|
|
40
|
-
"button",
|
|
41
|
-
"media_player",
|
|
42
|
-
],
|
|
43
|
-
controlServices: [
|
|
44
|
-
"media_pause",
|
|
45
|
-
"media_next_track",
|
|
46
|
-
"media_play",
|
|
47
|
-
"media_previous_track",
|
|
48
|
-
"media_stop",
|
|
49
|
-
"press",
|
|
50
|
-
"turn_off",
|
|
51
|
-
"turn_on",
|
|
52
|
-
"volume_down",
|
|
53
|
-
"volume_mute",
|
|
54
|
-
"volume_set",
|
|
55
|
-
"volume_up",
|
|
56
|
-
],
|
|
57
|
-
discoverySources: [
|
|
58
|
-
'manual',
|
|
59
|
-
'custom',
|
|
60
|
-
],
|
|
61
|
-
discoveryKeywords: [
|
|
62
|
-
"panasonic_viera",
|
|
63
|
-
"Panasonic Viera",
|
|
64
|
-
"Panasonic",
|
|
65
|
-
"Viera",
|
|
66
|
-
],
|
|
49
|
+
displayName: panasonicVieraDefaultName,
|
|
50
|
+
manufacturer: 'Panasonic',
|
|
51
|
+
status: 'control-runtime' as const,
|
|
52
|
+
platforms: ['button'],
|
|
53
|
+
controlServices: ['press'],
|
|
54
|
+
discoverySources: ['manual', 'custom'],
|
|
67
55
|
metadata: {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"panasonic_viera",
|
|
80
|
-
],
|
|
81
|
-
"runtime": {
|
|
82
|
-
"type": "control-runtime",
|
|
83
|
-
"services": [
|
|
84
|
-
"snapshot",
|
|
85
|
-
"status",
|
|
86
|
-
"refresh",
|
|
87
|
-
"media_pause",
|
|
88
|
-
"media_play",
|
|
89
|
-
"press",
|
|
90
|
-
"volume_down",
|
|
91
|
-
"volume_up",
|
|
92
|
-
],
|
|
93
|
-
"platforms": [
|
|
94
|
-
"button",
|
|
95
|
-
"media_player",
|
|
96
|
-
],
|
|
97
|
-
"controls": "native SOAP-over-HTTP when config.host/config.url is provided; injected executors remain supported",
|
|
98
|
-
},
|
|
99
|
-
"localApi": {
|
|
100
|
-
"implemented": [
|
|
101
|
-
"native SOAP-over-HTTP polling against /nrc/ddd.xml and /dmr/control_0 on port 55000",
|
|
102
|
-
"native SOAP-over-HTTP remote key, volume, and mute commands against /nrc/control_0 and /dmr/control_0",
|
|
103
|
-
"encrypted command transport when appId and encryptionKey are supplied",
|
|
104
|
-
"manual snapshots, rawData, snapshotProvider, and injected native clients remain supported",
|
|
105
|
-
],
|
|
106
|
-
"explicitUnsupported": [
|
|
107
|
-
"interactive encrypted TV pairing/PIN enrollment is not exposed by this TypeScript config flow; provide appId and encryptionKey from an already paired client",
|
|
108
|
-
"UPnP event subscription callback server support from panasonic-viera is not implemented",
|
|
109
|
-
"Home Assistant entity registry migrations and repair flows",
|
|
110
|
-
],
|
|
56
|
+
source: 'home-assistant/core',
|
|
57
|
+
upstreamPath: 'homeassistant/components/panasonic_viera',
|
|
58
|
+
upstreamDomain: panasonicVieraDomain,
|
|
59
|
+
integrationType: 'device',
|
|
60
|
+
iotClass: 'local_polling',
|
|
61
|
+
configFlow: true,
|
|
62
|
+
documentation: 'https://www.home-assistant.io/integrations/panasonic_viera',
|
|
63
|
+
runtime: {
|
|
64
|
+
type: 'control-runtime',
|
|
65
|
+
controls: 'Selected plaintext NRC, currently advertised finite keys, matching SOAP acknowledgements only.',
|
|
66
|
+
explicitUnsupported: ['PIN/encrypted families', 'pairing', 'power state', 'current input', 'absolute volume/mute', 'media playback', 'arbitrary SOAP'],
|
|
111
67
|
},
|
|
112
68
|
},
|
|
113
|
-
};
|
|
69
|
+
});
|