Small cleanup in Plugwise climate (#65800)

This commit is contained in:
Franck Nijhof 2022-02-05 17:09:49 +01:00 committed by GitHub
parent df0e98f428
commit 00e8d2bc3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,7 +1,9 @@
"""Plugwise Climate component for Home Assistant.""" """Plugwise Climate component for Home Assistant."""
import logging import logging
from typing import Any
from plugwise.exceptions import PlugwiseException from plugwise.exceptions import PlugwiseException
from plugwise.smile import Smile
from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
@ -18,6 +20,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import ( from .const import (
COORDINATOR, COORDINATOR,
@ -32,8 +35,6 @@ from .gateway import SmileGateway
HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO] HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO]
HVAC_MODES_HEAT_COOL = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO] HVAC_MODES_HEAT_COOL = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO]
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -66,8 +67,6 @@ async def async_setup_entry(
dev_id, dev_id,
device_properties["location"], device_properties["location"],
device_properties["class"], device_properties["class"],
DEFAULT_MIN_TEMP,
DEFAULT_MAX_TEMP,
) )
entities.append(thermostat) entities.append(thermostat)
@ -78,199 +77,137 @@ async def async_setup_entry(
class PwThermostat(SmileGateway, ClimateEntity): class PwThermostat(SmileGateway, ClimateEntity):
"""Representation of an Plugwise thermostat.""" """Representation of an Plugwise thermostat."""
_attr_hvac_mode = HVAC_MODE_HEAT
_attr_max_temp = DEFAULT_MAX_TEMP
_attr_min_temp = DEFAULT_MIN_TEMP
_attr_preset_mode = None
_attr_preset_modes = None
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
_attr_temperature_unit = TEMP_CELSIUS
_attr_hvac_modes = HVAC_MODES_HEAT_ONLY
_attr_hvac_mode = HVAC_MODE_HEAT
def __init__( def __init__(
self, api, coordinator, name, dev_id, loc_id, model, min_temp, max_temp self,
): api: Smile,
coordinator: DataUpdateCoordinator,
name: str,
dev_id: str,
loc_id: str,
model: str,
) -> None:
"""Set up the Plugwise API.""" """Set up the Plugwise API."""
super().__init__(api, coordinator, name, dev_id) super().__init__(api, coordinator, name, dev_id)
self._attr_extra_state_attributes = {}
self._api = api self._api = api
self._loc_id = loc_id self._loc_id = loc_id
self._model = model self._model = model
self._min_temp = min_temp
self._max_temp = max_temp
self._selected_schema = None
self._last_active_schema = None
self._preset_mode = None
self._presets = None self._presets = None
self._presets_list = None
self._heating_state = None
self._cooling_state = None
self._compressor_state = None
self._dhw_state = None
self._hvac_mode = None
self._schema_names = None
self._schema_status = None
self._temperature = None
self._setpoint = None
self._water_pressure = None
self._schedule_temp = None
self._hvac_mode = None
self._single_thermostat = self._api.single_master_thermostat() self._single_thermostat = self._api.single_master_thermostat()
self._unique_id = f"{dev_id}-climate" self._unique_id = f"{dev_id}-climate"
@property async def async_set_temperature(self, **kwargs: Any) -> None:
def hvac_action(self):
"""Return the current action."""
if self._single_thermostat:
if self._heating_state:
return CURRENT_HVAC_HEAT
if self._cooling_state:
return CURRENT_HVAC_COOL
return CURRENT_HVAC_IDLE
if self._setpoint > self._temperature:
return CURRENT_HVAC_HEAT
return CURRENT_HVAC_IDLE
@property
def supported_features(self):
"""Return the list of supported features."""
return SUPPORT_FLAGS
@property
def extra_state_attributes(self):
"""Return the device specific state attributes."""
attributes = {}
if self._schema_names:
attributes["available_schemas"] = self._schema_names
if self._selected_schema:
attributes["selected_schema"] = self._selected_schema
return attributes
@property
def preset_modes(self):
"""Return the available preset modes list."""
return self._presets_list
@property
def hvac_modes(self):
"""Return the available hvac modes list."""
if self._compressor_state is not None:
return HVAC_MODES_HEAT_COOL
return HVAC_MODES_HEAT_ONLY
@property
def hvac_mode(self):
"""Return current active hvac state."""
return self._hvac_mode
@property
def target_temperature(self):
"""Return the target_temperature."""
return self._setpoint
@property
def preset_mode(self):
"""Return the active preset."""
if self._presets:
return self._preset_mode
return None
@property
def current_temperature(self):
"""Return the current room temperature."""
return self._temperature
@property
def min_temp(self):
"""Return the minimal temperature possible to set."""
return self._min_temp
@property
def max_temp(self):
"""Return the maximum temperature possible to set."""
return self._max_temp
@property
def temperature_unit(self):
"""Return the unit of measured temperature."""
return TEMP_CELSIUS
async def async_set_temperature(self, **kwargs):
"""Set new target temperature.""" """Set new target temperature."""
temperature = kwargs.get(ATTR_TEMPERATURE) temperature = kwargs.get(ATTR_TEMPERATURE)
if (temperature is not None) and ( if (temperature is not None) and (
self._min_temp < temperature < self._max_temp self._attr_min_temp < temperature < self._attr_max_temp
): ):
try: try:
await self._api.set_temperature(self._loc_id, temperature) await self._api.set_temperature(self._loc_id, temperature)
self._setpoint = temperature self._attr_target_temperature = temperature
self.async_write_ha_state() self.async_write_ha_state()
except PlugwiseException: except PlugwiseException:
_LOGGER.error("Error while communicating to device") _LOGGER.error("Error while communicating to device")
else: else:
_LOGGER.error("Invalid temperature requested") _LOGGER.error("Invalid temperature requested")
async def async_set_hvac_mode(self, hvac_mode): async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set the hvac mode.""" """Set the hvac mode."""
state = SCHEDULE_OFF state = SCHEDULE_OFF
climate_data = self._api.get_device_data(self._dev_id)
if hvac_mode == HVAC_MODE_AUTO: if hvac_mode == HVAC_MODE_AUTO:
state = SCHEDULE_ON state = SCHEDULE_ON
try: try:
await self._api.set_temperature(self._loc_id, self._schedule_temp) await self._api.set_temperature(
self._setpoint = self._schedule_temp self._loc_id, climate_data.get("schedule_temperature")
)
self._attr_target_temperature = climate_data.get("schedule_temperature")
except PlugwiseException: except PlugwiseException:
_LOGGER.error("Error while communicating to device") _LOGGER.error("Error while communicating to device")
try: try:
await self._api.set_schedule_state( await self._api.set_schedule_state(
self._loc_id, self._last_active_schema, state self._loc_id, climate_data.get("last_used"), state
) )
self._hvac_mode = hvac_mode self._attr_hvac_mode = hvac_mode
self.async_write_ha_state() self.async_write_ha_state()
except PlugwiseException: except PlugwiseException:
_LOGGER.error("Error while communicating to device") _LOGGER.error("Error while communicating to device")
async def async_set_preset_mode(self, preset_mode): async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set the preset mode.""" """Set the preset mode."""
if self._presets is None:
raise ValueError("No presets available")
try: try:
await self._api.set_preset(self._loc_id, preset_mode) await self._api.set_preset(self._loc_id, preset_mode)
self._preset_mode = preset_mode self._attr_preset_mode = preset_mode
self._setpoint = self._presets.get(self._preset_mode, "none")[0] self._attr_target_temperature = self._presets.get(preset_mode, "none")[0]
self.async_write_ha_state() self.async_write_ha_state()
except PlugwiseException: except PlugwiseException:
_LOGGER.error("Error while communicating to device") _LOGGER.error("Error while communicating to device")
@callback @callback
def _async_process_data(self): def _async_process_data(self) -> None:
"""Update the data for this climate device.""" """Update the data for this climate device."""
climate_data = self._api.get_device_data(self._dev_id) climate_data = self._api.get_device_data(self._dev_id)
heater_central_data = self._api.get_device_data(self._api.heater_id) heater_central_data = self._api.get_device_data(self._api.heater_id)
if "setpoint" in climate_data: # Current & set temperatures
self._setpoint = climate_data["setpoint"] if setpoint := climate_data.get("setpoint"):
if "temperature" in climate_data: self._attr_target_temperature = setpoint
self._temperature = climate_data["temperature"] if temperature := climate_data.get("temperature"):
if "schedule_temperature" in climate_data: self._attr_current_temperature = temperature
self._schedule_temp = climate_data["schedule_temperature"]
if "available_schedules" in climate_data:
self._schema_names = climate_data["available_schedules"]
if "selected_schedule" in climate_data:
self._selected_schema = climate_data["selected_schedule"]
self._schema_status = False
if self._selected_schema is not None:
self._schema_status = True
if "last_used" in climate_data:
self._last_active_schema = climate_data["last_used"]
if "presets" in climate_data:
self._presets = climate_data["presets"]
if self._presets:
self._presets_list = list(self._presets)
if "active_preset" in climate_data:
self._preset_mode = climate_data["active_preset"]
if heater_central_data.get("heating_state") is not None: # Presets handling
self._heating_state = heater_central_data["heating_state"] self._attr_preset_mode = climate_data.get("active_preset")
if heater_central_data.get("cooling_state") is not None: if presets := climate_data.get("presets"):
self._cooling_state = heater_central_data["cooling_state"] self._presets = presets
self._attr_preset_modes = list(presets)
else:
self._presets = None
self._attr_preset_mode = None
# Determine current hvac action
self._attr_hvac_action = CURRENT_HVAC_IDLE
if self._single_thermostat:
if heater_central_data.get("heating_state"):
self._attr_hvac_action = CURRENT_HVAC_HEAT
elif heater_central_data.get("cooling_state"):
self._attr_hvac_action = CURRENT_HVAC_COOL
elif (
self.target_temperature is not None
and self.current_temperature is not None
and self.target_temperature > self.current_temperature
):
self._attr_hvac_action = CURRENT_HVAC_HEAT
# Determine hvac modes and current hvac mode
self._attr_hvac_mode = HVAC_MODE_HEAT
self._attr_hvac_modes = HVAC_MODES_HEAT_ONLY
if heater_central_data.get("compressor_state") is not None: if heater_central_data.get("compressor_state") is not None:
self._compressor_state = heater_central_data["compressor_state"] self._attr_hvac_mode = HVAC_MODE_HEAT_COOL
self._attr_hvac_modes = HVAC_MODES_HEAT_COOL
if climate_data.get("selected_schedule") is not None:
self._attr_hvac_mode = HVAC_MODE_AUTO
self._hvac_mode = HVAC_MODE_HEAT # Extra attributes
if self._compressor_state is not None: self._attr_extra_state_attributes = {
self._hvac_mode = HVAC_MODE_HEAT_COOL "available_schemas": climate_data.get("available_schedules"),
"selected_schema": climate_data.get("selected_schedule"),
if self._schema_status: }
self._hvac_mode = HVAC_MODE_AUTO
self.async_write_ha_state() self.async_write_ha_state()