-
Notifications
You must be signed in to change notification settings - Fork 9
POC: add unified devices method #151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
karlbeecken
wants to merge
11
commits into
erwindouna:main
Choose a base branch
from
karlbeecken:unified-tadox
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,548
−7
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
6b6873e
add unified devices method
karlbeecken 4550ab3
linter fixes
karlbeecken 2ca03fd
snapshot update, linter
karlbeecken 562e50e
linter, cleanup
karlbeecken 5d3c1ed
fix typing
karlbeecken b1d3687
ruff format, pylint
karlbeecken 2a7eb54
pylint
karlbeecken 79a0e1d
Merge branch 'main' into unified-tadox
karlbeecken ebbd615
add offset for x unified class
karlbeecken 1d9ea32
update snapshots
karlbeecken f19d844
move to unifier class
karlbeecken File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| """Wrapper for Tado v3 API.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING | ||
|
|
||
| import orjson | ||
|
|
||
| from tadoasync.models_v3 import Device, TemperatureOffset, Zone | ||
|
|
||
| if TYPE_CHECKING: | ||
| from tadoasync.tadoasync import Tado | ||
|
|
||
|
|
||
| class ApiV3: | ||
| """Wrapper class for the Tado v3 API.""" | ||
|
|
||
| def __init__(self, base: Tado) -> None: | ||
| """Initialize the API wrapper.""" | ||
| self._base = base | ||
|
|
||
| async def get_zones(self) -> list[Zone]: | ||
| """Get zones.""" | ||
| response = await self._base._request( # noqa: SLF001 | ||
| uri=f"homes/{self._base._home_id}/zones", # noqa: SLF001 | ||
| ) | ||
| obj = orjson.loads(response) | ||
| return [Zone.from_dict(zone) for zone in obj] | ||
|
|
||
| async def get_devices(self) -> list[Device]: | ||
| """Get devices.""" | ||
| response = await self._base._request( # noqa: SLF001 | ||
| uri=f"homes/{self._base._home_id}/devices", # noqa: SLF001 | ||
| ) | ||
| obj = orjson.loads(response) | ||
| return [Device.from_dict(device) for device in obj] | ||
|
|
||
| async def get_device(self, serial_no: str) -> Device: | ||
| """Get device.""" | ||
| response = await self._base._request( # noqa: SLF001 | ||
| uri=f"homes/{self._base._home_id}/devices/{serial_no}", # noqa: SLF001 | ||
| ) | ||
| return Device.from_json(response) | ||
|
|
||
| async def get_device_temperature_offset(self, serial_no: str) -> TemperatureOffset: | ||
| """Get the device temperature offset.""" | ||
| response = await self._base._request(f"devices/{serial_no}/temperatureOffset") # noqa: SLF001 | ||
| return TemperatureOffset.from_json(response) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| """Wrapper for Tado X API.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING | ||
|
|
||
| from tadoasync.models_x import RoomsAndDevices | ||
|
|
||
| API_URL = "hops.tado.com" | ||
|
|
||
| if TYPE_CHECKING: | ||
| from tadoasync.tadoasync import Tado | ||
|
|
||
|
|
||
| class ApiX: # pylint: disable=too-few-public-methods | ||
| """Wrapper class for the Tado X API.""" | ||
|
|
||
| def __init__(self, base: Tado) -> None: | ||
| """Initialize the API wrapper.""" | ||
| self._base = base | ||
|
|
||
| async def get_rooms_and_devices(self) -> RoomsAndDevices: | ||
| """Get rooms and devices.""" | ||
| response = await self._base._request( # noqa: SLF001 | ||
| endpoint=API_URL, | ||
| uri=f"homes/{self._base._home_id}/roomsAndDevices", # noqa: SLF001 | ||
| ) | ||
| return RoomsAndDevices.from_json(response) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| """Abstract models for interaction with the Tado API, regardless of line.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| from mashumaro.mixins.orjson import DataClassORJSONMixin | ||
|
|
||
| if TYPE_CHECKING: | ||
| from tadoasync import models_v3, models_x | ||
|
|
||
|
|
||
| @dataclass | ||
| class Device(DataClassORJSONMixin): | ||
| """Device model.""" | ||
|
|
||
| device_type: str | ||
| serial: str | ||
| firmware_version: str | ||
|
|
||
| connection_state: bool | ||
|
|
||
| battery_state: str | None | ||
|
|
||
| temperature_offset: float | None = None | ||
|
|
||
| child_lock_enabled: bool | None = None | ||
|
|
||
| @classmethod | ||
| def from_v3( | ||
| cls, | ||
| v3_device: models_v3.Device, | ||
| offset: models_v3.TemperatureOffset | None = None, | ||
| ) -> Device: | ||
| """Create a device from the v3 API.""" | ||
| return cls( | ||
| device_type=v3_device.device_type, | ||
| serial=v3_device.serial_no, | ||
| firmware_version=v3_device.current_fw_version, | ||
| temperature_offset=offset.celsius if offset else None, | ||
| connection_state=v3_device.connection_state.value, | ||
| battery_state=v3_device.battery_state, | ||
| child_lock_enabled=v3_device.child_lock_enabled, | ||
| ) | ||
|
|
||
| @classmethod | ||
| def from_x( | ||
| cls, | ||
| x_device: models_x.Device, | ||
| ) -> Device: | ||
| """Create a device from the X API.""" | ||
| return cls( | ||
| device_type=x_device.type, | ||
| serial=x_device.serial_number, | ||
| firmware_version=x_device.firmware_version, | ||
| temperature_offset=x_device.temperature_offset, | ||
| connection_state=x_device.connection.state == "CONNECTED", | ||
| battery_state=x_device.battery_state, | ||
| child_lock_enabled=x_device.child_lock_enabled, | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| """Models for the Tado API.""" | ||
| """Models for the Tado v3 API.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| """Models for the Tado X API.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass, field | ||
| from typing import Any | ||
|
|
||
| from mashumaro import field_options | ||
| from mashumaro.mixins.orjson import DataClassORJSONMixin | ||
|
|
||
|
|
||
| @dataclass | ||
| class DeviceManualControlTermination(DataClassORJSONMixin): | ||
| """Represents the manual control termination settings of a device.""" | ||
|
|
||
| type: str | ||
| duration_in_seconds: int | None = field( | ||
| metadata=field_options(alias="durationInSeconds") | ||
| ) | ||
|
|
||
|
|
||
| @dataclass | ||
| class Connection(DataClassORJSONMixin): | ||
| """Connection model represents the connection information of a device.""" | ||
|
|
||
| state: str | ||
|
|
||
|
|
||
| @dataclass | ||
| class Device(DataClassORJSONMixin): | ||
| """Device model represents the device information.""" | ||
|
|
||
| serial_number: str = field(metadata=field_options(alias="serialNumber")) | ||
| type: str | ||
| firmware_version: str = field(metadata=field_options(alias="firmwareVersion")) | ||
| connection: Connection | ||
| battery_state: str | None = field( | ||
| default=None, metadata=field_options(alias="batteryState") | ||
| ) | ||
| temperature_as_measured: float | None = field( | ||
| default=None, metadata=field_options(alias="temperatureAsMeasured") | ||
| ) | ||
| temperature_offset: float | None = field( | ||
| default=None, metadata=field_options(alias="temperatureOffset") | ||
| ) | ||
| mounting_state: str | None = field( | ||
| default=None, metadata=field_options(alias="mountingState") | ||
| ) | ||
| child_lock_enabled: bool | None = field( | ||
| default=None, metadata=field_options(alias="childLockEnabled") | ||
| ) | ||
|
|
||
|
|
||
| @dataclass | ||
| class Room(DataClassORJSONMixin): | ||
| """Room model represents the room information of a home.""" | ||
|
|
||
| room_id: int = field(metadata=field_options(alias="roomId")) | ||
| room_name: str = field(metadata=field_options(alias="roomName")) | ||
| device_manual_control_termination: DeviceManualControlTermination = field( | ||
| metadata=field_options(alias="deviceManualControlTermination") | ||
| ) | ||
| devices: list[Device] | ||
| zone_controller_assignable: bool = field( | ||
| metadata=field_options(alias="zoneControllerAssignable") | ||
| ) | ||
| zone_controllers: list[Any] = field(metadata=field_options(alias="zoneControllers")) | ||
| room_link_available: bool = field(metadata=field_options(alias="roomLinkAvailable")) | ||
|
|
||
|
|
||
| @dataclass | ||
| class RoomsAndDevices(DataClassORJSONMixin): | ||
| """RoomsAndDevices model represents the rooms and devices information of a home.""" | ||
|
|
||
| rooms: list[Room] | ||
| other_devices: list[Device] = field(metadata=field_options(alias="otherDevices")) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.