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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = 20250109

# 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 @@ async def poll(self) -> None:
self._status = results[0]
if has_dynamic:
self._parse_dynamic_components(results[1])
await self._retrieve_blutrv_components(results[1])

async def _init_calls(self) -> None:
"""Make calls needed to initialize the device."""
Expand Down Expand Up @@ -309,7 +313,9 @@ async def _init_calls(self) -> None:
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)
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 @@ async def get_dynamic_components(self) -> None:
return
components = await self.call_rpc("Shelly.GetComponents", {"dynamic_only": True})
self._parse_dynamic_components(components)
await self._retrieve_blutrv_components(components)

def _supports_dynamic_components(self) -> bool:
"""Return True if device supports dynamic components."""
Expand Down Expand Up @@ -538,3 +545,32 @@ def _parse_dynamic_components(self, components: dict[str, Any]) -> None:
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

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

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

if _key[0] != BLU_TRV_IDENTIFIER:
continue

calls = [
("BluTrv.GetRemoteConfig", {"id": _key[1]}),
("BluTrv.GetRemoteStatus", {"id": _key[1]}),
]
results = await self.call_rpc_multiple(calls)

cfg: dict[str, Any] = results[0]["config"]["trv:0"]
# 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"]})
Loading