1 """Switcher integration Climate platform."""
3 from __future__
import annotations
5 from typing
import Any, cast
7 from aioswitcher.api
import SwitcherApi, SwitcherBaseResponse
8 from aioswitcher.api.remotes
import SwitcherBreezeRemote
9 from aioswitcher.device
import (
35 from .
import SwitcherConfigEntry
36 from .const
import SIGNAL_DEVICE_ADD
37 from .coordinator
import SwitcherDataUpdateCoordinator
38 from .entity
import SwitcherEntity
39 from .utils
import get_breeze_remote_manager
42 ThermostatMode.COOL: HVACMode.COOL,
43 ThermostatMode.HEAT: HVACMode.HEAT,
44 ThermostatMode.FAN: HVACMode.FAN_ONLY,
45 ThermostatMode.DRY: HVACMode.DRY,
46 ThermostatMode.AUTO: HVACMode.HEAT_COOL,
49 HA_TO_DEVICE_MODE = {value: key
for key, value
in DEVICE_MODE_TO_HA.items()}
52 ThermostatFanLevel.LOW: FAN_LOW,
53 ThermostatFanLevel.MEDIUM: FAN_MEDIUM,
54 ThermostatFanLevel.HIGH: FAN_HIGH,
55 ThermostatFanLevel.AUTO: FAN_AUTO,
58 HA_TO_DEVICE_FAN = {value: key
for key, value
in DEVICE_FAN_TO_HA.items()}
63 config_entry: SwitcherConfigEntry,
64 async_add_entities: AddEntitiesCallback,
66 """Set up Switcher climate from config entry."""
68 async
def async_add_climate(coordinator: SwitcherDataUpdateCoordinator) ->
None:
69 """Get remote and add climate from Switcher device."""
70 data = cast(SwitcherThermostat, coordinator.data)
71 if coordinator.data.device_type.category == DeviceCategory.THERMOSTAT:
72 remote: SwitcherBreezeRemote = await hass.async_add_executor_job(
77 config_entry.async_on_unload(
83 """Representation of a Switcher climate entity."""
86 _enable_turn_on_off_backwards_compatibility =
False
89 self, coordinator: SwitcherDataUpdateCoordinator, remote: SwitcherBreezeRemote
91 """Initialize the entity."""
95 self.
_attr_unique_id_attr_unique_id = f
"{coordinator.device_id}-{coordinator.mac_address}"
103 for mode
in remote.modes_features:
105 features = remote.modes_features[mode]
107 if features[
"temperature_control"]:
108 self._attr_supported_features |= ClimateEntityFeature.TARGET_TEMPERATURE
110 if features[
"fan_levels"]:
111 self._attr_supported_features |= ClimateEntityFeature.FAN_MODE
113 if features[
"swing"]
and not remote.separated_swing_command:
114 self._attr_supported_features |= ClimateEntityFeature.SWING_MODE
117 self._attr_supported_features |= (
118 ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
124 """Handle updated data from the coordinator."""
129 """Update data from device."""
130 data = cast(SwitcherThermostat, self.coordinator.data)
131 features = self.
_remote_remote.modes_features[data.mode]
133 if data.target_temperature == 0
and not force_update:
140 if data.device_state == DeviceState.ON:
145 if features[
"fan_levels"]:
146 self.
_attr_fan_modes_attr_fan_modes = [DEVICE_FAN_TO_HA[x]
for x
in features[
"fan_levels"]]
147 self.
_attr_fan_mode_attr_fan_mode = DEVICE_FAN_TO_HA[data.fan_level]
151 if features[
"swing"]:
154 if data.swing == ThermostatSwing.ON:
158 """Call Switcher Control Breeze API."""
159 response: SwitcherBaseResponse |
None =
None
163 async
with SwitcherApi(
164 self.coordinator.data.device_type,
165 self.coordinator.data.ip_address,
166 self.coordinator.data.device_id,
167 self.coordinator.data.device_key,
169 response = await swapi.control_breeze_device(self.
_remote_remote, **kwargs)
170 except (TimeoutError, OSError, RuntimeError)
as err:
173 if error
or not response
or not response.successful:
174 self.coordinator.last_update_success =
False
177 f
"Call Breeze control for {self.name} failed, "
178 f
"response/error: {response or error}"
182 """Set new target temperature."""
183 data = cast(SwitcherThermostat, self.coordinator.data)
184 if not self.
_remote_remote.modes_features[data.mode][
"temperature_control"]:
186 "Current mode doesn't support setting Target Temperature"
189 if (temperature := kwargs.get(ATTR_TEMPERATURE))
is None:
190 raise ValueError(
"No target temperature provided")
195 """Set new target fan mode."""
196 data = cast(SwitcherThermostat, self.coordinator.data)
197 if not self.
_remote_remote.modes_features[data.mode][
"fan_levels"]:
203 """Set new target operation mode."""
204 if hvac_mode == hvac_mode.OFF:
208 state=DeviceState.ON, mode=HA_TO_DEVICE_MODE[hvac_mode]
212 """Set new target swing operation."""
213 data = cast(SwitcherThermostat, self.coordinator.data)
214 if not self.
_remote_remote.modes_features[data.mode][
"swing"]:
217 if swing_mode == SWING_VERTICAL:
_attr_current_temperature
None async_set_fan_mode(self, str fan_mode)
None async_set_hvac_mode(self, HVACMode hvac_mode)
None _async_control_breeze_device(self, **Any kwargs)
None async_set_swing_mode(self, str swing_mode)
None async_set_temperature(self, **Any kwargs)
_attr_target_temperature_step
None __init__(self, SwitcherDataUpdateCoordinator coordinator, SwitcherBreezeRemote remote)
None _handle_coordinator_update(self)
None _update_data(self, bool force_update=False)
None async_write_ha_state(self)
None async_setup_entry(HomeAssistant hass, SwitcherConfigEntry config_entry, AddEntitiesCallback async_add_entities)
SwitcherBreezeRemoteManager get_breeze_remote_manager(HomeAssistant hass)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)