Skip to content

Commit

Permalink
rename schema constants (plus other fixes)
Browse files Browse the repository at this point in the history
  • Loading branch information
zxdavb committed Nov 3, 2024
1 parent b177fd8 commit f0e7af2
Show file tree
Hide file tree
Showing 24 changed files with 817 additions and 824 deletions.
4 changes: 2 additions & 2 deletions src/evohomeasync2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from .hotwater import HotWater # noqa: F401
from .location import Location
from .schema import SCH_FULL_CONFIG, SCH_USER_ACCOUNT, convert_keys_to_snake_case
from .schema.const import SZ_USER_ID
from .schema.const import S2_USER_ID
from .zone import Zone # noqa: F401

if TYPE_CHECKING:
Expand Down Expand Up @@ -129,7 +129,7 @@ async def update(
assert self._user_info is not None # mypy hint

if self._install_config is None:
url = f"location/installationInfo?userId={self._user_info[SZ_USER_ID]}"
url = f"location/installationInfo?userId={self._user_info[S2_USER_ID]}"
url += "&includeTemperatureControlSystems=True"

self._install_config = await self.auth.get(url, schema=SCH_FULL_CONFIG) # type: ignore[assignment]
Expand Down
14 changes: 6 additions & 8 deletions src/evohomeasync2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import logging
from abc import ABC, abstractmethod
from collections.abc import Generator
from datetime import datetime as dt, timedelta as td
from http import HTTPMethod, HTTPStatus
from types import TracebackType
Expand All @@ -21,15 +22,15 @@
AUTH_URL,
CREDS_REFRESH_TOKEN,
CREDS_USER_PASSWORD,
URL_BASE,
URL_HOST,
)
from .schema import (
SCH_OAUTH_TOKEN,
SZ_ACCESS_TOKEN,
SZ_ACCESS_TOKEN_EXPIRES,
SZ_EXPIRES_IN,
SZ_PASSWORD,
SZ_REFRESH_TOKEN,
SZ_USERNAME,
URL_BASE,
URL_HOST,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -60,9 +61,6 @@
HTTPStatus.UNAUTHORIZED: "Unauthorized (expired access token/unknown entity id?)",
}

SZ_USERNAME: Final = "Username"
SZ_PASSWORD: Final = "Password"


class OAuthTokenData(TypedDict):
access_token: str
Expand Down Expand Up @@ -298,7 +296,7 @@ async def __aexit__(
self._response.release()
await self._response.wait_for_close()

def __await__(self) -> aiohttp.ClientResponse:
def __await__(self) -> Generator[Any, Any, aiohttp.ClientResponse]:
"""Make this class awaitable."""
return self._await_impl().__await__()

Expand Down
3 changes: 1 addition & 2 deletions src/evohomeasync2/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@

from . import EvohomeClientNew, HotWater, Zone, exceptions as exc
from .auth import AbstractTokenManager, _EvoTokenData
from .const import SZ_NAME, SZ_SCHEDULE
from .const import SZ_ACCESS_TOKEN_EXPIRES, SZ_NAME, SZ_SCHEDULE
from .control_system import ControlSystem
from .schema import SZ_ACCESS_TOKEN_EXPIRES

# all _DBG_* flags should be False for published code
_DBG_DEBUG_CLI = False # for debugging of click
Expand Down
37 changes: 36 additions & 1 deletion src/evohomeasync2/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@

from typing import Final

from .schema import DhwState as DhwState, SystemMode as SystemMode, ZoneMode as ZoneMode
import voluptuous as vol

from .schema import (
DhwState as DhwState,
SystemMode as SystemMode,
ZoneMode as ZoneMode,
obfuscate as _obfuscate,
)

URL_HOST: Final = "https://tccna.honeywell.com"

Expand Down Expand Up @@ -52,10 +59,38 @@
}


# These snake_case equivalents of schema strings
# S2_SYSTEM_MODE: Final = "system_mode"
# SZ_USER_ID: Final = "user_id"


# These are used in TCS.temperatures convenience function
SZ_ID: Final = "id"
SZ_NAME: Final = "name"
SZ_TEMP: Final = "temp"
SZ_THERMOSTAT: Final = "thermostat"
SZ_SCHEDULE: Final = "schedule"
SZ_SETPOINT: Final = "setpoint"


# These are used for v1/v2 authentication (not part of a schema)
SZ_USERNAME: Final = "Username"
SZ_PASSWORD: Final = "Password"

SZ_ACCESS_TOKEN: Final = "access_token"
SZ_ACCESS_TOKEN_EXPIRES: Final = "access_token_expires"
SZ_EXPIRES_IN: Final = "expires_in"
SZ_REFRESH_TOKEN: Final = "refresh_token"
SZ_SCOPE: Final = "scope"
SZ_TOKEN_TYPE: Final = "token_type"


SCH_OAUTH_TOKEN: Final = vol.Schema(
{
vol.Required(SZ_ACCESS_TOKEN): vol.All(str, _obfuscate),
vol.Required(SZ_EXPIRES_IN): int, # 1800 seconds
vol.Required(SZ_REFRESH_TOKEN): vol.All(str, _obfuscate),
vol.Required(SZ_TOKEN_TYPE): str,
vol.Optional(SZ_SCOPE): str, # "EMEA-V1-Basic EMEA-V1-Anonymous"
}
)
86 changes: 43 additions & 43 deletions src/evohomeasync2/control_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@
from .hotwater import HotWater
from .schema import SCH_TCS_STATUS, convert_keys_to_snake_case
from .schema.const import (
SZ_ALLOWED_SYSTEM_MODES,
SZ_DHW,
SZ_DHW_ID,
SZ_IS_AVAILABLE,
SZ_MODE,
SZ_MODEL_TYPE,
SZ_PERMANENT,
SZ_SYSTEM_ID,
SZ_SYSTEM_MODE,
SZ_SYSTEM_MODE_STATUS,
SZ_TARGET_HEAT_TEMPERATURE,
SZ_TEMPERATURE,
SZ_TIME_UNTIL,
SZ_ZONE_ID,
SZ_ZONES,
S2_ALLOWED_SYSTEM_MODES,
S2_DHW,
S2_DHW_ID,
S2_IS_AVAILABLE,
S2_MODE,
S2_MODEL_TYPE,
S2_PERMANENT,
S2_SYSTEM_ID,
S2_SYSTEM_MODE,
S2_SYSTEM_MODE_STATUS,
S2_TARGET_HEAT_TEMPERATURE,
S2_TEMPERATURE,
S2_TIME_UNTIL,
S2_ZONE_ID,
S2_ZONES,
EntityType,
)
from .zone import ActiveFaultsBase, Zone
Expand All @@ -58,7 +58,7 @@ class ControlSystem(ActiveFaultsBase):

def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:
super().__init__(
config[SZ_SYSTEM_ID],
config[S2_SYSTEM_ID],
gateway._broker,
gateway._logger,
)
Expand All @@ -67,7 +67,7 @@ def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:
self.location: Location = gateway.location

self._config: Final[_EvoDictT] = {
k: v for k, v in config.items() if k not in (SZ_DHW, SZ_ZONES)
k: v for k, v in config.items() if k not in (S2_DHW, S2_ZONES)
}
self._status: _EvoDictT = {}

Expand All @@ -78,66 +78,66 @@ def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:
self.hotwater: None | HotWater = None

zon_config: _EvoDictT
for zon_config in config[SZ_ZONES]:
for zon_config in config[S2_ZONES]:
try:
zone = Zone(self, zon_config)
except exc.InvalidSchemaError as err:
self._logger.warning(
f"{self}: zone_id='{zon_config[SZ_ZONE_ID]}' ignored: {err}"
f"{self}: zone_id='{zon_config[S2_ZONE_ID]}' ignored: {err}"
)
else:
self.zones.append(zone)
self.zones_by_name[zone.name] = zone
self.zones_by_id[zone.id] = zone

dhw_config: _EvoDictT
if dhw_config := config.get(SZ_DHW): # type: ignore[assignment]
if dhw_config := config.get(S2_DHW): # type: ignore[assignment]
self.hotwater = HotWater(self, dhw_config)

@property
def allowed_system_modes(self) -> _EvoListT:
ret: _EvoListT = self._config[SZ_ALLOWED_SYSTEM_MODES]
ret: _EvoListT = self._config[S2_ALLOWED_SYSTEM_MODES]
return convert_keys_to_snake_case(ret)

@property
def model_type(self) -> str:
ret: str = self._config[SZ_MODEL_TYPE]
ret: str = self._config[S2_MODEL_TYPE]
return ret

def _update_status(self, status: _EvoDictT) -> None:
super()._update_status(status) # process active faults

self._status = status

for zon_status in self._status[SZ_ZONES]:
if zone := self.zones_by_id.get(zon_status[SZ_ZONE_ID]):
for zon_status in self._status[S2_ZONES]:
if zone := self.zones_by_id.get(zon_status[S2_ZONE_ID]):
zone._update_status(zon_status)

else:
self._logger.warning(
f"{self}: zone_id='{zon_status[SZ_ZONE_ID]}' not known"
f"{self}: zone_id='{zon_status[S2_ZONE_ID]}' not known"
", (has the system configuration been changed?)"
)

if dhw_status := self._status.get(SZ_DHW):
if self.hotwater and self.hotwater.id == dhw_status[SZ_DHW_ID]:
if dhw_status := self._status.get(S2_DHW):
if self.hotwater and self.hotwater.id == dhw_status[S2_DHW_ID]:
self.hotwater._update_status(dhw_status)

else:
self._logger.warning(
f"{self}: dhw_id='{dhw_status[SZ_DHW_ID]}' not known"
f"{self}: dhw_id='{dhw_status[S2_DHW_ID]}' not known"
", (has the system configuration been changed?)"
)

@property
def system_mode_status(self) -> _EvoDictT | None:
return self._status.get(SZ_SYSTEM_MODE_STATUS)
return self._status.get(S2_SYSTEM_MODE_STATUS)

@property # status attr for convenience (new)
def system_mode(self) -> str | None:
if (status := self._status.get(SZ_SYSTEM_MODE_STATUS)) is None:
if (status := self._status.get(S2_SYSTEM_MODE_STATUS)) is None:
return None
ret: str = status[SZ_MODE]
ret: str = status[S2_MODE]
return ret

@property
Expand All @@ -159,21 +159,21 @@ async def set_mode(self, mode: SystemMode, /, *, until: dt | None = None) -> Non
request: _EvoDictT

if mode not in [
m[SZ_SYSTEM_MODE] for m in self._config[SZ_ALLOWED_SYSTEM_MODES]
m[S2_SYSTEM_MODE] for m in self._config[S2_ALLOWED_SYSTEM_MODES]
]:
raise exc.InvalidParameterError(f"{self}: Unsupported/unknown mode: {mode}")

if until is None:
request = {
SZ_SYSTEM_MODE: mode,
SZ_PERMANENT: True,
# SZ_TIME_UNTIL: None,
S2_SYSTEM_MODE: mode,
S2_PERMANENT: True,
# S2_TIME_UNTIL: None,
}
else:
request = {
SZ_SYSTEM_MODE: mode,
SZ_PERMANENT: False,
SZ_TIME_UNTIL: until.strftime(API_STRFTIME),
S2_SYSTEM_MODE: mode,
S2_PERMANENT: False,
S2_TIME_UNTIL: until.strftime(API_STRFTIME),
}

await self._set_mode(request)
Expand Down Expand Up @@ -219,9 +219,9 @@ async def temperatures(self) -> _EvoListT:

if (
isinstance(dhw.temperature_status, dict)
and dhw.temperature_status[SZ_IS_AVAILABLE]
and dhw.temperature_status[S2_IS_AVAILABLE]
):
dhw_status[SZ_TEMP] = dhw.temperature_status[SZ_TEMPERATURE]
dhw_status[SZ_TEMP] = dhw.temperature_status[S2_TEMPERATURE]

result.append(dhw_status)

Expand All @@ -236,14 +236,14 @@ async def temperatures(self) -> _EvoListT:

if isinstance(zone.setpoint_status, dict):
zone_status[SZ_SETPOINT] = zone.setpoint_status[
SZ_TARGET_HEAT_TEMPERATURE
S2_TARGET_HEAT_TEMPERATURE
]

if (
isinstance(zone.temperature_status, dict)
and zone.temperature_status[SZ_IS_AVAILABLE]
and zone.temperature_status[S2_IS_AVAILABLE]
):
zone_status[SZ_TEMP] = zone.temperature_status[SZ_TEMPERATURE]
zone_status[SZ_TEMP] = zone.temperature_status[S2_TEMPERATURE]

result.append(zone_status)

Expand Down
Loading

0 comments on commit f0e7af2

Please sign in to comment.