diff --git a/custom_components/panasonic_cc/panasonic.py b/custom_components/panasonic_cc/panasonic.py index bfcd2fd..f3b797f 100644 --- a/custom_components/panasonic_cc/panasonic.py +++ b/custom_components/panasonic_cc/panasonic.py @@ -268,6 +268,14 @@ def support_eco_navi(self) -> bool: @property def eco_navi(self): return self._details.parameters.eco_navi_mode + + @cached_property + def support_zones(self) -> bool: + return self._details.parameters.zones.count() > 0 + + @property + def zones(self): + return self._details.parameters.zones async def turn_off(self): await self.set_device( @@ -467,6 +475,31 @@ async def set_eco_navi_mode(self, eco_navi: constants.EcoNaviMode): ) await self.do_update() + async def set_zone( + self, + zone_id: int, + mode: constants.ZoneMode = None, + level: int = None, + temperature: int = None, + spill: int = None): + """Set new zone.""" + _LOGGER.debug("Set %s zone id: %s", self.name, zone_id) + data = { + "zoneId": zone_id + } + if mode is not None: + data["zoneOnOff"] = mode + if level is not None: + data["zoneLevel"] = level + if temperature is not None: + data["zoneTemperature"] = temperature + if spill is not None: + data["zoneSpill"] = spill + await self.set_device( + { "zoneParameters": data } + ) + await self.do_update() + async def set_device(self, args): try: diff --git a/custom_components/panasonic_cc/pcomfortcloud/constants.py b/custom_components/panasonic_cc/pcomfortcloud/constants.py index 1d277d4..b12f723 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/constants.py +++ b/custom_components/panasonic_cc/pcomfortcloud/constants.py @@ -73,6 +73,10 @@ class EcoNaviMode(Enum): Off = 0 On = 1 +class ZoneMode(Enum): + Off = 0 + On = 1 + INVALID_TEMPERATURE = 126 DEFAULT_X_APP_VERSION = "1.21.0" diff --git a/custom_components/panasonic_cc/pcomfortcloud/panasonicdevice.py b/custom_components/panasonic_cc/pcomfortcloud/panasonicdevice.py index 2406501..8b5635d 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/panasonicdevice.py +++ b/custom_components/panasonic_cc/pcomfortcloud/panasonicdevice.py @@ -82,6 +82,7 @@ def __init__(self, json = None) -> None: self.target_temperature: int = None self.inside_temperature: int = None self.outside_temperature: int = None + self.zones: list[PanasonicDeviceZone] = [] self.load(json) @@ -97,6 +98,7 @@ def load(self, json): self._load_swing_mode(json) self._load_temperature(json) + self._load_zones(json) if 'ecoMode' in json: self.eco_mode = constants.EcoMode(json['ecoMode']) @@ -105,6 +107,13 @@ def load(self, json): if 'ecoNavi' in json: self.eco_navi_mode = constants.EcoNaviMode(json['ecoNavi']) + def _load_zones(self, json): + if 'zoneParameters' not in json: + return + for zone in json['zoneParameters']: + self.zones.append(PanasonicDeviceZone(zone)) + + def _load_temperature(self, json): if 'temperatureSet' in json and json['temperatureSet'] != constants.INVALID_TEMPERATURE: self.target_temperature = json['temperatureSet'] @@ -136,3 +145,31 @@ def _load_swing_mode(self, json): +class PanasonicDeviceZone: + def __init__(self, json = None) -> None: + self.id:int = None + self.name:str = None + self.mode = constants.ZoneMode.Off + self.level = 100 + self.spill = 0 + self.temperature: int = None + pass + + def load(self, json): + if not json: + return + if 'zoneId' in json: + self.id = json['zoneId'] + if 'zoneName' in json: + self.name = json['zoneName'] + if 'zoneOnOff' in json: + self.mode = constants.ZoneMode(json['zoneOnOff']) + if 'zoneLevel' in json: + self.level = json['zoneLevel'] + if 'zoneSpill' in json: + self.spill = json['zoneSpill'] + if 'zoneTemperature' in json: + self.temperature = json['zoneTemperature'] + if self.temperature == -255: + self.temperature = None + \ No newline at end of file diff --git a/custom_components/panasonic_cc/switch.py b/custom_components/panasonic_cc/switch.py index 04e9f1a..7063d2c 100644 --- a/custom_components/panasonic_cc/switch.py +++ b/custom_components/panasonic_cc/switch.py @@ -4,6 +4,7 @@ from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription from .panasonic import PanasonicApiDevice from .pcomfortcloud import constants +from .pcomfortcloud.panasonicdevice import PanasonicDeviceZone from . import DOMAIN as PANASONIC_DOMAIN, PANASONIC_DEVICES @@ -28,6 +29,8 @@ async def async_setup_entry(hass, entry, async_add_entities): devices.append(PanasonicNanoeSwitch(device)) if device.support_eco_navi: devices.append(PanasonicEcoNaviSwitch(device)) + for zone in device.zones: + devices.append(PanasonicZoneSwitch(device, zone)) async_add_entities(devices) class PanasonicNanoeSwitch(ToggleEntity): @@ -80,8 +83,6 @@ class PanasonicEcoNaviSwitch(ToggleEntity): def __init__(self, api_device:PanasonicApiDevice): """Initialize the zone.""" self._api = api_device - - @property def unique_id(self): @@ -119,3 +120,48 @@ async def async_turn_on(self, **kwargs): async def async_turn_off(self, **kwargs): """Turn off nanoe.""" await self._api.set_eco_navi_mode(constants.EcoNaviMode.Off) + +class PanasonicZoneSwitch(ToggleEntity): + """Representation of a zone.""" + + def __init__(self, api_device:PanasonicApiDevice, zone: PanasonicDeviceZone): + """Initialize the zone.""" + self._api = api_device + self._zone = zone + + @property + def unique_id(self): + """Return a unique ID.""" + return f"{self._api.id}-zone-{self._zone.id}" + + @property + def icon(self): + """Icon to use in the frontend, if any.""" + return "mdi:thermostat" + + @property + def name(self): + """Return the name of the sensor.""" + return f"{self._api.name} {self._zone.name}" + + @property + def is_on(self): + """Return the state of the sensor.""" + return self._zone.mode == constants.ZoneMode.On + + @property + def device_info(self): + """Return a device description for device registry.""" + return self._api.device_info + + async def async_update(self): + """Retrieve latest state.""" + await self._api.update() + + async def async_turn_on(self, **kwargs): + """Turn on zone.""" + await self._api.set_zone(self._zone.id, mode=constants.ZoneMode.On) + + async def async_turn_off(self, **kwargs): + """Turn off zone.""" + await self._api.set_zone(self._zone.id, mode=constants.ZoneMode.Off) \ No newline at end of file