diff --git a/CHANGELOG.md b/CHANGELOG.md index 6093479c7..90190a3a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Ongoing + +- PR [319](https://github.com/plugwise/python-plugwise-usb/pull/319): Replace unclear warning message when a node is not online, also various small improvements suggested by CRAI. + ## v0.44.11 - 2025-08-14 - Improve reading from energy-logs cache via PR [314](https://github.com/plugwise/python-plugwise-usb/pull/314) diff --git a/plugwise_usb/connection/queue.py b/plugwise_usb/connection/queue.py index a74d8d430..8e0a4b9cb 100644 --- a/plugwise_usb/connection/queue.py +++ b/plugwise_usb/connection/queue.py @@ -85,12 +85,14 @@ async def submit(self, request: PlugwiseRequest) -> PlugwiseResponse | None: f"Cannot send message {request} which is currently waiting for response." ) - while request.resend: + while True: + if not request.resend: + break _LOGGER.debug("submit | start (%s) %s", request.retries_left, request) if not self._running or self._stick is None: raise StickError( - f"Cannot send message {request.__class__.__name__} for" - + f"{request.mac_decoded} because queue manager is stopped" + f"Cannot send message {request.__class__.__name__} for " + f"{request.mac_decoded} because queue manager is stopped" ) await self._add_request_to_queue(request) @@ -107,20 +109,22 @@ async def submit(self, request: PlugwiseRequest) -> PlugwiseResponse | None: "%s, cancel because timeout is expected for NodePingRequests", exc, ) - elif request.resend: + continue + if request.resend: _LOGGER.debug("%s, retrying", exc) - else: - _LOGGER.warning("%s, cancel request", exc) # type: ignore[unreachable] + continue + _LOGGER.debug("%s, cancel request", exc) + break except StickError as exc: _LOGGER.error(exc) raise StickError( f"No response received for {request.__class__.__name__} " - + f"to {request.mac_decoded}" + f"to {request.mac_decoded}" ) from exc except BaseException as exc: raise StickError( f"No response received for {request.__class__.__name__} " - + f"to {request.mac_decoded}" + f"to {request.mac_decoded}" ) from exc return None diff --git a/plugwise_usb/connection/sender.py b/plugwise_usb/connection/sender.py index 36030f13e..c4df44688 100644 --- a/plugwise_usb/connection/sender.py +++ b/plugwise_usb/connection/sender.py @@ -147,7 +147,6 @@ async def write_request_to_port(self, request: PlugwiseRequest) -> None: async def _process_stick_response(self, response: StickResponse) -> None: """Process stick response.""" if self._stick_response is None or self._stick_response.done(): - _LOGGER.warning("No open request for %s", str(response)) return _LOGGER.debug("Received %s as reply to %s", response, self._current_request) self._stick_response.set_result(response) diff --git a/plugwise_usb/messages/requests.py b/plugwise_usb/messages/requests.py index bbaf00145..39e07a46b 100644 --- a/plugwise_usb/messages/requests.py +++ b/plugwise_usb/messages/requests.py @@ -1,4 +1,4 @@ -"""All known request messages to be send to plugwise devices.""" +"""All known request messages to be sent to plugwise devices.""" from __future__ import annotations @@ -58,7 +58,7 @@ class PlugwiseRequest(PlugwiseMessage): - """Base class for request messages to be send from by USB-Stick.""" + """Base class for request messages to be sent from by USB-Stick.""" _reply_identifier: bytes = b"0000" @@ -215,7 +215,7 @@ def _response_timeout_expired(self, stick_timeout: bool = False) -> None: if self._response_future.done(): return if stick_timeout: - _LOGGER.info("USB-stick responded with time out to %s", self) + _LOGGER.info("USB-stick response timeout for %s", self) else: _LOGGER.info( "No response received for %s within %s seconds", self, NODE_TIME_OUT @@ -225,12 +225,12 @@ def _response_timeout_expired(self, stick_timeout: bool = False) -> None: self._unsubscribe_from_node() if stick_timeout: self._response_future.set_exception( - StickTimeout(f"USB-stick responded with time out to {self}") + StickTimeout(f"USB-stick response timeout for {self}") ) else: self._response_future.set_exception( NodeTimeout( - f"No device response to {self} within {NODE_TIME_OUT} seconds" + f"No device response for {self} within {NODE_TIME_OUT} seconds" ) ) @@ -249,16 +249,17 @@ async def process_node_response(self, response: PlugwiseResponse) -> bool: if self._seq_id is None: _LOGGER.warning( "Received %s as reply to %s without a seq_id assigned", - self._response, + response, self, ) return False if self._seq_id != response.seq_id: _LOGGER.warning( - "Received %s as reply to %s which is not correct (expected seq_id=%s)", - self._response, + "Received %s as reply to %s with mismatched seq_id (expected=%r, got=%r)", + response, self, - str(self.seq_id), + self.seq_id, + response.seq_id, ) return False if self._response_future.done(): @@ -297,19 +298,9 @@ async def _process_stick_response(self, stick_response: StickResponse) -> None: return if stick_response.ack_id == StickResponseType.FAILED: - self._unsubscribe_from_node() + prev_seq_id = self._seq_id self._seq_id = None - self._response_future.set_exception( - NodeError(f"Stick failed request {self._seq_id}") - ) - return - - _LOGGER.debug( - "Unknown StickResponseType %s at %s for request %s", - str(stick_response.ack_id), - stick_response, - self, - ) + self.assign_error(NodeError(f"Stick failed request {prev_seq_id!r}")) async def _send_request( self, suppress_node_errors=False diff --git a/plugwise_usb/network/__init__.py b/plugwise_usb/network/__init__.py index e71ce2d81..8272747b7 100644 --- a/plugwise_usb/network/__init__.py +++ b/plugwise_usb/network/__init__.py @@ -297,6 +297,12 @@ def _unsubscribe_to_protocol_events(self) -> None: if self._unsubscribe_node_awake is not None: self._unsubscribe_node_awake() self._unsubscribe_node_awake = None + if self._unsubscribe_node_join is not None: + self._unsubscribe_node_join() + self._unsubscribe_node_join = None + if self._unsubscribe_node_rejoin is not None: + self._unsubscribe_node_rejoin() + self._unsubscribe_node_rejoin = None if self._unsubscribe_stick_event is not None: self._unsubscribe_stick_event() self._unsubscribe_stick_event = None @@ -322,10 +328,9 @@ async def discover_network_coordinator(self, load: bool = False) -> bool: ping_response = await ping_request.send() except StickTimeout as err: raise StickError( - "The zigbee network coordinator (Circle+/Stealth+) with mac " - + "'%s' did not respond to ping request. Make " - + "sure the Circle+/Stealth+ is within reach of the USB-stick !", - self._controller.mac_coordinator, + f"The zigbee network coordinator (Circle+/Stealth+) with mac " + f"'{self._controller.mac_coordinator}' did not respond to the ping request. " + "Make sure the Circle+/Stealth+ is within reach of the USB-stick!" ) from err if ping_response is None: return False @@ -418,7 +423,9 @@ async def _discover_node( _LOGGER.debug("Starting the discovery of node %s with unknown NodeType", mac) node_info, node_ping = await self._controller.get_node_details(mac, ping_first) if node_info is None: - _LOGGER.debug("Node %s with unknown NodeType not responding", mac) + _LOGGER.warning( + "Node %s with unknown NodeType not responding, is it offline?", mac + ) self._registry_stragglers.append(mac) return False await self._create_node_object(mac, node_info.node_type) diff --git a/plugwise_usb/nodes/circle.py b/plugwise_usb/nodes/circle.py index 8e644a26b..3c548e449 100644 --- a/plugwise_usb/nodes/circle.py +++ b/plugwise_usb/nodes/circle.py @@ -973,7 +973,7 @@ async def _load_from_cache(self) -> bool: # Energy collection if not await self._energy_log_records_load_from_cache(): - _LOGGER.warning( + _LOGGER.debug( "Node %s failed to load energy_log_records from cache", self._mac_in_str, ) diff --git a/pyproject.toml b/pyproject.toml index 747abaebf..6b79f94dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise_usb" -version = "0.44.11" +version = "0.44.12a1" license = "MIT" keywords = ["home", "automation", "plugwise", "module", "usb"] classifiers = [