From f35336bd513916e17f432022e05dad3886476e83 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 24 May 2025 10:23:37 +0200 Subject: [PATCH 1/3] Switch: remove unused self --- plugwise_usb/nodes/switch.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugwise_usb/nodes/switch.py b/plugwise_usb/nodes/switch.py index d20b97ab6..1a2fed77e 100644 --- a/plugwise_usb/nodes/switch.py +++ b/plugwise_usb/nodes/switch.py @@ -40,7 +40,6 @@ def __init__( super().__init__(mac, address, controller, loaded_callback) self._switch_subscription: Callable[[], None] | None = None self._switch_state: bool | None = None - self._switch: bool = False async def load(self) -> bool: """Load and activate Switch node features.""" @@ -124,7 +123,6 @@ async def _switch_state_update( self._set_cache(CACHE_SWITCH_TIMESTAMP, timestamp) if state_update: - self._switch = switch_state await gather( *[ self.publish_feature_update_to_subscribers( From 94d8774597197a02226baafe9f6b23d739e6f6c9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 24 May 2025 10:27:19 +0200 Subject: [PATCH 2/3] Pulses: fix wrong logic --- plugwise_usb/nodes/helpers/pulses.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugwise_usb/nodes/helpers/pulses.py b/plugwise_usb/nodes/helpers/pulses.py index ef539c3ae..3ad85b31b 100644 --- a/plugwise_usb/nodes/helpers/pulses.py +++ b/plugwise_usb/nodes/helpers/pulses.py @@ -905,18 +905,22 @@ def _last_known_duration(self) -> timedelta: """Duration for last known logs.""" if self._logs is None: raise EnergyError("Unable to return last known duration without any logs") + if len(self._logs) < 2: return timedelta(hours=1) + address, slot = self._last_log_reference() if address is None or slot is None: raise EnergyError("Unable to return last known duration without any logs") + last_known_timestamp = self._logs[address][slot].timestamp address, slot = calc_log_address(address, slot, -1) while ( self._log_exists(address, slot) - or self._logs[address][slot].timestamp == last_known_timestamp + and self._logs[address][slot].timestamp == last_known_timestamp ): address, slot = calc_log_address(address, slot, -1) + return self._logs[address][slot].timestamp - last_known_timestamp def _missing_addresses_before( From 17274430761ea0571c7d60f820e559df4b0d52d4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 24 May 2025 10:30:26 +0200 Subject: [PATCH 3/3] Sed: remove unneeded code, implement suggested lock-fixes --- plugwise_usb/nodes/sed.py | 58 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/plugwise_usb/nodes/sed.py b/plugwise_usb/nodes/sed.py index 50ee5facb..66ff9eaca 100644 --- a/plugwise_usb/nodes/sed.py +++ b/plugwise_usb/nodes/sed.py @@ -236,11 +236,10 @@ async def set_awake_duration(self, seconds: int) -> bool: raise ValueError( f"Invalid awake duration ({seconds}). It must be between 1 and 255 seconds." ) + if self._battery_config.awake_duration == seconds: - self._new_battery_config = replace( - self._new_battery_config, awake_duration=seconds - ) - return False + return False + self._new_battery_config = replace( self._new_battery_config, awake_duration=seconds ) @@ -251,6 +250,7 @@ async def set_awake_duration(self, seconds: int) -> bool: "set_awake_duration | Device %s | config scheduled", self.name, ) + return True @raise_not_loaded @@ -266,11 +266,10 @@ async def set_clock_interval(self, minutes: int) -> bool: raise ValueError( f"Invalid clock interval ({minutes}). It must be between 1 and 65535 minutes." ) + if self.battery_config.clock_interval == minutes: - self._new_battery_config = replace( - self._new_battery_config, clock_interval=minutes - ) return False + self._new_battery_config = replace( self._new_battery_config, clock_interval=minutes ) @@ -281,6 +280,7 @@ async def set_clock_interval(self, minutes: int) -> bool: "set_clock_interval | Device %s | config scheduled", self.name, ) + return True @raise_not_loaded @@ -293,10 +293,8 @@ async def set_clock_sync(self, sync: bool) -> bool: sync, ) if self._battery_config.clock_sync == sync: - self._new_battery_config = replace( - self._new_battery_config, clock_sync=sync - ) return False + self._new_battery_config = replace(self._new_battery_config, clock_sync=sync) if not self._sed_config_task_scheduled: await self.schedule_task_when_awake(self._configure_sed_task()) @@ -305,6 +303,7 @@ async def set_clock_sync(self, sync: bool) -> bool: "set_clock_sync | Device %s | config scheduled", self.name, ) + return True @raise_not_loaded @@ -320,11 +319,10 @@ async def set_maintenance_interval(self, minutes: int) -> bool: raise ValueError( f"Invalid maintenance interval ({minutes}). It must be between 1 and 1440 minutes." ) + if self.battery_config.maintenance_interval == minutes: - self._new_battery_config = replace( - self._new_battery_config, maintenance_interval=minutes - ) return False + self._new_battery_config = replace( self._new_battery_config, maintenance_interval=minutes ) @@ -335,6 +333,7 @@ async def set_maintenance_interval(self, minutes: int) -> bool: "set_maintenance_interval | Device %s | config scheduled", self.name, ) + return True @raise_not_loaded @@ -353,11 +352,10 @@ async def set_sleep_duration(self, minutes: int) -> bool: raise ValueError( f"Invalid sleep duration ({minutes}). It must be between 1 and 65535 minutes." ) + if self._battery_config.sleep_duration == minutes: - self._new_battery_config = replace( - self._new_battery_config, sleep_duration=minutes - ) return False + self._new_battery_config = replace( self._new_battery_config, sleep_duration=minutes ) @@ -368,6 +366,7 @@ async def set_sleep_duration(self, minutes: int) -> bool: "set_sleep_duration | Device %s | config scheduled", self.name, ) + return True # endregion @@ -639,25 +638,24 @@ async def _send_tasks(self) -> None: """Send all tasks in queue.""" if len(self._send_task_queue) == 0: return - await self._send_task_lock.acquire() - task_result = await gather(*self._send_task_queue) - if not all(task_result): - _LOGGER.warning( - "Executed %s tasks (result=%s) for %s", - len(self._send_task_queue), - task_result, - self.name, - ) - self._send_task_queue = [] - self._send_task_lock.release() + + async with self._send_task_lock: + task_result = await gather(*self._send_task_queue) + if not all(task_result): + _LOGGER.warning( + "Executed %s tasks (result=%s) for %s", + len(self._send_task_queue), + task_result, + self.name, + ) + self._send_task_queue = [] async def schedule_task_when_awake( self, task_fn: Coroutine[Any, Any, bool] ) -> None: """Add task to queue to be executed when node is awake.""" - await self._send_task_lock.acquire() - self._send_task_queue.append(task_fn) - self._send_task_lock.release() + async with self._send_task_lock: + self._send_task_queue.append(task_fn) async def sed_configure( # pylint: disable=too-many-arguments self,