Skip to content

Commit

Permalink
refactor for camel case everywhere (incomplete)
Browse files Browse the repository at this point in the history
  • Loading branch information
zxdavb committed Oct 30, 2024
1 parent 8304a6d commit 609c6be
Show file tree
Hide file tree
Showing 16 changed files with 747 additions and 684 deletions.
4 changes: 2 additions & 2 deletions src/evohomeasync2/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .location import Location
from .schema import SCH_FULL_CONFIG, SCH_USER_ACCOUNT
from .schema.const import SZ_USER_ID
from .session import AbstractTokenManager, Auth
from .session import AbstractTokenManager, Auth, camel_to_snake

if TYPE_CHECKING:
from .schema import _EvoDictT, _EvoListT, _ScheduleT
Expand Down Expand Up @@ -227,7 +227,7 @@ async def _installation(self, refresh_status: bool = True) -> _EvoListT:
# FIXME: shouldn't really be starting again with new objects?
self.locations = [] # for now, need to clear this before GET

url = f"location/installationInfo?userId={self.account_info[SZ_USER_ID]}"
url = f"location/installationInfo?userId={self.account_info[camel_to_snake(SZ_USER_ID)]}"
url += "&includeTemperatureControlSystems=True"

self._full_config = await self.broker.get(url, schema=SCH_FULL_CONFIG) # type: ignore[assignment]
Expand Down
30 changes: 20 additions & 10 deletions src/evohomeasync2/controlsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
SZ_ZONES,
EntityType,
)
from .session import camel_to_snake
from .zone import ActiveFaultsBase, Zone

if TYPE_CHECKING:
Expand Down Expand Up @@ -125,7 +126,11 @@ class ControlSystem(ActiveFaultsBase, _ControlSystemDeprecated):
TYPE: Final = EntityType.TCS # type: ignore[misc]

def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:
super().__init__(config[SZ_SYSTEM_ID], gateway._broker, gateway._logger)
super().__init__(
config[camel_to_snake(SZ_SYSTEM_ID)],
gateway._broker,
gateway._logger,
)

self.gateway = gateway # parent
self.location: Location = gateway.location
Expand All @@ -147,7 +152,7 @@ def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:
zone = Zone(self, zon_config)
except exc.InvalidSchema as err:
self._logger.warning(
f"{self}: zone_id='{zon_config[SZ_ZONE_ID]}' ignored: {err}"
f"{self}: zone_id='{zon_config[camel_to_snake(SZ_ZONE_ID)]}' ignored: {err}"
)
else:
self._zones.append(zone)
Expand All @@ -160,12 +165,12 @@ def __init__(self, gateway: Gateway, config: _EvoDictT) -> None:

@property
def allowedSystemModes(self) -> _EvoListT:
ret: _EvoListT = self._config[SZ_ALLOWED_SYSTEM_MODES]
ret: _EvoListT = self._config[camel_to_snake(SZ_ALLOWED_SYSTEM_MODES)]
return ret

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

async def _refresh_status(self) -> _EvoDictT:
Expand All @@ -178,28 +183,31 @@ def _update_status(self, status: _EvoDictT) -> None:
self._status = status

if dhw_status := self._status.get(SZ_DHW):
if self.hotwater and self.hotwater.id == dhw_status[SZ_DHW_ID]:
if (
self.hotwater
and self.hotwater.id == dhw_status[camel_to_snake(SZ_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[camel_to_snake(SZ_DHW_ID)]}' not known"
", (has the system configuration been changed?)"
)

for zon_status in self._status[SZ_ZONES]:
if zone := self.zones_by_id.get(zon_status[SZ_ZONE_ID]):
if zone := self.zones_by_id.get(zon_status[camel_to_snake(SZ_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[camel_to_snake(SZ_ZONE_ID)]}' not known"
", (has the system configuration been changed?)"
)

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

@property # status attr for convenience (new)
def system_mode(self) -> str | None:
Expand All @@ -221,7 +229,9 @@ 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.allowedSystemModes]:
if mode not in [
m[camel_to_snake(SZ_SYSTEM_MODE)] for m in self.allowedSystemModes
]:
raise exc.InvalidParameter(f"{self}: Unsupported/unknown mode: {mode}")

if until is None:
Expand Down
19 changes: 12 additions & 7 deletions src/evohomeasync2/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
SZ_TEMPERATURE_CONTROL_SYSTEMS,
EntityType,
)
from .session import camel_to_snake
from .zone import ActiveFaultsBase

if TYPE_CHECKING:
Expand All @@ -44,20 +45,22 @@ class Gateway(_GatewayDeprecated, ActiveFaultsBase):

def __init__(self, location: Location, config: _EvoDictT) -> None:
super().__init__(
config[SZ_GATEWAY_INFO][SZ_GATEWAY_ID], location._broker, location._logger
config[camel_to_snake(SZ_GATEWAY_INFO)][camel_to_snake(SZ_GATEWAY_ID)],
location._broker,
location._logger,
)

self.location = location # parent

self._config: Final[_EvoDictT] = config[SZ_GATEWAY_INFO]
self._config: Final[_EvoDictT] = config[camel_to_snake(SZ_GATEWAY_INFO)]
self._status: _EvoDictT = {}

# children
self._control_systems: list[ControlSystem] = []
self.control_systems: dict[str, ControlSystem] = {} # tcs by id

tcs_config: _EvoDictT
for tcs_config in config[SZ_TEMPERATURE_CONTROL_SYSTEMS]:
for tcs_config in config[camel_to_snake(SZ_TEMPERATURE_CONTROL_SYSTEMS)]:
tcs = ControlSystem(self, tcs_config)

self._control_systems.append(tcs)
Expand All @@ -70,20 +73,22 @@ def mac(self) -> str:

@property
def isWiFi(self) -> bool:
ret: bool = self._config[SZ_IS_WI_FI]
ret: bool = self._config[camel_to_snake(SZ_IS_WI_FI)]
return ret

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

self._status = status

for tcs_status in self._status[SZ_TEMPERATURE_CONTROL_SYSTEMS]:
if tcs := self.control_systems.get(tcs_status[SZ_SYSTEM_ID]):
for tcs_status in self._status[camel_to_snake(SZ_TEMPERATURE_CONTROL_SYSTEMS)]:
if tcs := self.control_systems.get(
tcs_status[camel_to_snake(SZ_SYSTEM_ID)]
):
tcs._update_status(tcs_status)

else:
self._logger.warning(
f"{self}: system_id='{tcs_status[SZ_SYSTEM_ID]}' not known"
f"{self}: system_id='{tcs_status[camel_to_snake(SZ_SYSTEM_ID)]}' not known"
", (has the gateway configuration been changed?)"
)
15 changes: 10 additions & 5 deletions src/evohomeasync2/hotwater.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
EntityType,
ZoneMode,
)
from .session import camel_to_snake
from .zone import _ZoneBase

if TYPE_CHECKING:
Expand Down Expand Up @@ -71,21 +72,25 @@ class HotWater(HotWaterDeprecated, _ZoneBase):
SCH_SCHEDULE_PUT: Final[vol.Schema] = SCH_PUT_SCHEDULE_DHW # type: ignore[misc]

def __init__(self, tcs: ControlSystem, config: _EvoDictT) -> None:
super().__init__(config[SZ_DHW_ID], tcs, config)
super().__init__(config[camel_to_snake(SZ_DHW_ID)], tcs, config)

@property
def dhwStateCapabilitiesResponse(self) -> _EvoDictT:
ret: _EvoDictT = self._config[SZ_DHW_STATE_CAPABILITIES_RESPONSE]
ret: _EvoDictT = self._config[
camel_to_snake(SZ_DHW_STATE_CAPABILITIES_RESPONSE)
]
return ret

@property
def scheduleCapabilitiesResponse(self) -> _EvoDictT:
ret: _EvoDictT = self._config[SZ_SCHEDULE_CAPABILITIES_RESPONSE]
ret: _EvoDictT = self._config[camel_to_snake(SZ_SCHEDULE_CAPABILITIES_RESPONSE)]
return ret

@property # for convenience (is not a top-level config attribute)
def allowedModes(self) -> _EvoListT:
ret: _EvoListT = self.dhwStateCapabilitiesResponse[SZ_ALLOWED_MODES]
ret: _EvoListT = self.dhwStateCapabilitiesResponse[
camel_to_snake(SZ_ALLOWED_MODES)
]
return ret

@property
Expand All @@ -94,7 +99,7 @@ def name(self) -> str:

@property
def stateStatus(self) -> _EvoDictT | None:
return self._status.get(SZ_STATE_STATUS)
return self._status.get(camel_to_snake(SZ_STATE_STATUS))

@property # status attr for convenience (new)
def mode(self) -> str | None:
Expand Down
19 changes: 11 additions & 8 deletions src/evohomeasync2/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
SZ_USE_DAYLIGHT_SAVE_SWITCHING,
EntityType,
)
from .session import camel_to_snake
from .zone import EntityBase

if TYPE_CHECKING:
Expand Down Expand Up @@ -51,12 +52,14 @@ class Location(_LocationDeprecated, EntityBase):

def __init__(self, client: EvohomeClient, config: _EvoDictT) -> None:
super().__init__(
config[SZ_LOCATION_INFO][SZ_LOCATION_ID], client.broker, client._logger
config[camel_to_snake(SZ_LOCATION_INFO)][camel_to_snake(SZ_LOCATION_ID)],
client.broker,
client._logger,
)

self.client = client # proxy for parent

self._config: Final[_EvoDictT] = config[SZ_LOCATION_INFO]
self._config: Final[_EvoDictT] = config[camel_to_snake(SZ_LOCATION_INFO)]
self._status: _EvoDictT = {}

# children
Expand All @@ -77,12 +80,12 @@ def country(self) -> str:

@property
def locationOwner(self) -> _EvoDictT:
ret: _EvoDictT = self._config[SZ_LOCATION_OWNER]
ret: _EvoDictT = self._config[camel_to_snake(SZ_LOCATION_OWNER)]
return ret

@property
def locationType(self) -> str:
ret: str = self._config[SZ_LOCATION_TYPE]
ret: str = self._config[camel_to_snake(SZ_LOCATION_TYPE)]
return ret

@property
Expand All @@ -92,12 +95,12 @@ def name(self) -> str:

@property
def timeZone(self) -> _EvoDictT:
ret: _EvoDictT = self._config[SZ_TIME_ZONE]
ret: _EvoDictT = self._config[camel_to_snake(SZ_TIME_ZONE)]
return ret

@property
def useDaylightSaveSwitching(self) -> bool:
ret: bool = self._config[SZ_USE_DAYLIGHT_SAVE_SWITCHING]
ret: bool = self._config[camel_to_snake(SZ_USE_DAYLIGHT_SAVE_SWITCHING)]
return ret

async def refresh_status(self) -> _EvoDictT:
Expand All @@ -117,11 +120,11 @@ def _update_status(self, status: _EvoDictT) -> None:
self._status = status

for gwy_status in self._status[SZ_GATEWAYS]:
if gwy := self.gateways.get(gwy_status[SZ_GATEWAY_ID]):
if gwy := self.gateways.get(gwy_status[camel_to_snake(SZ_GATEWAY_ID)]):
gwy._update_status(gwy_status)

else:
self._logger.warning(
f"{self}: gateway_id='{gwy_status[SZ_GATEWAY_ID]} not known"
f"{self}: gateway_id='{gwy_status[camel_to_snake(SZ_GATEWAY_ID)]} not known"
", (has the location configuration been changed?)"
)
2 changes: 1 addition & 1 deletion src/evohomeasync2/schema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@
SCH_TEMPERATURE_CONTROL_SYSTEM as SCH_TCS_STATUS,
SCH_ZONE as SCH_ZONE_STATUS,
)
from .typing import _EvoDictT, _EvoLeafT, _EvoListT, _EvoSchemaT, _ModeT # noqa: F401
from .typedefs import _EvoDictT, _EvoLeafT, _EvoListT, _EvoSchemaT, _ModeT # noqa: F401
2 changes: 1 addition & 1 deletion src/evohomeasync2/schema/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
SZ_TIME_OF_DAY,
)
from .helpers import pascal_case
from .typing import _EvoDictT, _EvoListT
from .typedefs import _EvoDictT, _EvoListT

_ScheduleT = dict[str, dict[str, Any]]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""evohomeasync2 schema - shared types."""
"""evohomeasync2 schema - shared types (WIP)."""

from typing import Any

Expand Down
23 changes: 21 additions & 2 deletions src/evohomeasync2/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from __future__ import annotations

import logging
import re
from abc import ABC, abstractmethod
from datetime import datetime as dt, timedelta as td
from http import HTTPMethod, HTTPStatus
from typing import TYPE_CHECKING, Any, Final, TypedDict
from typing import TYPE_CHECKING, Any, Final, TypedDict, TypeVar

import aiohttp
import voluptuous as vol
Expand Down Expand Up @@ -354,7 +355,7 @@ async def get(self, url: StrOrURL, schema: vol.Schema | None = None) -> _EvoSche
f"Response JSON may be invalid: GET {url}: vol.Invalid({err})"
)

return content
return convert_keys_to_snake_case(content)

async def put(
self, url: StrOrURL, json: _EvoDictT | str, schema: vol.Schema | None = None
Expand All @@ -378,3 +379,21 @@ async def put(
)

return content


_T = TypeVar("_T")


def camel_to_snake(name: str) -> str:
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()


def convert_keys_to_snake_case(data: _T) -> _T:
if isinstance(data, list):
return [convert_keys_to_snake_case(item) for item in data] # type: ignore[return-value]

if not isinstance(data, dict):
return data

return {camel_to_snake(k): convert_keys_to_snake_case(v) for k, v in data.items()} # type: ignore[return-value]
Loading

0 comments on commit 609c6be

Please sign in to comment.