Skip to content
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

feat: add config and status for BLU TRV #688

Merged
merged 18 commits into from
Jan 9, 2025
Merged
11 changes: 9 additions & 2 deletions aioshelly/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,13 @@
# Firmware 1.0.99 release date
GEN3_MIN_FIRMWARE_DATE = 20231102

# Firmware 1.5.x release date
# Temporary use beta release to allow BluTrv support
GEN3_GATEWAY_MIN_FIRMWARE_DATE = 20241219
chemelli74 marked this conversation as resolved.
Show resolved Hide resolved

# Firmware 1.4.x release date
GEN4_MIN_FIRMWARE_DATE = 20240902


# Fallback for unknown devices
MIN_FIRMWARE_DATES = {
GEN1: GEN1_MIN_FIRMWARE_DATE,
Expand Down Expand Up @@ -473,7 +476,7 @@ class ShellyDevice:
MODEL_BLU_GATEWAY_GEN3: ShellyDevice(
model="S3GW-1DBT001",
name="Shelly BLU Gateway Gen3",
min_fw_date=GEN3_MIN_FIRMWARE_DATE,
min_fw_date=GEN3_GATEWAY_MIN_FIRMWARE_DATE,
gen=GEN3,
supported=True,
),
Expand Down Expand Up @@ -929,6 +932,10 @@ class ShellyDevice:
MODEL_VINTAGE_V2,
}

BLU_TRV_IDENTIFIER = "blutrv"
BLU_TRV_MODEL_ID = {8: "SBTR-001AEU"}
BLU_TRV_MODEL_NAME = {"SBTR-001AEU": "Shelly BLU TRV"}


class UndefinedType(Enum):
"""Singleton type for use with not set sentinel values."""
Expand Down
38 changes: 37 additions & 1 deletion aioshelly/rpc_device/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
process_ip_or_options,
)
from ..const import (
BLU_TRV_IDENTIFIER,
BLU_TRV_MODEL_ID,
CONNECT_ERRORS,
DEVICE_INIT_TIMEOUT,
DEVICE_IO_TIMEOUT,
DEVICE_POLL_TIMEOUT,
FIRMWARE_PATTERN,
MODEL_BLU_GATEWAY_GEN3,
NOTIFY_WS_CLOSED,
VIRTUAL_COMPONENTS,
VIRTUAL_COMPONENTS_MIN_FIRMWARE,
Expand Down Expand Up @@ -280,6 +283,7 @@
self._status = results[0]
if has_dynamic:
self._parse_dynamic_components(results[1])
await self._retrieve_blutrv_components(results[1])

Check warning on line 286 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L286

Added line #L286 was not covered by tests

async def _init_calls(self) -> None:
"""Make calls needed to initialize the device."""
Expand Down Expand Up @@ -309,7 +313,9 @@
if fetch_status:
self._status = results.pop(0)
if fetch_dynamic:
self._parse_dynamic_components(results.pop(0))
components = results.pop(0)
self._parse_dynamic_components(components)
await self._retrieve_blutrv_components(components)

Check warning on line 318 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L316-L318

Added lines #L316 - L318 were not covered by tests
chemelli74 marked this conversation as resolved.
Show resolved Hide resolved

async def script_list(self) -> list[ShellyScript]:
"""Get a list of scripts from 'Script.List'."""
Expand Down Expand Up @@ -509,6 +515,7 @@
return
components = await self.call_rpc("Shelly.GetComponents", {"dynamic_only": True})
self._parse_dynamic_components(components)
await self._retrieve_blutrv_components(components)

Check warning on line 518 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L518

Added line #L518 was not covered by tests

def _supports_dynamic_components(self) -> bool:
"""Return True if device supports dynamic components."""
Expand Down Expand Up @@ -538,3 +545,32 @@
for item in self._dynamic_components
}
)

async def _retrieve_blutrv_components(self, components: dict[str, Any]) -> None:
chemelli74 marked this conversation as resolved.
Show resolved Hide resolved
"""Retrieve BLU TRV components."""
if self.model != MODEL_BLU_GATEWAY_GEN3:
return

Check warning on line 552 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L551-L552

Added lines #L551 - L552 were not covered by tests

if not self._config or not self._status:
raise NotInitialized

Check warning on line 555 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L554-L555

Added lines #L554 - L555 were not covered by tests

for component in components.get("components", []):
_key = component["key"].split(":")

Check warning on line 558 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L557-L558

Added lines #L557 - L558 were not covered by tests

if _key[0] != BLU_TRV_IDENTIFIER:
continue

Check warning on line 561 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L560-L561

Added lines #L560 - L561 were not covered by tests

calls = [

Check warning on line 563 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L563

Added line #L563 was not covered by tests
("BluTrv.GetRemoteConfig", {"id": _key[1]}),
("BluTrv.GetRemoteStatus", {"id": _key[1]}),
]
results = await self.call_rpc_multiple(calls)

Check warning on line 567 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L567

Added line #L567 was not covered by tests

cfg: dict[str, Any] = results[0]["config"]["trv:0"]

Check warning on line 569 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L569

Added line #L569 was not covered by tests
# addr, name and model_id must be added from Shelly.GetComponents call
_attrs = component.get("attrs", {})
cfg.update({"addr": component["config"]["addr"]})
cfg.update({"name": component["config"]["name"]})
cfg.update({"local_name": BLU_TRV_MODEL_ID.get(_attrs.get("model_id"))})
self._config.update({component["key"]: cfg})
self._status.update({component["key"]: results[1]["status"]["trv:0"]})

Check warning on line 576 in aioshelly/rpc_device/device.py

View check run for this annotation

Codecov / codecov/patch

aioshelly/rpc_device/device.py#L571-L576

Added lines #L571 - L576 were not covered by tests
Loading