Skip to content

Commit fe5f773

Browse files
committed
Update api.py
Ajoute une fonction pour aller chercher le devicelist venant de DeviceListInitialValuesReceived au lieu du REST. C'est slow à mon goût
1 parent 24ca5ba commit fe5f773

1 file changed

Lines changed: 48 additions & 4 deletions

File tree

pyhilo/api.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ def __init__(
9797
self.ws_token: str = ""
9898
self.endpoint: str = ""
9999
self._urn: str | None = None
100+
self._websocket_device_cache: list[dict[str, Any]] = []
101+
self._device_cache_ready: asyncio.Event = asyncio.Event()
100102

101103
@classmethod
102104
async def async_create(
@@ -796,13 +798,19 @@ def _transform_graphql_device_to_rest(
796798
async def get_devices(self, location_id: int) -> list[dict[str, Any]]:
797799
"""Get list of all devices.
798800
799-
Now uses GraphQL instead of the deprecated REST endpoint.
800-
Falls back to REST if GraphQL fails or URN is not available.
801+
Prioritizes websocket-cached device data (from DeviceListInitialValuesReceived)
802+
over REST/GraphQL since the websocket provides everything we need.
803+
Falls back to GraphQL, then REST if websocket data unavailable.
801804
"""
802805
devices: list[dict[str, Any]] = []
803806

804-
# Try GraphQL first if we have a URN
805-
if self.urn:
807+
# Try to use cached websocket device data first
808+
# The DeviceHub websocket sends DeviceListInitialValuesReceived with full device info
809+
if self._websocket_device_cache:
810+
LOG.debug("Using cached device list from websocket (%d devices)", len(self._websocket_device_cache))
811+
devices = self._websocket_device_cache.copy()
812+
# Try GraphQL if we have a URN and no websocket cache
813+
elif self.urn:
806814
try:
807815
LOG.debug("Fetching devices via GraphQL for URN: %s", self.urn)
808816
devices = await self.get_devices_graphql(self.urn)
@@ -854,6 +862,42 @@ async def get_devices(self, location_id: int) -> list[dict[str, Any]]:
854862
devices.append(callback())
855863

856864
return devices
865+
866+
def cache_websocket_devices(self, device_list: list[dict[str, Any]]) -> None:
867+
"""Cache device list received from DeviceHub websocket.
868+
869+
The DeviceListInitialValuesReceived message contains the full device list
870+
with all the info we need (id, name, identifier, etc.) in REST format.
871+
This eliminates the need to call the deprecated REST endpoint.
872+
873+
Args:
874+
device_list: List of devices from DeviceListInitialValuesReceived
875+
"""
876+
self._websocket_device_cache = device_list
877+
self._device_cache_ready.set()
878+
LOG.debug("Cached %d devices from websocket", len(device_list))
879+
880+
async def wait_for_device_cache(self, timeout: float = 10.0) -> bool:
881+
"""Wait for the websocket device cache to be populated.
882+
883+
This should be called before devices.async_init() to ensure
884+
device names and IDs are available from the websocket.
885+
886+
Args:
887+
timeout: Maximum time to wait in seconds (default: 10.0)
888+
889+
Returns:
890+
True if cache was populated, False if timeout occurred
891+
"""
892+
try:
893+
await asyncio.wait_for(self._device_cache_ready.wait(), timeout=timeout)
894+
LOG.debug("Device cache ready after waiting")
895+
return True
896+
except asyncio.TimeoutError:
897+
LOG.warning(
898+
"Timeout waiting for websocket device cache, will use fallback method"
899+
)
900+
return False
857901

858902
async def _set_device_attribute(
859903
self,

0 commit comments

Comments
 (0)