Browse Source

fix: ensure lock state is reflected when operated manually while connected (#173)

J. Nick Koston 1 year ago
parent
commit
a34072f388
2 changed files with 18 additions and 19 deletions
  1. 11 6
      switchbot/devices/device.py
  2. 7 13
      switchbot/devices/lock.py

+ 11 - 6
switchbot/devices/device.py

@@ -552,15 +552,20 @@ class SwitchbotBaseDevice:
             )
         return result[index] in values
 
-    def _update_parsed_data(self, new_data: dict[str, Any]) -> None:
-        """Update data."""
+    def _update_parsed_data(self, new_data: dict[str, Any]) -> bool:
+        """Update data.
+
+        Returns true if data has changed and False if not.
+        """
         if not self._sb_adv_data:
             _LOGGER.exception("No advertisement data to update")
             return
-        self._set_parsed_data(
-            self._sb_adv_data,
-            _merge_data(self._sb_adv_data.data.get("data") or {}, new_data),
-        )
+        old_data = self._sb_adv_data.data.get("data") or {}
+        merged_data = _merge_data(old_data, new_data)
+        if merged_data == old_data:
+            return False
+        self._set_parsed_data(self._sb_adv_data, merged_data)
+        return True
 
     def _set_parsed_data(
         self, advertisement: SwitchBotAdvertisement, data: dict[str, Any]

+ 7 - 13
switchbot/devices/lock.py

@@ -235,19 +235,13 @@ class SwitchbotLock(SwitchbotDevice):
             super()._notification_handler(_sender, data)
 
     def _update_lock_status(self, data: bytearray) -> None:
-        data = self._decrypt(data[4:])
-        lock_data = self._parse_lock_data(data)
-        current_status = self.get_lock_status()
-        if (
-            lock_data["status"] != current_status or current_status not in REST_STATUSES
-        ) and (
-            lock_data["status"] in REST_STATUSES
-            or lock_data["status"] in BLOCKED_STATUSES
-        ):
-            asyncio.create_task(self._disable_notifications())
-
-        self._update_parsed_data(lock_data)
-        self._fire_callbacks()
+        lock_data = self._parse_lock_data(self._decrypt(data[4:]))
+        if self._update_parsed_data(lock_data):
+            # We leave notifications enabled in case
+            # the lock is operated manually before we
+            # disconnect.
+            self._reset_disconnect_timer()
+            self._fire_callbacks()
 
     @staticmethod
     def _parse_lock_data(data: bytes) -> dict[str, Any]: