Browse Source

fix: return None when there is no response instead of an empty byte so we can give a better error (#90)

J. Nick Koston 1 year ago
parent
commit
5f25d59572

+ 3 - 3
switchbot/devices/bulb.py

@@ -25,8 +25,8 @@ CW_KEY = f"{BULB_COMMAND}17"
 
 _LOGGER = logging.getLogger(__name__)
 
-from .device import ColorMode
 from .base_light import SwitchbotBaseLight
+from .device import ColorMode
 
 
 class SwitchbotBulb(SwitchbotBaseLight):
@@ -88,9 +88,9 @@ class SwitchbotBulb(SwitchbotBaseLight):
         self._update_state(result)
         return self._check_command_result(result, 1, {0x80})
 
-    def _update_state(self, result: bytes) -> None:
+    def _update_state(self, result: bytes | None) -> None:
         """Update device state."""
-        if len(result) < 10:
+        if not result or len(result) < 10:
             return
         self._state["r"] = result[3]
         self._state["g"] = result[4]

+ 7 - 0
switchbot/devices/curtain.py

@@ -97,6 +97,10 @@ class SwitchbotCurtain(SwitchbotDevice):
         """Get basic info for all devices in chain."""
         _data = await self._sendcommand(key=CURTAIN_EXT_SUM_KEY)
 
+        if not _data:
+            _LOGGER.error("%s: Unsuccessful, no result from device", self.name)
+            return None
+
         if _data in (b"\x07", b"\x00"):
             _LOGGER.error("%s: Unsuccessful, please try again", self.name)
             return None
@@ -127,6 +131,9 @@ class SwitchbotCurtain(SwitchbotDevice):
         """Get advance page info for device chain."""
 
         _data = await self._sendcommand(key=CURTAIN_EXT_ADV_KEY)
+        if not _data:
+            _LOGGER.error("%s: Unsuccessful, no result from device", self.name)
+            return None
 
         if _data in (b"\x07", b"\x00"):
             _LOGGER.error("%s: Unsuccessful, please try again", self.name)

+ 6 - 6
switchbot/devices/device.py

@@ -114,7 +114,7 @@ class SwitchbotDevice:
         key_suffix = key[4:]
         return KEY_PASSWORD_PREFIX + key_action + self._password_encoded + key_suffix
 
-    async def _sendcommand(self, key: str, retry: int | None = None) -> bytes:
+    async def _sendcommand(self, key: str, retry: int | None = None) -> bytes | None:
         """Send command to device and read response."""
         if retry is None:
             retry = self._retry_count
@@ -145,7 +145,7 @@ class SwitchbotDevice:
                         self.rssi,
                         exc_info=True,
                     )
-                    return b"\x00"
+                    return None
                 except CharacteristicMissingError as ex:
                     if attempt == retry:
                         _LOGGER.error(
@@ -155,7 +155,7 @@ class SwitchbotDevice:
                             self.rssi,
                             exc_info=True,
                         )
-                        return b"\x00"
+                        return None
 
                     _LOGGER.debug(
                         "%s: characteristic missing: %s; RSSI: %s",
@@ -172,7 +172,7 @@ class SwitchbotDevice:
                             self.rssi,
                             exc_info=True,
                         )
-                        return b"\x00"
+                        return None
 
                     _LOGGER.debug(
                         "%s: communication failed with:", self.name, exc_info=True
@@ -411,10 +411,10 @@ class SwitchbotDevice:
         """Update state of device."""
 
     def _check_command_result(
-        self, result: bytes, index: int, values: set[int]
+        self, result: bytes | None, index: int, values: set[int]
     ) -> bool:
         """Check command result."""
-        if not result:
+        if not result or len(result) - 1 < index:
             raise SwitchbotOperationError(
                 f"{self.name}: Sending command failed (rssi={self.rssi})"
             )

+ 2 - 2
switchbot/devices/light_strip.py

@@ -74,9 +74,9 @@ class SwitchbotLightStrip(SwitchbotBaseLight):
         self._update_state(result)
         return self._check_command_result(result, 1, {0x80})
 
-    def _update_state(self, result: bytes) -> None:
+    def _update_state(self, result: bytes | None) -> None:
         """Update device state."""
-        if len(result) < 10:
+        if not result or len(result) < 10:
             return
         self._state["r"] = result[3]
         self._state["g"] = result[4]