Use library constants instead of literals in Evohome (#105039)

* initial commit

* roll back some consts

* doctweak

* tweak linting

* doctweak
This commit is contained in:
David Bonnes 2023-12-17 22:08:18 +00:00 committed by GitHub
parent 67d903ca99
commit 45b5ddfad7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 27 deletions

View File

@ -11,8 +11,24 @@ import re
from typing import Any
import evohomeasync
from evohomeasync.schema import SZ_ID, SZ_SESSION_ID, SZ_TEMP
import evohomeasync2
import voluptuous as vol
from evohomeasync2.schema.const import (
SZ_ALLOWED_SYSTEM_MODES,
SZ_AUTO_WITH_RESET,
SZ_CAN_BE_TEMPORARY,
SZ_HEAT_SETPOINT,
SZ_LOCATION_INFO,
SZ_SETPOINT_STATUS,
SZ_STATE_STATUS,
SZ_SYSTEM_MODE,
SZ_SYSTEM_MODE_STATUS,
SZ_TIME_UNTIL,
SZ_TIME_ZONE,
SZ_TIMING_MODE,
SZ_UNTIL,
)
import voluptuous as vol # type: ignore[import-untyped]
from homeassistant.const import (
ATTR_ENTITY_ID,
@ -243,17 +259,19 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
if _LOGGER.isEnabledFor(logging.DEBUG):
_config: dict[str, Any] = {
"locationInfo": {"timeZone": None},
SZ_LOCATION_INFO: {SZ_TIME_ZONE: None},
GWS: [{TCS: None}],
}
_config["locationInfo"]["timeZone"] = loc_config["locationInfo"]["timeZone"]
_config[SZ_LOCATION_INFO][SZ_TIME_ZONE] = loc_config[SZ_LOCATION_INFO][
SZ_TIME_ZONE
]
_config[GWS][0][TCS] = loc_config[GWS][0][TCS]
_LOGGER.debug("Config = %s", _config)
client_v1 = evohomeasync.EvohomeClient(
client_v2.username,
client_v2.password,
session_id=user_data.get("sessionId") if user_data else None, # STORAGE_VER 1
session_id=user_data.get(SZ_SESSION_ID) if user_data else None, # STORAGE_VER 1
session=async_get_clientsession(hass),
)
@ -333,25 +351,25 @@ def setup_service_functions(hass: HomeAssistant, broker):
hass.services.async_register(DOMAIN, SVC_REFRESH_SYSTEM, force_refresh)
# Enumerate which operating modes are supported by this system
modes = broker.config["allowedSystemModes"]
modes = broker.config[SZ_ALLOWED_SYSTEM_MODES]
# Not all systems support "AutoWithReset": register this handler only if required
if [m["systemMode"] for m in modes if m["systemMode"] == "AutoWithReset"]:
if [m[SZ_SYSTEM_MODE] for m in modes if m[SZ_SYSTEM_MODE] == SZ_AUTO_WITH_RESET]:
hass.services.async_register(DOMAIN, SVC_RESET_SYSTEM, set_system_mode)
system_mode_schemas = []
modes = [m for m in modes if m["systemMode"] != "AutoWithReset"]
modes = [m for m in modes if m[SZ_SYSTEM_MODE] != SZ_AUTO_WITH_RESET]
# Permanent-only modes will use this schema
perm_modes = [m["systemMode"] for m in modes if not m["canBeTemporary"]]
perm_modes = [m[SZ_SYSTEM_MODE] for m in modes if not m[SZ_CAN_BE_TEMPORARY]]
if perm_modes: # any of: "Auto", "HeatingOff": permanent only
schema = vol.Schema({vol.Required(ATTR_SYSTEM_MODE): vol.In(perm_modes)})
system_mode_schemas.append(schema)
modes = [m for m in modes if m["canBeTemporary"]]
modes = [m for m in modes if m[SZ_CAN_BE_TEMPORARY]]
# These modes are set for a number of hours (or indefinitely): use this schema
temp_modes = [m["systemMode"] for m in modes if m["timingMode"] == "Duration"]
temp_modes = [m[SZ_SYSTEM_MODE] for m in modes if m[SZ_TIMING_MODE] == "Duration"]
if temp_modes: # any of: "AutoWithEco", permanent or for 0-24 hours
schema = vol.Schema(
{
@ -365,7 +383,7 @@ def setup_service_functions(hass: HomeAssistant, broker):
system_mode_schemas.append(schema)
# These modes are set for a number of days (or indefinitely): use this schema
temp_modes = [m["systemMode"] for m in modes if m["timingMode"] == "Period"]
temp_modes = [m[SZ_SYSTEM_MODE] for m in modes if m[SZ_TIMING_MODE] == "Period"]
if temp_modes: # any of: "Away", "Custom", "DayOff", permanent or for 1-99 days
schema = vol.Schema(
{
@ -509,7 +527,7 @@ class EvoBroker:
)
self.client_v1 = None
else:
self.temps = {str(i["id"]): i["temp"] for i in temps}
self.temps = {str(i[SZ_ID]): i[SZ_TEMP] for i in temps}
finally:
if self.client_v1 and session_id != self.client_v1.broker.session_id:
@ -591,12 +609,12 @@ class EvoDevice(Entity):
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the evohome-specific state attributes."""
status = self._device_state_attrs
if "systemModeStatus" in status:
convert_until(status["systemModeStatus"], "timeUntil")
if "setpointStatus" in status:
convert_until(status["setpointStatus"], "until")
if "stateStatus" in status:
convert_until(status["stateStatus"], "until")
if SZ_SYSTEM_MODE_STATUS in status:
convert_until(status[SZ_SYSTEM_MODE_STATUS], SZ_TIME_UNTIL)
if SZ_SETPOINT_STATUS in status:
convert_until(status[SZ_SETPOINT_STATUS], SZ_UNTIL)
if SZ_STATE_STATUS in status:
convert_until(status[SZ_STATE_STATUS], SZ_UNTIL)
return {"status": convert_dict(status)}
@ -675,7 +693,7 @@ class EvoChild(EvoDevice):
self._setpoints[f"{key}_sp_from"] = dt_aware.isoformat()
try:
self._setpoints[f"{key}_sp_temp"] = switchpoint["heatSetpoint"]
self._setpoints[f"{key}_sp_temp"] = switchpoint[SZ_HEAT_SETPOINT]
except KeyError:
self._setpoints[f"{key}_sp_state"] = switchpoint["DhwState"]

View File

@ -5,6 +5,20 @@ from datetime import datetime as dt
import logging
from typing import Any
from evohomeasync2.schema.const import (
SZ_ACTIVE_FAULTS,
SZ_ALLOWED_SYSTEM_MODES,
SZ_SETPOINT_STATUS,
SZ_SYSTEM_ID,
SZ_SYSTEM_MODE,
SZ_SYSTEM_MODE_STATUS,
SZ_TEMPERATURE_STATUS,
SZ_UNTIL,
SZ_ZONE_ID,
ZoneModelType,
ZoneType,
)
from homeassistant.components.climate import (
PRESET_AWAY,
PRESET_ECO,
@ -71,8 +85,13 @@ EVO_PRESET_TO_HA = {
}
HA_PRESET_TO_EVO = {v: k for k, v in EVO_PRESET_TO_HA.items()}
STATE_ATTRS_TCS = ["systemId", "activeFaults", "systemModeStatus"]
STATE_ATTRS_ZONES = ["zoneId", "activeFaults", "setpointStatus", "temperatureStatus"]
STATE_ATTRS_TCS = [SZ_SYSTEM_ID, SZ_ACTIVE_FAULTS, SZ_SYSTEM_MODE_STATUS]
STATE_ATTRS_ZONES = [
SZ_ZONE_ID,
SZ_ACTIVE_FAULTS,
SZ_SETPOINT_STATUS,
SZ_TEMPERATURE_STATUS,
]
async def async_setup_platform(
@ -98,7 +117,10 @@ async def async_setup_platform(
entities: list[EvoClimateEntity] = [EvoController(broker, broker.tcs)]
for zone in broker.tcs.zones.values():
if zone.modelType == "HeatingZone" or zone.zoneType == "Thermostat":
if (
zone.modelType == ZoneModelType.HEATING_ZONE
or zone.zoneType == ZoneType.THERMOSTAT
):
_LOGGER.debug(
"Adding: %s (%s), id=%s, name=%s",
zone.zoneType,
@ -237,7 +259,9 @@ class EvoZone(EvoChild, EvoClimateEntity):
await self._update_schedule()
until = dt_util.parse_datetime(self.setpoints.get("next_sp_from", ""))
elif self._evo_device.mode == EVO_TEMPOVER:
until = dt_util.parse_datetime(self._evo_device.setpointStatus["until"])
until = dt_util.parse_datetime(
self._evo_device.setpointStatus[SZ_UNTIL]
)
until = dt_util.as_utc(until) if until else None
await self._evo_broker.call_client_api(
@ -318,7 +342,7 @@ class EvoController(EvoClimateEntity):
self._evo_id = evo_device.systemId
self._attr_name = evo_device.location.name
modes = [m["systemMode"] for m in evo_broker.config["allowedSystemModes"]]
modes = [m[SZ_SYSTEM_MODE] for m in evo_broker.config[SZ_ALLOWED_SYSTEM_MODES]]
self._attr_preset_modes = [
TCS_PRESET_TO_HA[m] for m in modes if m in list(TCS_PRESET_TO_HA)
]
@ -400,7 +424,7 @@ class EvoController(EvoClimateEntity):
attrs = self._device_state_attrs
for attr in STATE_ATTRS_TCS:
if attr == "activeFaults":
if attr == SZ_ACTIVE_FAULTS:
attrs["activeSystemFaults"] = getattr(self._evo_tcs, attr)
else:
attrs[attr] = getattr(self._evo_tcs, attr)

View File

@ -3,6 +3,15 @@ from __future__ import annotations
import logging
from evohomeasync2.schema.const import (
SZ_ACTIVE_FAULTS,
SZ_DHW_ID,
SZ_OFF,
SZ_ON,
SZ_STATE_STATUS,
SZ_TEMPERATURE_STATUS,
)
from homeassistant.components.water_heater import (
WaterHeaterEntity,
WaterHeaterEntityFeature,
@ -26,10 +35,10 @@ _LOGGER = logging.getLogger(__name__)
STATE_AUTO = "auto"
HA_STATE_TO_EVO = {STATE_AUTO: "", STATE_ON: "On", STATE_OFF: "Off"}
HA_STATE_TO_EVO = {STATE_AUTO: "", STATE_ON: SZ_ON, STATE_OFF: SZ_OFF}
EVO_STATE_TO_HA = {v: k for k, v in HA_STATE_TO_EVO.items() if k != ""}
STATE_ATTRS_DHW = ["dhwId", "activeFaults", "stateStatus", "temperatureStatus"]
STATE_ATTRS_DHW = [SZ_DHW_ID, SZ_ACTIVE_FAULTS, SZ_STATE_STATUS, SZ_TEMPERATURE_STATUS]
async def async_setup_platform(