From 016124859f0e941407b80bbee70241782d8c5390 Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:31:37 -0400 Subject: [PATCH 1/7] Update api.py --- pyhilo/api.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/pyhilo/api.py b/pyhilo/api.py index 958c80d..7728f63 100755 --- a/pyhilo/api.py +++ b/pyhilo/api.py @@ -140,7 +140,7 @@ async def async_get_access_token(self) -> str: await self._oauth_session.async_ensure_token_valid() access_token = str(self._oauth_session.token["access_token"]) - LOG.debug(f"Websocket access token is {access_token}") + LOG.debug("Websocket access token is %s", access_token) return str(self._oauth_session.token["access_token"]) @@ -246,8 +246,9 @@ async def _async_request( data: dict[str, Any] = {} url = parse.urljoin(f"https://{host}", endpoint) if self.log_traces: - LOG.debug(f"[TRACE] Headers: {kwargs['headers']}") - LOG.debug(f"[TRACE] Async request: {method} {url}") + LOG.debug("[TRACE] Headers: %s", kwargs["headers"]) + LOG.debug("[TRACE] Async request: %s %s", method, url) + async with self.session.request(method, url, **kwargs) as resp: if "application/json" in resp.headers.get("content-type", ""): try: @@ -396,7 +397,7 @@ async def get_websocket_params(self) -> None: """Retrieves and constructs WebSocket connection parameters from the negotiation endpoint.""" uri = parse.urlparse(self.ws_url) LOG.debug("Getting websocket params") - LOG.debug(f"Getting uri {uri}") + LOG.debug("Getting uri %s", uri) resp: dict[str, Any] = await self.async_request( "post", f"{uri.path}negotiate?{uri.query}", @@ -407,7 +408,7 @@ async def get_websocket_params(self) -> None: ) conn_id: str = resp.get("connectionId", "") self.full_ws_url = f"{self.ws_url}&id={conn_id}&access_token={self.ws_token}" - LOG.debug(f"Getting full ws URL {self.full_ws_url}") + LOG.debug("Getting full ws URL %s", self.full_ws_url) transport_dict: list[WebsocketTransportsDict] = resp.get( "availableTransports", [] ) @@ -441,7 +442,7 @@ async def fb_install(self, fb_id: str) -> None: if err.status in (401, 403): raise InvalidCredentialsError("Invalid credentials") from err raise RequestError(err) from err - LOG.debug(f"FB Install data: {resp}") + LOG.debug("FB Install data: %s", resp) auth_token = resp.get("authToken", {}) LOG.debug("Calling set_state from fb_install") await set_state( @@ -479,7 +480,7 @@ async def android_register(self) -> None: if err.status in (401, 403): raise InvalidCredentialsError("Invalid credentials") from err raise RequestError(err) from err - LOG.debug(f"Android client register: {resp}") + LOG.debug("Android client register: %s", resp) msg: str = resp.get("message", "") if msg.startswith("Error="): LOG.error(f"Android registration error: {msg}") @@ -497,14 +498,14 @@ async def android_register(self) -> None: async def get_location_ids(self) -> tuple[int, str]: """Gets location id from an API call""" url = f"{API_AUTOMATION_ENDPOINT}/Locations" - LOG.debug(f"LocationId URL is {url}") + LOG.debug("LocationId URL is %s", url) req: list[dict[str, Any]] = await self.async_request("get", url) return (req[0]["id"], req[0]["locationHiloId"]) async def get_devices(self, location_id: int) -> list[dict[str, Any]]: """Get list of all devices""" url = self._get_url("Devices", location_id) - LOG.debug(f"Devices URL is {url}") + LOG.debug("Devices URL is %s", url) devices: list[dict[str, Any]] = await self.async_request("get", url) devices.append(await self.get_gateway(location_id)) # Now it's time to add devices coming from external sources like hass @@ -521,7 +522,7 @@ async def _set_device_attribute( ) -> None: """Sets device attributes""" url = self._get_url(f"Devices/{device.id}/Attributes", device.location_id) - LOG.debug(f"Device Attribute URL is {url}") + LOG.debug("Device Attribute URL is %s", url) await self.async_request("put", url, json={key.hilo_attribute: value}) async def get_event_notifications(self, location_id: int) -> dict[str, Any]: @@ -549,7 +550,7 @@ async def get_event_notifications(self, location_id: int) -> dict[str, Any]: "viewed": false }""" url = self._get_url(None, location_id, events=True) - LOG.debug(f"Event Notifications URL is {url}") + LOG.debug("Event Notifications URL is %s", url) return cast(dict[str, Any], await self.async_request("get", url)) async def get_gd_events( @@ -622,7 +623,7 @@ async def get_gd_events( else: url += f"/{event_id}" - LOG.debug(f"get_gd_events URL is {url}") + LOG.debug("get_gd_events URL is %s", url) return cast(dict[str, Any], await self.async_request("get", url)) async def get_seasons(self, location_id: int) -> dict[str, Any]: @@ -645,13 +646,13 @@ async def get_seasons(self, location_id: int) -> dict[str, Any]: ] """ url = self._get_url("Seasons", location_id, challenge=True) - LOG.debug(f"Seasons URL is {url}") + LOG.debug("Seasons URL is %s", url) return cast(dict[str, Any], await self.async_request("get", url)) 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) - LOG.debug(f"Gateway URL is {url}") + LOG.debug("Gateway URL is %s", url) req = await self.async_request("get", url) saved_attrs = [ "zigBeePairingActivated", @@ -694,7 +695,7 @@ async def get_weather(self, location_id: int) -> dict[str, Any]: ] """ url = self._get_url("Weather", location_id) - LOG.debug(f"Weather URL is {url}") + LOG.debug("Weather URL is %s", url) response = await self.async_request("get", url) - LOG.debug(f"Weather API response: {response}") + LOG.debug("Weather API response: %s", response) return cast(dict[str, Any], await self.async_request("get", url)) From 961825803fe635f4efa9805450748bb1853a132b Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:35:26 -0400 Subject: [PATCH 2/7] Update devices.py --- pyhilo/devices.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyhilo/devices.py b/pyhilo/devices.py index e558646..8ff3c7d 100644 --- a/pyhilo/devices.py +++ b/pyhilo/devices.py @@ -60,7 +60,7 @@ def _map_readings_to_devices( device_identifier = reading.hilo_id if device := self.find_device(device_identifier): device.update_readings(reading) - LOG.debug(f"{device} Received {reading}") + LOG.debug("%s Received %s", device, reading) if device not in updated_devices: updated_devices.append(device) else: @@ -96,14 +96,14 @@ async def update(self) -> None: fresh_devices = await self._api.get_devices(self.location_id) generated_devices = [] for raw_device in fresh_devices: - LOG.debug(f"Generating device {raw_device}") + LOG.debug("Generating device %s", raw_device) dev = self.generate_device(raw_device) generated_devices.append(dev) if dev not in self.devices: self.devices.append(dev) for device in self.devices: if device not in generated_devices: - LOG.debug(f"Device unpaired {device}") + LOG.debug("Device unpaired %s", device) # Don't do anything with unpaired device for now. # self.devices.remove(device) @@ -113,7 +113,7 @@ async def update_devicelist_from_signalr( # ic-dev21 not sure if this is dead code? new_devices = [] for raw_device in values: - LOG.debug(f"Generating device {raw_device}") + LOG.debug("Generating device %s", raw_device) dev = self.generate_device(raw_device) if dev not in self.devices: self.devices.append(dev) From 723d2ca46c56d1c3c1db02d6fea2fef1982774c0 Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:40:39 -0400 Subject: [PATCH 3/7] lazy formatting --- pyhilo/event.py | 2 +- pyhilo/graphql.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pyhilo/event.py b/pyhilo/event.py index 9afa91c..0e7b2e9 100755 --- a/pyhilo/event.py +++ b/pyhilo/event.py @@ -67,7 +67,7 @@ def __init__(self, **event: dict[str, Any]): def update_wh(self, used_wH: float) -> None: """This function is used to update the used_kWh attribute during a Hilo Challenge Event""" - LOG.debug(f"Updating Wh: {used_wH}") + LOG.debug("Updating Wh: %s", used_wH) self.used_kWh = round(used_wH / 1000, 2) self.last_update = datetime.now(timezone.utc).astimezone() diff --git a/pyhilo/graphql.py b/pyhilo/graphql.py index 8a8dace..3cdb37e 100644 --- a/pyhilo/graphql.py +++ b/pyhilo/graphql.py @@ -562,14 +562,16 @@ async def subscribe_to_device_updated( query, variable_values={"locationHiloId": location_hilo_id} ): LOG.debug( - f"subscribe_to_device_updated: Received subscription result {result}" + "subscribe_to_device_updated: Received subscription result %s", + result, ) device_hilo_id = self._handle_device_subscription_result(result) if callback: callback(device_hilo_id) except Exception as e: LOG.debug( - f"subscribe_to_device_updated: Connection lost: {e}. Reconnecting in 5 seconds..." + "subscribe_to_device_updated: Connection lost: %s. Reconnecting in 5 seconds...", + e, ) await asyncio.sleep(5) try: @@ -580,7 +582,8 @@ async def subscribe_to_device_updated( except Exception as e2: LOG.error( - f"subscribe_to_device_updated, exception while reconnecting, retrying: {e2}" + "subscribe_to_device_updated, exception while reconnecting, retrying: %s", + e2, ) async def subscribe_to_location_updated( @@ -597,7 +600,7 @@ async def subscribe_to_location_updated( async for result in session.subscribe( query, variable_values={"locationHiloId": location_hilo_id} ): - LOG.debug(f"Received subscription result {result}") + LOG.debug("Received subscription result %s", result) device_hilo_id = self._handle_location_subscription_result(result) callback(device_hilo_id) except asyncio.CancelledError: @@ -620,7 +623,7 @@ def _handle_device_subscription_result(self, result: Dict[str, Any]) -> str: attributes = self.mapper.map_device_subscription_values(devices_values) updated_device = self._devices.parse_values_received(attributes) # callback to update the device in the UI - LOG.debug(f"Device updated: {updated_device}") + LOG.debug("Device updated: %s", updated_device) return devices_values.get("hiloId") def _handle_location_subscription_result(self, result: Dict[str, Any]) -> str: @@ -628,5 +631,5 @@ def _handle_location_subscription_result(self, result: Dict[str, Any]) -> str: attributes = self.mapper.map_location_subscription_values(devices_values) updated_device = self._devices.parse_values_received(attributes) # callback to update the device in the UI - LOG.debug(f"Device updated: {updated_device}") + LOG.debug("Device updated: %s", updated_device) return devices_values.get("hiloId") From c54168d98ecbdfbcee0ed40451428b19c9fb1085 Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 17:46:34 -0400 Subject: [PATCH 4/7] Update websocket.py --- pyhilo/websocket.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/pyhilo/websocket.py b/pyhilo/websocket.py index 9c6dcfc..7b55cf4 100755 --- a/pyhilo/websocket.py +++ b/pyhilo/websocket.py @@ -214,18 +214,22 @@ async def _async_send_json(self, payload: dict[str, Any]) -> None: if self._api.log_traces: LOG.debug( - f"[TRACE] Sending data to websocket {self._api.endpoint} : {json.dumps(payload)}" + "[TRACE] Sending data to websocket %s : %s", + self._api.endpoint, + json.dumps(payload), ) # Hilo added a control character (chr(30)) at the end of each payload they send. # They also expect this char to be there at the end of every payload we send them. - LOG.debug(f"WebsocketClient _async_send_json payload: {payload}") + LOG.debug("WebsocketClient _async_send_json payload: %s", payload) await self._client.send_str(json.dumps(payload) + chr(30)) def _parse_message(self, msg: dict[str, Any]) -> None: """Parse an incoming message.""" if self._api.log_traces: LOG.debug( - f"[TRACE] Received message on websocket(_parse_message) {self._api.endpoint}: {msg}" + "[TRACE] Received message on websocket(_parse_message) %s: %s", + self._api.endpoint, + msg, ) if msg.get("type") == SignalRMsgType.PING: schedule_callback(self._async_pong) @@ -272,7 +276,7 @@ async def async_connect(self) -> None: LOG.info("Websocket: Connecting to server %s", self._api.endpoint) if self._api.log_traces: - LOG.debug(f"[TRACE] Websocket URL: {self._api.full_ws_url}") + LOG.debug("[TRACE] Websocket URL: %s", self._api.full_ws_url) headers = { "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits", "Pragma": "no-cache", @@ -396,9 +400,13 @@ async def async_invoke( except asyncio.TimeoutError: return self._ready_event.clear() - LOG.debug( - f"async_invoke invoke argument: {arg}, invocationId: {inv_id}, target: {target}, type: {type}" - ) + LOG.debug( + "async_invoke invoke argument: %s, invocationId: %s, target: %s, type: %s", + arg, + inv_id, + target, + type, + ) await self._async_send_json( { "arguments": arg, @@ -481,9 +489,9 @@ async def _negotiate(self, config: WebsocketConfig) -> Tuple[str, str]: Returns: Tuple containing the websocket URL and access token """ - LOG.debug(f"Getting websocket url for {config.endpoint}") + LOG.debug("Getting websocket url for %s", config.endpoint) url = f"{config.endpoint}/negotiate" - LOG.debug(f"Negotiate URL is {url}") + LOG.debug("Negotiate URL is %s", url) resp = await self.async_request("post", url) ws_url = resp.get("url") @@ -513,8 +521,8 @@ async def _get_websocket_params(self, config: WebsocketConfig) -> None: config: The websocket configuration to get parameters for """ uri = parse.urlparse(config.url) - LOG.debug(f"Getting websocket params for {config.endpoint}") - LOG.debug(f"Getting uri {uri}") + LOG.debug("Getting websocket params for %s", config.endpoint) + LOG.debug("Getting uri %s", uri) resp = await self.async_request( "post", @@ -529,7 +537,7 @@ async def _get_websocket_params(self, config: WebsocketConfig) -> None: config.full_ws_url = ( f"{config.url}&id={config.connection_id}&access_token={config.token}" ) - LOG.debug(f"Getting full ws URL {config.full_ws_url}") + LOG.debug("Getting full ws URL %s", config.full_ws_url) transport_dict = resp.get("availableTransports", []) websocket_dict = { @@ -544,5 +552,5 @@ async def _get_websocket_params(self, config: WebsocketConfig) -> None: if config.endpoint == AUTOMATION_DEVICEHUB_ENDPOINT else "websocketChallenges" ) - LOG.debug(f"Calling set_state {state_key}_params") + LOG.debug("Calling set_state %s_params", state_key) await self._set_state(self._state_yaml, state_key, websocket_dict) From bd082fe70e2f300549b30f6cf8ca9d18a6e4d33e Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 19:34:42 -0400 Subject: [PATCH 5/7] Update light.py --- pyhilo/device/light.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhilo/device/light.py b/pyhilo/device/light.py index c74cd03..eb0b95b 100644 --- a/pyhilo/device/light.py +++ b/pyhilo/device/light.py @@ -10,7 +10,7 @@ class Light(HiloDevice): def __init__(self, api: API, **kwargs: dict[str, Union[str, int]]): super().__init__(api, **kwargs) # type: ignore - LOG.debug(f"Setting up Light device: {self.name}") + LOG.debug("Setting up Light device: %s", self.name) @property def brightness(self) -> float: From 32b96e1c55322ef1d6c6f6f41c1590948aa92099 Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 19:35:11 -0400 Subject: [PATCH 6/7] Update sensor.py --- pyhilo/device/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhilo/device/sensor.py b/pyhilo/device/sensor.py index e396c03..42320b4 100644 --- a/pyhilo/device/sensor.py +++ b/pyhilo/device/sensor.py @@ -10,7 +10,7 @@ class Sensor(HiloDevice): def __init__(self, api: API, **kwargs: dict[str, Union[str, int]]): super().__init__(api, **kwargs) # type: ignore - LOG.debug(f"Setting up Sensor device: {self.name}") + LOG.debug("Setting up Sensor device: %s", self.name) @property def state(self) -> str: From 03ec09ca02ce48f4808fdee2d7456d2e9ede36ec Mon Sep 17 00:00:00 2001 From: "Ian C." <108159253+ic-dev21@users.noreply.github.com> Date: Sun, 7 Sep 2025 19:35:31 -0400 Subject: [PATCH 7/7] Update switch.py --- pyhilo/device/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyhilo/device/switch.py b/pyhilo/device/switch.py index 0732ba3..9f74076 100644 --- a/pyhilo/device/switch.py +++ b/pyhilo/device/switch.py @@ -10,7 +10,7 @@ class Switch(HiloDevice): def __init__(self, api: API, **kwargs: dict[str, Union[str, int]]): super().__init__(api, **kwargs) # type: ignore - LOG.debug(f"Setting up Switch device: {self.name}") + LOG.debug("Setting up Switch device: %s", self.name) @property def state(self) -> str: