1 """Plugwise Climate component for Home Assistant."""
3 from __future__
import annotations
21 from .
import PlugwiseConfigEntry
22 from .const
import DOMAIN, MASTER_THERMOSTATS
23 from .coordinator
import PlugwiseDataUpdateCoordinator
24 from .entity
import PlugwiseEntity
25 from .util
import plugwise_command
30 entry: PlugwiseConfigEntry,
31 async_add_entities: AddEntitiesCallback,
33 """Set up the Smile Thermostats from a config entry."""
34 coordinator = entry.runtime_data
37 def _add_entities() -> None:
39 if not coordinator.new_devices:
42 if coordinator.data.gateway[
"smile_name"] ==
"Adam":
45 for device_id
in coordinator.new_devices
46 if coordinator.data.devices[device_id][
"dev_class"] ==
"climate"
51 for device_id
in coordinator.new_devices
52 if coordinator.data.devices[device_id][
"dev_class"]
57 entry.async_on_unload(coordinator.async_add_listener(_add_entities))
61 """Representation of a Plugwise thermostat."""
63 _attr_has_entity_name =
True
65 _attr_temperature_unit = UnitOfTemperature.CELSIUS
66 _attr_translation_key = DOMAIN
67 _enable_turn_on_off_backwards_compatibility =
False
69 _previous_mode: str =
"heating"
73 coordinator: PlugwiseDataUpdateCoordinator,
76 """Set up the Plugwise API."""
77 super().
__init__(coordinator, device_id)
81 self.
_devices_devices = coordinator.data.devices
82 self.
_gateway_gateway = coordinator.data.gateway
83 gateway_id: str = self.
_gateway_gateway[
"gateway_id"]
87 if (location := self.
devicedevice.
get(
"location"))
is not None:
92 if self.
_gateway_gateway[
"cooling_present"]
and self.
_gateway_gateway[
"smile_name"] !=
"Adam":
94 ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
98 ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
100 if presets := self.
devicedevice.
get(
"preset_modes"):
108 self.
devicedevice[
"thermostat"][
"resolution"], 0.1
112 """Return the previous action-mode when the regulation-mode is not heating or cooling.
114 Helper for set_hvac_mode().
119 and "cooling" in self.
_gateway_data_gateway_data[
"regulation_modes"]
121 mode = self.
_gateway_data_gateway_data[
"select_regulation_mode"]
122 if mode
in (
"cooling",
"heating"):
127 """Return the current temperature."""
128 return self.
devicedevice[
"sensors"][
"temperature"]
132 """Return the temperature we try to reach.
134 Connected to the HVACMode combination of AUTO-HEAT.
137 return self.
devicedevice[
"thermostat"][
"setpoint"]
141 """Return the temperature we try to reach in case of cooling.
143 Connected to the HVACMode combination of AUTO-HEAT_COOL.
145 return self.
devicedevice[
"thermostat"][
"setpoint_high"]
149 """Return the heating temperature we try to reach in case of heating.
151 Connected to the HVACMode combination AUTO-HEAT_COOL.
153 return self.
devicedevice[
"thermostat"][
"setpoint_low"]
157 """Return HVAC operation ie. auto, cool, heat, heat_cool, or off mode."""
159 mode := self.
devicedevice.
get(
"climate_mode")
162 return HVACMode(mode)
166 """Return a list of available HVACModes."""
167 hvac_modes: list[HVACMode] = []
169 hvac_modes.append(HVACMode.OFF)
171 if "available_schedules" in self.
devicedevice:
172 hvac_modes.append(HVACMode.AUTO)
174 if self.
_gateway_gateway[
"cooling_present"]:
176 if self.
_gateway_data_gateway_data[
"select_regulation_mode"] ==
"cooling":
177 hvac_modes.append(HVACMode.COOL)
178 if self.
_gateway_data_gateway_data[
"select_regulation_mode"] ==
"heating":
179 hvac_modes.append(HVACMode.HEAT)
181 hvac_modes.append(HVACMode.HEAT_COOL)
183 hvac_modes.append(HVACMode.HEAT)
189 """Return the current running hvac operation if supported."""
194 if self.
_gateway_gateway[
"smile_name"] ==
"Adam":
195 if (control_state := self.
devicedevice.
get(
"control_state")) ==
"cooling":
196 return HVACAction.COOLING
197 if control_state ==
"heating":
198 return HVACAction.HEATING
199 if control_state ==
"preheating":
200 return HVACAction.PREHEATING
201 if control_state ==
"off":
202 return HVACAction.IDLE
204 return HVACAction.IDLE
207 heater: str = self.
_gateway_gateway[
"heater_id"]
208 heater_data = self.
_devices_devices[heater]
209 if heater_data[
"binary_sensors"][
"heating_state"]:
210 return HVACAction.HEATING
211 if heater_data[
"binary_sensors"].
get(
"cooling_state",
False):
212 return HVACAction.COOLING
214 return HVACAction.IDLE
218 """Return the current preset mode."""
219 return self.
devicedevice.
get(
"active_preset")
223 """Set new target temperature."""
224 data: dict[str, Any] = {}
225 if ATTR_TEMPERATURE
in kwargs:
226 data[
"setpoint"] = kwargs.get(ATTR_TEMPERATURE)
227 if ATTR_TARGET_TEMP_HIGH
in kwargs:
228 data[
"setpoint_high"] = kwargs.get(ATTR_TARGET_TEMP_HIGH)
229 if ATTR_TARGET_TEMP_LOW
in kwargs:
230 data[
"setpoint_low"] = kwargs.get(ATTR_TARGET_TEMP_LOW)
232 for temperature
in data.values():
233 if temperature
is None or not (
236 raise ValueError(
"Invalid temperature change requested")
238 if mode := kwargs.get(ATTR_HVAC_MODE):
241 await self.coordinator.api.set_temperature(self.
_location_location, data)
245 """Set the hvac mode."""
252 if hvac_mode == HVACMode.OFF:
253 await self.coordinator.api.set_regulation_mode(hvac_mode)
255 await self.coordinator.api.set_schedule_state(
257 "on" if hvac_mode == HVACMode.AUTO
else "off",
260 await self.coordinator.api.set_regulation_mode(self.
_previous_mode_previous_mode)
264 """Set the preset mode."""
265 await self.coordinator.api.set_preset(self.
_location_location, preset_mode)
None async_set_hvac_mode(self, HVACMode hvac_mode)
HVACMode|None hvac_mode(self)
list[HVACMode] hvac_modes(self)
HVACAction hvac_action(self)
float current_temperature(self)
float target_temperature_high(self)
None async_set_temperature(self, **Any kwargs)
float target_temperature(self)
None async_set_hvac_mode(self, HVACMode hvac_mode)
_attr_extra_state_attributes
None __init__(self, PlugwiseDataUpdateCoordinator coordinator, str device_id)
list[HVACMode] hvac_modes(self)
float target_temperature_low(self)
_attr_target_temperature_step
str|None preset_mode(self)
None _previous_action_mode(self, PlugwiseDataUpdateCoordinator coordinator)
None async_set_preset_mode(self, str preset_mode)
GwEntityData device(self)
web.Response get(self, web.Request request, str config_key)
None async_setup_entry(HomeAssistant hass, PlugwiseConfigEntry entry, AddEntitiesCallback async_add_entities)