diff --git a/pyproject.toml b/pyproject.toml index 63885c3..a50df8e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tadoasync" -version = "0.1.18" +version = "0.1.19" authors = ["Erwin Douna "] classifiers = [ "Development Status :: 5 - Production/Stable", diff --git a/src/tadoasync/models.py b/src/tadoasync/models.py index c523865..9a3d1c1 100644 --- a/src/tadoasync/models.py +++ b/src/tadoasync/models.py @@ -171,13 +171,24 @@ class Zone(DataClassORJSONMixin): # pylint: disable=too-many-instance-attribute date_created: str = field(metadata=field_options(alias="dateCreated")) device_types: list[str] = field(metadata=field_options(alias="deviceTypes")) devices: list[Device] - report_available: bool = field(metadata=field_options(alias="reportAvailable")) - show_schedule_detup: bool = field(metadata=field_options(alias="showScheduleSetup")) - supports_dazzle: bool = field(metadata=field_options(alias="supportsDazzle")) - dazzle_enabled: bool = field(metadata=field_options(alias="dazzleEnabled")) - dazzle_mode: DazzleMode = field(metadata=field_options(alias="dazzleMode")) - open_window_detection: OpenWindowDetection = field( - metadata=field_options(alias="openWindowDetection") + dazzle_mode: DazzleMode | None = field( + metadata=field_options(alias="dazzleMode"), + default=None, + ) + open_window_detection: OpenWindowDetection | None = field( + metadata=field_options(alias="openWindowDetection"), default=None + ) + report_available: bool = field( + metadata=field_options(alias="reportAvailable"), default=False + ) + show_schedule_setup: bool = field( + metadata=field_options(alias="showScheduleSetup"), default=False + ) + supports_dazzle: bool = field( + metadata=field_options(alias="supportsDazzle"), default=False + ) + dazzle_enabled: bool = field( + metadata=field_options(alias="dazzleEnabled"), default=False ) @@ -277,7 +288,77 @@ class Capabilities(DataClassORJSONMixin): """Capabilities model represents the capabilities of a zone.""" type: str - temperatures: Temperatures + temperatures: Temperatures | None = None + can_set_temperature: bool | None = field( + metadata=field_options(alias="canSetTemperature"), default=None + ) + + # Air conditioning specifics + auto: AutoAC | None = field(metadata=field_options(alias="AUTO"), default=None) + cool: CoolAC | None = field(metadata=field_options(alias="COOL"), default=None) + dry: DryAC | None = field(metadata=field_options(alias="DRY"), default=None) + fan: FanAC | None = field(metadata=field_options(alias="FAN"), default=None) + heat: HeatAC | None = field(metadata=field_options(alias="HEAT"), default=None) + + +@dataclass +class AutoAC(DataClassORJSONMixin): + """AutoAC model represents the auto AC capabilities of a zone.""" + + fan_speeds: list[str] | None = field( + default=None, metadata=field_options(alias="fanSpeeds") + ) + swing_modes: list[str] | None = field( + default=None, metadata=field_options(alias="swings") + ) + light: str | None = None + + +@dataclass +class CoolAC(DataClassORJSONMixin): + """CoolAC model represents the cool AC capabilities of a zone.""" + + fan_speeds: list[str] | None = field( + default=None, metadata=field_options(alias="fanSpeeds") + ) + swing_modes: list[str] | None = field( + default=None, metadata=field_options(alias="swings") + ) + temperatures: Temperatures | None = None + + +@dataclass +class DryAC(DataClassORJSONMixin): + """DryAC model represents the dry AC capabilities of a zone.""" + + swing_modes: list[str] | None = field( + default=None, metadata=field_options(alias="swings") + ) + + +@dataclass +class FanAC(DataClassORJSONMixin): + """FanAC model represents the fan AC capabilities of a zone.""" + + fan_speeds: list[str] | None = field( + default=None, metadata=field_options(alias="fanSpeeds") + ) + swing_modes: list[str] | None = field( + default=None, metadata=field_options(alias="swings") + ) + + +@dataclass +class HeatAC(DataClassORJSONMixin): + """HeatAC model represents the heat AC capabilities of a zone.""" + + fan_speeds: list[str] | None = field( + default=None, metadata=field_options(alias="fanSpeeds") + ) + swing_modes: list[str] | None = field( + default=None, metadata=field_options(alias="swings") + ) + temperatures: Temperatures | None = None @dataclass diff --git a/src/tadoasync/tadoasync.py b/src/tadoasync/tadoasync.py index e5bd77e..d7423d2 100644 --- a/src/tadoasync/tadoasync.py +++ b/src/tadoasync/tadoasync.py @@ -250,12 +250,17 @@ async def get_zone_states(self) -> list[ZoneStates]: zone_id: ZoneState.from_dict(zone_state_dict) for zone_id, zone_state_dict in obj["zoneStates"].items() } + + for zone_state in zone_states.values(): + await self.update_zone_data(zone_state) + return [ZoneStates(zone_states=zone_states)] async def get_zone_state(self, zone_id: int) -> ZoneState: """Get the zone state.""" response = await self._request(f"homes/{self._home_id}/zones/{zone_id}/state") zone_state = ZoneState.from_json(response) + await self.update_zone_data(zone_state) return zone_state @@ -362,11 +367,15 @@ async def set_zone_overlay( ) async def get_device_info( - self, serial_no: str, attribute: str - ) -> TemperatureOffset: + self, serial_no: str, attribute: str | None = None + ) -> TemperatureOffset | Device: """Get the device info.""" - response = await self._request(f"devices/{serial_no}/{attribute}") - return TemperatureOffset.from_json(response) + if attribute == "temperatureOffset": + response = await self._request(f"devices/{serial_no}/{attribute}") + return TemperatureOffset.from_json(response) + + response = await self._request(f"devices/{serial_no}/") + return Device.from_json(response) async def set_child_lock(self, serial_no: str, child_lock: bool | None) -> None: """Set the child lock.""" @@ -468,8 +477,7 @@ async def update_zone_data(self, data: ZoneState) -> None: # pylint: disable=to data.current_fan_speed = None data.current_fan_level = None - # If there is no overlay, the mode will always be - # "SMART_SCHEDULE" + # If there is no overlay, the mode will always be "SMART_SCHEDULE" data.current_hvac_mode = CONST_MODE_OFF data.current_swing_mode = CONST_MODE_OFF data.current_vertical_swing_mode = CONST_VERTICAL_SWING_OFF @@ -518,6 +526,8 @@ async def update_zone_data(self, data: ZoneState) -> None: # pylint: disable=to else CONST_FAN_SPEED_OFF ) + data.preparation = hasattr(data, "preparation") and data.preparation is not None + data.open_window_detected = ( hasattr(data, "open_window_detected") and data.open_window_detected is not None @@ -537,6 +547,9 @@ async def update_zone_data(self, data: ZoneState) -> None: # pylint: disable=to data.current_hvac_mode, CONST_HVAC_COOL ) + # The overlay is active if the current mode is not smart schedule + data.overlay_active = data.current_hvac_mode != CONST_MODE_SMART_SCHEDULE + if data.activity_data_points.heating_power is not None: # This needs to be validated if this is actually in! data.heating_power = data.heating_power = ( diff --git a/tests/__snapshots__/test_tado.ambr b/tests/__snapshots__/test_tado.ambr index 78f26b2..64010a0 100644 --- a/tests/__snapshots__/test_tado.ambr +++ b/tests/__snapshots__/test_tado.ambr @@ -15,6 +15,12 @@ # --- # name: test_get_capabilities dict({ + 'auto': None, + 'can_set_temperature': None, + 'cool': None, + 'dry': None, + 'fan': None, + 'heat': None, 'temperatures': dict({ 'celsius': dict({ 'max': 25.0, @@ -30,7 +36,139 @@ 'type': 'HEATING', }) # --- +# name: test_get_capabilities_ac + dict({ + 'auto': dict({ + 'fan_speeds': list([ + 'AUTO', + 'HIGH', + 'MIDDLE', + 'LOW', + ]), + 'light': None, + 'swing_modes': list([ + 'OFF', + 'ON', + ]), + }), + 'can_set_temperature': None, + 'cool': dict({ + 'fan_speeds': list([ + 'AUTO', + 'HIGH', + 'MIDDLE', + 'LOW', + ]), + 'swing_modes': list([ + 'OFF', + 'ON', + ]), + 'temperatures': dict({ + 'celsius': dict({ + 'max': 30.0, + 'min': 18.0, + 'step': 1.0, + }), + 'fahrenheit': dict({ + 'max': 86.0, + 'min': 64.0, + 'step': 1.0, + }), + }), + }), + 'dry': dict({ + 'swing_modes': list([ + 'OFF', + 'ON', + ]), + }), + 'fan': dict({ + 'fan_speeds': list([ + 'AUTO', + 'HIGH', + 'MIDDLE', + 'LOW', + ]), + 'swing_modes': list([ + 'OFF', + 'ON', + ]), + }), + 'heat': dict({ + 'fan_speeds': list([ + 'AUTO', + 'HIGH', + 'MIDDLE', + 'LOW', + ]), + 'swing_modes': list([ + 'OFF', + 'ON', + ]), + 'temperatures': dict({ + 'celsius': dict({ + 'max': 30.0, + 'min': 16.0, + 'step': 1.0, + }), + 'fahrenheit': dict({ + 'max': 86.0, + 'min': 61.0, + 'step': 1.0, + }), + }), + }), + 'temperatures': None, + 'type': 'AIR_CONDITIONING', + }) +# --- +# name: test_get_capabilities_water_heater + dict({ + 'auto': None, + 'can_set_temperature': True, + 'cool': None, + 'dry': None, + 'fan': None, + 'heat': None, + 'temperatures': dict({ + 'celsius': dict({ + 'max': 31.0, + 'min': 16.0, + 'step': 1.0, + }), + 'fahrenheit': dict({ + 'max': 88.0, + 'min': 61.0, + 'step': 1.0, + }), + }), + 'type': 'HOT_WATER', + }) +# --- # name: test_get_device_info + dict({ + 'battery_state': None, + 'characteristics': dict({ + 'capabilities': list([ + 'RADIO_ENCRYPTION_KEY_ACCESS', + ]), + }), + 'child_lock_enabled': None, + 'connection_state': dict({ + 'timestamp': '2024-11-18T21:41:49.404Z', + 'value': True, + }), + 'current_fw_version': '92.1', + 'device_type': 'IB01', + 'in_pairing_mode': False, + 'mounting_state': None, + 'mounting_state_with_error': None, + 'orientation': None, + 'serial_no': 'SerialNo1', + 'short_serial_no': 'ShortSerialNo1', + }) +# --- +# name: test_get_device_info_attribute dict({ 'celsius': 0.0, 'fahrenheit': 0.0, @@ -316,13 +454,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 50.4, @@ -424,13 +562,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.5, @@ -532,13 +670,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 60.9, @@ -640,13 +778,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.0, @@ -743,13 +881,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.0, @@ -851,13 +989,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 60.9, @@ -959,13 +1097,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'OFF', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 48.2, @@ -1062,13 +1200,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'OFF', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.0, @@ -1170,13 +1308,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 61.6, @@ -1259,13 +1397,13 @@ 'open_window_attr': None, 'open_window_detected': False, 'overlay': None, - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': None, 'overlay_type': None, 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 60.0, @@ -1367,13 +1505,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'OFF', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 49.2, @@ -1469,13 +1607,13 @@ 'open_window_attr': None, 'open_window_detected': False, 'overlay': None, - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': None, 'overlay_type': None, 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 42.3, @@ -1577,13 +1715,13 @@ 'open_window_attr': None, 'open_window_detected': False, 'overlay': None, - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': None, 'overlay_type': None, 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -1709,13 +1847,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -1851,13 +1989,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -1992,13 +2130,13 @@ 'termination': None, 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': None, 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -2137,13 +2275,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -2267,13 +2405,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'OFF', 'precision': 0.1, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 45.2, @@ -2360,13 +2498,13 @@ 'open_window_attr': None, 'open_window_detected': False, 'overlay': None, - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': None, 'overlay_type': None, 'power': 'ON', 'precision': None, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ }), 'setting': dict({ @@ -2467,13 +2605,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'ON', 'precision': None, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ }), 'setting': dict({ @@ -2569,13 +2707,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', 'power': 'OFF', 'precision': None, - 'preparation': None, + 'preparation': False, 'sensor_data_points': dict({ }), 'setting': dict({ @@ -2599,8 +2737,8 @@ dict({ 'zone_states': dict({ '1': dict({ - 'ac_power': None, - 'ac_power_timestamp': None, + 'ac_power': 'ON', + 'ac_power_timestamp': '2024-07-05T04:02:40.867Z', 'activity_data_points': dict({ 'ac_power': dict({ 'timestamp': '2024-07-05T04:02:40.867Z', @@ -2609,18 +2747,18 @@ }), 'heating_power': None, }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, - 'current_fan_speed': None, + 'current_fan_speed': 'AUTO', 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 62.0, + 'current_humidity_timestamp': '2024-07-05T04:02:07.396Z', + 'current_hvac_action': 'DRYING', + 'current_hvac_mode': 'DRY', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 25.01, + 'current_temp_timestamp': '2024-07-05T04:02:07.396Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, @@ -2639,14 +2777,14 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ 'fan_level': None, 'fan_speed': None, 'horizontal_swing': None, - 'mode': 'FAN', + 'mode': 'DRY', 'power': 'ON', 'swing': None, 'temperature': None, @@ -2660,13 +2798,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'ON', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.0, @@ -2688,7 +2826,7 @@ 'fan_level': None, 'fan_speed': None, 'horizontal_swing': None, - 'mode': 'FAN', + 'mode': 'DRY', 'power': 'ON', 'swing': None, 'temperature': None, @@ -2708,8 +2846,8 @@ dict({ 'zone_states': dict({ '1': dict({ - 'ac_power': None, - 'ac_power_timestamp': None, + 'ac_power': 'ON', + 'ac_power_timestamp': '2024-07-05T04:02:40.867Z', 'activity_data_points': dict({ 'ac_power': dict({ 'timestamp': '2024-07-05T04:02:40.867Z', @@ -2718,18 +2856,18 @@ }), 'heating_power': None, }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, - 'current_fan_speed': None, + 'current_fan_speed': 'AUTO', 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 62.0, + 'current_humidity_timestamp': '2024-07-05T04:02:07.396Z', + 'current_hvac_action': 'FAN', + 'current_hvac_mode': 'FAN', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 25.01, + 'current_temp_timestamp': '2024-07-05T04:02:07.396Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, @@ -2748,14 +2886,14 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ 'fan_level': None, 'fan_speed': None, 'horizontal_swing': None, - 'mode': 'DRY', + 'mode': 'FAN', 'power': 'ON', 'swing': None, 'temperature': None, @@ -2769,13 +2907,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'TADO_MODE', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'ON', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 62.0, @@ -2797,7 +2935,7 @@ 'fan_level': None, 'fan_speed': None, 'horizontal_swing': None, - 'mode': 'DRY', + 'mode': 'FAN', 'power': 'ON', 'swing': None, 'temperature': None, @@ -2828,26 +2966,26 @@ 'value': None, }), }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, 'current_fan_speed': None, 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 51.0, + 'current_humidity_timestamp': '2024-02-27T20:37:02.553Z', + 'current_hvac_action': 'IDLE', + 'current_hvac_mode': 'HEAT', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 17.98, + 'current_temp_timestamp': '2024-02-27T20:37:02.553Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, 'geolocation_override': False, 'geolocation_override_disable_time': None, 'heating_power': None, - 'heating_power_percentage': None, - 'heating_power_timestamp': None, + 'heating_power_percentage': 0.0, + 'heating_power_timestamp': '2024-02-27T20:30:01.259Z', 'is_away': False, 'link': dict({ 'state': 'ONLINE', @@ -2876,7 +3014,7 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ @@ -2902,13 +3040,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'ON', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 51.0, @@ -2943,7 +3081,7 @@ 'vertical_swing': None, }), 'tado_mode': 'HOME', - 'target_temp': None, + 'target_temp': 17.0, 'termination_condition': None, }), '2': dict({ @@ -2958,26 +3096,26 @@ 'value': None, }), }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, 'current_fan_speed': None, 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 56.9, + 'current_humidity_timestamp': '2024-02-27T20:38:14.791Z', + 'current_hvac_action': 'HEATING', + 'current_hvac_mode': 'HEAT', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 14.89, + 'current_temp_timestamp': '2024-02-27T20:38:14.791Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, 'geolocation_override': False, 'geolocation_override_disable_time': None, 'heating_power': None, - 'heating_power_percentage': None, - 'heating_power_timestamp': None, + 'heating_power_percentage': 11.0, + 'heating_power_timestamp': '2024-02-27T20:37:22.791Z', 'is_away': False, 'link': dict({ 'state': 'ONLINE', @@ -2988,7 +3126,7 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ @@ -3014,13 +3152,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'ON', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 56.9, @@ -3055,7 +3193,7 @@ 'vertical_swing': None, }), 'tado_mode': 'HOME', - 'target_temp': None, + 'target_temp': 15.0, 'termination_condition': None, }), '3': dict({ @@ -3070,26 +3208,26 @@ 'value': None, }), }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, 'current_fan_speed': None, 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 55.5, + 'current_humidity_timestamp': '2024-02-27T20:37:12.297Z', + 'current_hvac_action': 'IDLE', + 'current_hvac_mode': 'HEAT', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 17.52, + 'current_temp_timestamp': '2024-02-27T20:37:12.297Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, 'geolocation_override': False, 'geolocation_override_disable_time': None, 'heating_power': None, - 'heating_power_percentage': None, - 'heating_power_timestamp': None, + 'heating_power_percentage': 0.0, + 'heating_power_timestamp': '2024-02-27T20:28:21.301Z', 'is_away': False, 'link': dict({ 'state': 'ONLINE', @@ -3118,7 +3256,7 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ @@ -3144,13 +3282,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'ON', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 55.5, @@ -3185,7 +3323,7 @@ 'vertical_swing': None, }), 'tado_mode': 'HOME', - 'target_temp': None, + 'target_temp': 17.0, 'termination_condition': None, }), '4': dict({ @@ -3200,26 +3338,26 @@ 'value': None, }), }), - 'available': False, + 'available': True, 'connection': None, 'current_fan_level': None, 'current_fan_speed': None, 'current_horizontal_swing_mode': None, - 'current_humidity': None, - 'current_humidity_timestamp': None, - 'current_hvac_action': None, - 'current_hvac_mode': None, + 'current_humidity': 63.3, + 'current_humidity_timestamp': '2024-02-27T20:37:20.931Z', + 'current_hvac_action': 'OFF', + 'current_hvac_mode': 'OFF', 'current_swing_mode': None, - 'current_temp': None, - 'current_temp_timestamp': None, + 'current_temp': 18.57, + 'current_temp_timestamp': '2024-02-27T20:37:20.931Z', 'current_vertical_swing_mode': None, 'default_overlay_termination_duration': None, 'default_overlay_termination_type': None, 'geolocation_override': False, 'geolocation_override_disable_time': None, 'heating_power': None, - 'heating_power_percentage': None, - 'heating_power_timestamp': None, + 'heating_power_percentage': 0.0, + 'heating_power_timestamp': '2024-02-27T20:27:18.903Z', 'is_away': False, 'link': dict({ 'state': 'ONLINE', @@ -3248,7 +3386,7 @@ }), 'open_window': None, 'open_window_attr': None, - 'open_window_detected': None, + 'open_window_detected': False, 'overlay': dict({ 'projected_expiry': None, 'setting': dict({ @@ -3269,13 +3407,13 @@ }), 'type': 'MANUAL', }), - 'overlay_active': None, + 'overlay_active': True, 'overlay_termination_timestamp': None, - 'overlay_termination_type': None, + 'overlay_termination_type': 'MANUAL', 'overlay_type': 'MANUAL', - 'power': None, - 'precision': None, - 'preparation': None, + 'power': 'OFF', + 'precision': 0.1, + 'preparation': False, 'sensor_data_points': dict({ 'humidity': dict({ 'percentage': 63.3, @@ -3359,7 +3497,7 @@ 'timeout_in_seconds': 900, }), 'report_available': False, - 'show_schedule_detup': False, + 'show_schedule_setup': False, 'supports_dazzle': True, 'type': 'HEATING', }), @@ -3408,7 +3546,7 @@ 'timeout_in_seconds': 900, }), 'report_available': False, - 'show_schedule_detup': True, + 'show_schedule_setup': True, 'supports_dazzle': True, 'type': 'HEATING', }), @@ -3457,7 +3595,7 @@ 'timeout_in_seconds': 900, }), 'report_available': False, - 'show_schedule_detup': True, + 'show_schedule_setup': True, 'supports_dazzle': True, 'type': 'HEATING', }), @@ -3506,7 +3644,191 @@ 'timeout_in_seconds': 900, }), 'report_available': False, - 'show_schedule_detup': True, + 'show_schedule_setup': True, + 'supports_dazzle': True, + 'type': 'HEATING', + }), + ]) +# --- +# name: test_get_zones_no_owd + list([ + dict({ + 'date_created': '2023-04-12T12:58:12.737Z', + 'dazzle_enabled': True, + 'dazzle_mode': dict({ + 'enabled': True, + 'supported': True, + }), + 'device_types': list([ + 'VA02', + ]), + 'devices': list([ + dict({ + 'battery_state': 'NORMAL', + 'characteristics': dict({ + 'capabilities': list([ + 'INSIDE_TEMPERATURE_MEASUREMENT', + 'IDENTIFY', + ]), + }), + 'child_lock_enabled': True, + 'connection_state': dict({ + 'timestamp': '2024-02-27T20:30:13.976Z', + 'value': True, + }), + 'current_fw_version': '95.1', + 'device_type': 'VA02', + 'in_pairing_mode': None, + 'mounting_state': dict({ + 'timestamp': '2024-02-04T10:17:00.266Z', + 'value': 'CALIBRATED', + }), + 'mounting_state_with_error': 'CALIBRATED', + 'orientation': 'HORIZONTAL', + 'serial_no': 'Serial1', + 'short_serial_no': 'ShortSerial1', + }), + ]), + 'id': 2, + 'name': 'Zone1', + 'open_window_detection': None, + 'report_available': False, + 'show_schedule_setup': False, + 'supports_dazzle': True, + 'type': 'HEATING', + }), + dict({ + 'date_created': '2023-01-29T16:02:14.530Z', + 'dazzle_enabled': True, + 'dazzle_mode': dict({ + 'enabled': True, + 'supported': True, + }), + 'device_types': list([ + 'VA02', + ]), + 'devices': list([ + dict({ + 'battery_state': 'NORMAL', + 'characteristics': dict({ + 'capabilities': list([ + 'INSIDE_TEMPERATURE_MEASUREMENT', + 'IDENTIFY', + ]), + }), + 'child_lock_enabled': True, + 'connection_state': dict({ + 'timestamp': '2024-02-27T20:32:05.188Z', + 'value': True, + }), + 'current_fw_version': '95.1', + 'device_type': 'VA02', + 'in_pairing_mode': None, + 'mounting_state': dict({ + 'timestamp': '2023-10-09T15:39:08.131Z', + 'value': 'CALIBRATED', + }), + 'mounting_state_with_error': 'CALIBRATED', + 'orientation': 'HORIZONTAL', + 'serial_no': 'Serial2', + 'short_serial_no': 'ShortSerial2', + }), + ]), + 'id': 1, + 'name': 'Zone2', + 'open_window_detection': None, + 'report_available': False, + 'show_schedule_setup': True, + 'supports_dazzle': True, + 'type': 'HEATING', + }), + dict({ + 'date_created': '2023-04-14T07:52:56.352Z', + 'dazzle_enabled': True, + 'dazzle_mode': dict({ + 'enabled': True, + 'supported': True, + }), + 'device_types': list([ + 'VA02', + ]), + 'devices': list([ + dict({ + 'battery_state': 'NORMAL', + 'characteristics': dict({ + 'capabilities': list([ + 'INSIDE_TEMPERATURE_MEASUREMENT', + 'IDENTIFY', + ]), + }), + 'child_lock_enabled': True, + 'connection_state': dict({ + 'timestamp': '2024-02-27T20:31:11.417Z', + 'value': True, + }), + 'current_fw_version': '95.1', + 'device_type': 'VA02', + 'in_pairing_mode': None, + 'mounting_state': dict({ + 'timestamp': '2024-02-26T13:33:10.647Z', + 'value': 'CALIBRATED', + }), + 'mounting_state_with_error': 'CALIBRATED', + 'orientation': 'HORIZONTAL', + 'serial_no': 'Serial3', + 'short_serial_no': 'ShortSerial3', + }), + ]), + 'id': 3, + 'name': 'Zone3', + 'open_window_detection': None, + 'report_available': False, + 'show_schedule_setup': True, + 'supports_dazzle': True, + 'type': 'HEATING', + }), + dict({ + 'date_created': '2023-04-14T07:58:45.196Z', + 'dazzle_enabled': True, + 'dazzle_mode': dict({ + 'enabled': True, + 'supported': True, + }), + 'device_types': list([ + 'VA02', + ]), + 'devices': list([ + dict({ + 'battery_state': 'NORMAL', + 'characteristics': dict({ + 'capabilities': list([ + 'INSIDE_TEMPERATURE_MEASUREMENT', + 'IDENTIFY', + ]), + }), + 'child_lock_enabled': True, + 'connection_state': dict({ + 'timestamp': '2024-02-27T20:33:21.903Z', + 'value': True, + }), + 'current_fw_version': '95.1', + 'device_type': 'VA02', + 'in_pairing_mode': None, + 'mounting_state': dict({ + 'timestamp': '2024-02-19T17:23:30.537Z', + 'value': 'CALIBRATED', + }), + 'mounting_state_with_error': 'CALIBRATED', + 'orientation': 'HORIZONTAL', + 'serial_no': 'Serial4', + 'short_serial_no': 'ShortSerial4', + }), + ]), + 'id': 4, + 'name': 'Zone4', + 'open_window_detection': None, + 'report_available': False, + 'show_schedule_setup': True, 'supports_dazzle': True, 'type': 'HEATING', }), diff --git a/tests/fixtures/capabilities_ac.json b/tests/fixtures/capabilities_ac.json new file mode 100644 index 0000000..fbb1312 --- /dev/null +++ b/tests/fixtures/capabilities_ac.json @@ -0,0 +1,46 @@ +{ + "type": "AIR_CONDITIONING", + "AUTO": { + "fanSpeeds": ["AUTO", "HIGH", "MIDDLE", "LOW"], + "swings": ["OFF", "ON"] + }, + "COOL": { + "temperatures": { + "celsius": { + "min": 18, + "max": 30, + "step": 1.0 + }, + "fahrenheit": { + "min": 64, + "max": 86, + "step": 1.0 + } + }, + "fanSpeeds": ["AUTO", "HIGH", "MIDDLE", "LOW"], + "swings": ["OFF", "ON"] + }, + "DRY": { + "swings": ["OFF", "ON"] + }, + "FAN": { + "fanSpeeds": ["AUTO", "HIGH", "MIDDLE", "LOW"], + "swings": ["OFF", "ON"] + }, + "HEAT": { + "temperatures": { + "celsius": { + "min": 16, + "max": 30, + "step": 1.0 + }, + "fahrenheit": { + "min": 61, + "max": 86, + "step": 1.0 + } + }, + "fanSpeeds": ["AUTO", "HIGH", "MIDDLE", "LOW"], + "swings": ["OFF", "ON"] + } +} diff --git a/tests/fixtures/capabilities_water_heater.json b/tests/fixtures/capabilities_water_heater.json new file mode 100644 index 0000000..44edf80 --- /dev/null +++ b/tests/fixtures/capabilities_water_heater.json @@ -0,0 +1,16 @@ +{ + "canSetTemperature": true, + "type": "HOT_WATER", + "temperatures": { + "celsius": { + "min": 16, + "max": 31, + "step": 1 + }, + "fahrenheit": { + "step": 1, + "max": 88, + "min": 61 + } + } +} diff --git a/tests/fixtures/device_info.json b/tests/fixtures/device_info.json index 362f5ce..9752771 100644 --- a/tests/fixtures/device_info.json +++ b/tests/fixtures/device_info.json @@ -1 +1,16 @@ -{ "celsius": 0.0, "fahrenheit": 0.0 } +{ + "deviceType": "IB01", + "serialNo": "SerialNo1", + "shortSerialNo": "ShortSerialNo1", + "currentFwVersion": "92.1", + "connectionState": { + "value": true, + "timestamp": "2024-11-18T21:41:49.404Z" + }, + "characteristics": { + "capabilities": [ + "RADIO_ENCRYPTION_KEY_ACCESS" + ] + }, + "inPairingMode": false +} diff --git a/tests/fixtures/device_info_attribute.json b/tests/fixtures/device_info_attribute.json new file mode 100644 index 0000000..362f5ce --- /dev/null +++ b/tests/fixtures/device_info_attribute.json @@ -0,0 +1 @@ +{ "celsius": 0.0, "fahrenheit": 0.0 } diff --git a/tests/fixtures/zone_states_ac_power.dry.json b/tests/fixtures/zone_states_ac_power.dry.json index 29a52cb..753f72a 100644 --- a/tests/fixtures/zone_states_ac_power.dry.json +++ b/tests/fixtures/zone_states_ac_power.dry.json @@ -33,7 +33,7 @@ }, "setting": { "type": "AIR_CONDITIONING", - "mode": "FAN", + "mode": "DRY", "power": "ON" }, "type": "MANUAL" @@ -53,7 +53,7 @@ "nextScheduleChange": null, "setting": { "type": "AIR_CONDITIONING", - "mode": "FAN", + "mode": "DRY", "power": "ON" } } diff --git a/tests/fixtures/zone_states_ac_power.fan.json b/tests/fixtures/zone_states_ac_power.fan.json index 753f72a..29a52cb 100644 --- a/tests/fixtures/zone_states_ac_power.fan.json +++ b/tests/fixtures/zone_states_ac_power.fan.json @@ -33,7 +33,7 @@ }, "setting": { "type": "AIR_CONDITIONING", - "mode": "DRY", + "mode": "FAN", "power": "ON" }, "type": "MANUAL" @@ -53,7 +53,7 @@ "nextScheduleChange": null, "setting": { "type": "AIR_CONDITIONING", - "mode": "DRY", + "mode": "FAN", "power": "ON" } } diff --git a/tests/fixtures/zones_no_owd.json b/tests/fixtures/zones_no_owd.json new file mode 100644 index 0000000..e948d9f --- /dev/null +++ b/tests/fixtures/zones_no_owd.json @@ -0,0 +1,150 @@ +[ + { + "id": 2, + "name": "Zone1", + "type": "HEATING", + "dateCreated": "2023-04-12T12:58:12.737Z", + "deviceTypes": ["VA02"], + "devices": [ + { + "deviceType": "VA02", + "serialNo": "Serial1", + "shortSerialNo": "ShortSerial1", + "currentFwVersion": "95.1", + "connectionState": { + "value": true, + "timestamp": "2024-02-27T20:30:13.976Z" + }, + "characteristics": { + "capabilities": ["INSIDE_TEMPERATURE_MEASUREMENT", "IDENTIFY"] + }, + "mountingState": { + "value": "CALIBRATED", + "timestamp": "2024-02-04T10:17:00.266Z" + }, + "mountingStateWithError": "CALIBRATED", + "batteryState": "NORMAL", + "orientation": "HORIZONTAL", + "childLockEnabled": true, + "duties": ["ZONE_UI", "ZONE_DRIVER", "ZONE_LEADER"] + } + ], + "reportAvailable": false, + "showScheduleSetup": false, + "supportsDazzle": true, + "dazzleEnabled": true, + "dazzleMode": { "supported": true, "enabled": true }, + "openWindowDetection": null + }, + { + "id": 1, + "name": "Zone2", + "type": "HEATING", + "dateCreated": "2023-01-29T16:02:14.530Z", + "deviceTypes": ["VA02"], + "devices": [ + { + "deviceType": "VA02", + "serialNo": "Serial2", + "shortSerialNo": "ShortSerial2", + "currentFwVersion": "95.1", + "connectionState": { + "value": true, + "timestamp": "2024-02-27T20:32:05.188Z" + }, + "characteristics": { + "capabilities": ["INSIDE_TEMPERATURE_MEASUREMENT", "IDENTIFY"] + }, + "mountingState": { + "value": "CALIBRATED", + "timestamp": "2023-10-09T15:39:08.131Z" + }, + "mountingStateWithError": "CALIBRATED", + "batteryState": "NORMAL", + "orientation": "HORIZONTAL", + "childLockEnabled": true, + "duties": ["ZONE_UI", "ZONE_DRIVER", "ZONE_LEADER"] + } + ], + "reportAvailable": false, + "showScheduleSetup": true, + "supportsDazzle": true, + "dazzleEnabled": true, + "dazzleMode": { "supported": true, "enabled": true }, + "openWindowDetection": null + }, + { + "id": 3, + "name": "Zone3", + "type": "HEATING", + "dateCreated": "2023-04-14T07:52:56.352Z", + "deviceTypes": ["VA02"], + "devices": [ + { + "deviceType": "VA02", + "serialNo": "Serial3", + "shortSerialNo": "ShortSerial3", + "currentFwVersion": "95.1", + "connectionState": { + "value": true, + "timestamp": "2024-02-27T20:31:11.417Z" + }, + "characteristics": { + "capabilities": ["INSIDE_TEMPERATURE_MEASUREMENT", "IDENTIFY"] + }, + "mountingState": { + "value": "CALIBRATED", + "timestamp": "2024-02-26T13:33:10.647Z" + }, + "mountingStateWithError": "CALIBRATED", + "batteryState": "NORMAL", + "orientation": "HORIZONTAL", + "childLockEnabled": true, + "duties": ["ZONE_UI", "ZONE_DRIVER", "ZONE_LEADER"] + } + ], + "reportAvailable": false, + "showScheduleSetup": true, + "supportsDazzle": true, + "dazzleEnabled": true, + "dazzleMode": { "supported": true, "enabled": true }, + "openWindowDetection": null + }, + { + "id": 4, + "name": "Zone4", + "type": "HEATING", + "dateCreated": "2023-04-14T07:58:45.196Z", + "deviceTypes": ["VA02"], + "devices": [ + { + "deviceType": "VA02", + "serialNo": "Serial4", + "shortSerialNo": "ShortSerial4", + "currentFwVersion": "95.1", + "connectionState": { + "value": true, + "timestamp": "2024-02-27T20:33:21.903Z" + }, + "characteristics": { + "capabilities": ["INSIDE_TEMPERATURE_MEASUREMENT", "IDENTIFY"] + }, + "mountingState": { + "value": "CALIBRATED", + "timestamp": "2024-02-19T17:23:30.537Z" + }, + "mountingStateWithError": "CALIBRATED", + "batteryState": "NORMAL", + "orientation": "HORIZONTAL", + "childLockEnabled": true, + "duties": ["ZONE_UI", "ZONE_DRIVER", "ZONE_LEADER"] + } + ], + "reportAvailable": false, + "showScheduleSetup": true, + "supportsDazzle": true, + "dazzleEnabled": true, + "dazzleMode": { "supported": true, "enabled": true }, + "openWindowDetection": null + } +] diff --git a/tests/test_tado.py b/tests/test_tado.py index 8009bb9..f34ef7d 100644 --- a/tests/test_tado.py +++ b/tests/test_tado.py @@ -233,6 +233,18 @@ async def test_get_zones( assert await python_tado.get_zones() == snapshot +async def test_get_zones_no_owd( + python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion +) -> None: + """Test get zones.""" + responses.get( + f"{TADO_API_URL}/homes/1/zones", + status=200, + body=load_fixture("zones_no_owd.json"), + ) + assert await python_tado.get_zones() == snapshot + + async def test_get_zone_states_heating_power( python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion ) -> None: @@ -248,7 +260,6 @@ async def test_get_zone_states_heating_power( @pytest.mark.parametrize( ("fixture_file"), [ - # Go through the different modes ("zone_states_ac_power.dry.json"), ("zone_states_ac_power.fan.json"), ], @@ -304,6 +315,30 @@ async def test_get_capabilities( assert await python_tado.get_capabilities(1) == snapshot +async def test_get_capabilities_water_heater( + python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion +) -> None: + """Test get capabilities.""" + responses.get( + f"{TADO_API_URL}/homes/1/zones/1/capabilities", + status=200, + body=load_fixture("capabilities_water_heater.json"), + ) + assert await python_tado.get_capabilities(1) == snapshot + + +async def test_get_capabilities_ac( + python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion +) -> None: + """Test get capabilities.""" + responses.get( + f"{TADO_API_URL}/homes/1/zones/1/capabilities", + status=200, + body=load_fixture("capabilities_ac.json"), + ) + assert await python_tado.get_capabilities(1) == snapshot + + async def test_reset_zone_overlay_success( python_tado: Tado, responses: aioresponses ) -> None: @@ -345,18 +380,30 @@ async def test_set_presence_auto_delete( await python_tado.set_presence(presence) -async def test_get_device_info( +async def test_get_device_info_attribute( python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion ) -> None: """Test get device info.""" responses.get( f"{TADO_API_URL}/devices/1/temperatureOffset", status=200, - body=load_fixture("device_info.json"), + body=load_fixture("device_info_attribute.json"), ) assert await python_tado.get_device_info("1", "temperatureOffset") == snapshot +async def test_get_device_info( + python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion +) -> None: + """Test get device info.""" + responses.get( + f"{TADO_API_URL}/devices/1/", + status=200, + body=load_fixture("device_info.json"), + ) + assert await python_tado.get_device_info("1") == snapshot + + async def test_geofencing_supported( python_tado: Tado, responses: aioresponses, snapshot: SnapshotAssertion ) -> None: