Skip to content
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
32 changes: 0 additions & 32 deletions pyhilo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,38 +715,6 @@ async def get_seasons(self, location_id: int) -> list[dict[str, Any]]:

return all_seasons

async def get_gateway(self, location_id: int) -> dict[str, Any]:
"""Gets info about the Hilo hub (gateway)"""
url = self._get_url("Gateways/Info", location_id=location_id)
LOG.debug("Gateway URL is %s", url)
req = await self.async_request("get", url)
saved_attrs = [
"zigBeePairingActivated",
"zigBeeChannel",
"firmwareVersion",
"onlineStatus",
"lastStatusTime",
"disconnected",
]

gw = {
"name": "Hilo Gateway",
"Disconnected": {"value": not req[0].get("onlineStatus") == "Online"},
"type": "Gateway",
"category": "Gateway",
"supportedAttributes": ", ".join(saved_attrs),
"settableAttributes": "",
"id": 1,
"identifier": req[0].get("dsn"),
"sdi": req[0].get("sdi"),
"provider": 1,
"model_number": "EQ000017",
"sw_version": req[0].get("firmwareVersion"),
}
for attr in saved_attrs:
gw[attr] = {"value": req[0].get(attr)}
return gw

async def get_weather(self, location_id: int) -> dict[str, Any]:
"""This will return the current weather like in the app
https://api.hiloenergie.com/Automation/v1/api/Locations/XXXX/Weather
Expand Down
14 changes: 1 addition & 13 deletions pyhilo/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def generate_device(self, device: dict) -> HiloDevice:
return dev

async def update(self) -> None:
"""Update device list from SignalR cache + gateway from REST."""
"""Update device list from SignalR cache"""
# Get devices from SignalR cache (already populated by DeviceListInitialValuesReceived)
cached_devices = self._api.get_device_cache(self.location_id)
generated_devices = []
Expand All @@ -110,18 +110,6 @@ async def update(self) -> None:
if dev not in self.devices:
self.devices.append(dev)

# Append gateway from REST API (still available)
try:
gw = await self._api.get_gateway(self.location_id)
LOG.debug("Generating gateway device %s", gw)
gw_dev = self.generate_device(gw)
generated_devices.append(gw_dev)
if gw_dev not in self.devices:
self.devices.append(gw_dev)
except Exception as err:
LOG.error("Failed to get gateway: %s", err)

# Now add devices from external sources (e.g. unknown source tracker)
for callback in self._api._get_device_callbacks:
try:
cb_device = callback()
Expand Down
56 changes: 55 additions & 1 deletion pyhilo/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,16 @@ async def call_get_location_query(self, location_hilo_id: str) -> None:
return

if "data" in response_json:
devices = (
response_json["data"].get("getLocation", {}).get("devices", [])
)
gateways = [
d for d in devices if d.get("deviceType") in ("Gateway", "Hub")
]
LOG.debug(
"Gateway devices in getLocation response: %s",
json.dumps(gateways, indent=2),
)
self._handle_query_result(response_json["data"])

async def subscribe_to_device_updated(
Expand Down Expand Up @@ -790,12 +800,55 @@ async def _get_access_token(self) -> str:
return await self._api.async_get_access_token()

def _handle_query_result(self, result: Dict[str, Any]) -> None:
"""This receives query results and maps them to the proper device."""
"""Handle the result of the GraphQL query for location and devices."""
devices_values: List[Dict[str, Any]] = result["getLocation"]["devices"]

for raw_device in devices_values:
if raw_device.get("deviceType") in ("Gateway", "Hub"):
if self._devices.find_device(1) is None:
gw = self._build_gateway_dict(raw_device)
LOG.debug("Creating gateway device from GraphQL: %s", gw)
gw_dev = self._devices.generate_device(gw)
if gw_dev not in self._devices.devices:
self._devices.devices.append(gw_dev)

attributes = self.mapper.map_query_values(devices_values)
self._devices.parse_values_received(attributes)

def _build_gateway_dict(self, raw_device: Dict[str, Any]) -> Dict[str, Any]:
"""Build a dictionary representing the gateway device from raw GraphQL data."""
hilo_id = raw_device.get("hiloId", "")
parts = hilo_id.split(":")
mac = parts[3] if len(parts) > 3 else None
if mac is None:
LOG.warning("Unable to extract MAC from hiloId: %s", hilo_id)

connection_status = raw_device.get("connectionStatus")
return {
"name": "Hilo Gateway",
"type": "Gateway",
"category": "Gateway",
"id": 1,
"identifier": mac,
"sdi": mac,
"provider": 1,
"model_number": "EQ000017",
"sw_version": raw_device.get("controllerSoftwareVersion"),
"supportedAttributes": "zigBeePairingActivated, zigBeeChannel, firmwareVersion, onlineStatus, lastStatusTime, disconnected",
"settableAttributes": "",
"Disconnected": {"value": connection_status != "CONNECTED"},
"zigBeePairingActivated": {
"value": bool(raw_device.get("zigBeePairingModeEnhanced"))
},
"zigBeeChannel": {"value": raw_device.get("zigBeeChannel")},
"firmwareVersion": {"value": raw_device.get("controllerSoftwareVersion")},
"onlineStatus": {"value": connection_status},
"lastStatusTime": {"value": raw_device.get("lastConnectionTime")},
"disconnected": {"value": connection_status != "CONNECTED"},
}

def _handle_device_subscription_result(self, result: Dict[str, Any]) -> str:
"""Handle the result of the GraphQL subscription for device updates."""
device_value: Dict[str, Any] = result["onAnyDeviceUpdated"]["device"]
attributes = self.mapper.map_device_subscription_values(device_value)
updated_device = self._devices.parse_values_received(attributes)
Expand All @@ -804,6 +857,7 @@ def _handle_device_subscription_result(self, result: Dict[str, Any]) -> str:
return str(device_value.get("hiloId"))

def _handle_location_subscription_result(self, result: Dict[str, Any]) -> str:
"""Handle the result of the GraphQL subscription for location updates."""
location_value: Dict[str, Any] = result["onAnyLocationUpdated"]["location"]
attributes = self.mapper.map_location_subscription_values(location_value)
updated_device = self._devices.parse_values_received(attributes)
Expand Down