Browse Source

Additional refactoring to make it easier to add new devices (#62)

J. Nick Koston 1 year ago
parent
commit
31a2686133
4 changed files with 54 additions and 10 deletions
  1. 4 1
      switchbot/__init__.py
  2. 14 9
      switchbot/adv_parser.py
  3. 13 0
      switchbot/const.py
  4. 23 0
      switchbot/enum.py

+ 4 - 1
switchbot/__init__.py

@@ -1,7 +1,8 @@
 """Library to handle connection with Switchbot."""
 from __future__ import annotations
 
-from .adv_parser import parse_advertisement_data
+from .adv_parser import SwitchbotSupportedType, parse_advertisement_data
+from .const import SwitchbotModel
 from .devices.bot import Switchbot
 from .devices.curtain import SwitchbotCurtain
 from .devices.device import SwitchbotDevice
@@ -17,4 +18,6 @@ __all__ = [
     "SwitchbotCurtain",
     "Switchbot",
     "SwitchbotPlugMini",
+    "SwitchbotSupportedType",
+    "SwitchbotModel",
 ]

+ 14 - 9
switchbot/adv_parser.py

@@ -14,51 +14,56 @@ from .adv_parsers.curtain import process_wocurtain
 from .adv_parsers.meter import process_wosensorth
 from .adv_parsers.motion import process_wopresence
 from .adv_parsers.plug import process_woplugmini
+from .const import SwitchbotModel
 from .models import SwitchBotAdvertisement
 
 
 class SwitchbotSupportedType(TypedDict):
     """Supported type of Switchbot."""
 
-    modelName: str
+    modelName: SwitchbotModel
     modelFriendlyName: str
     func: Callable[[bytes, bytes | None], dict[str, bool | int]]
 
 
 SUPPORTED_TYPES: dict[str, SwitchbotSupportedType] = {
     "d": {
-        "modelName": "WoContact",
+        "modelName": SwitchbotModel.CONTACT_SENSOR,
         "modelFriendlyName": "Contact Sensor",
         "func": process_wocontact,
     },
-    "H": {"modelName": "WoHand", "modelFriendlyName": "Bot", "func": process_wohand},
+    "H": {
+        "modelName": SwitchbotModel.BOT,
+        "modelFriendlyName": "Bot",
+        "func": process_wohand,
+    },
     "s": {
-        "modelName": "WoPresence",
+        "modelName": SwitchbotModel.MOTION_SENSOR,
         "modelFriendlyName": "Motion Sensor",
         "func": process_wopresence,
     },
     "c": {
-        "modelName": "WoCurtain",
+        "modelName": SwitchbotModel.CURTAIN,
         "modelFriendlyName": "Curtain",
         "func": process_wocurtain,
     },
     "T": {
-        "modelName": "WoSensorTH",
+        "modelName": SwitchbotModel.METER,
         "modelFriendlyName": "Meter",
         "func": process_wosensorth,
     },
     "i": {
-        "modelName": "WoSensorTH",
+        "modelName": SwitchbotModel.METER,
         "modelFriendlyName": "Meter Plus",
         "func": process_wosensorth,
     },
     "g": {
-        "modelName": "WoPlug",
+        "modelName": SwitchbotModel.PLUG_MINI,
         "modelFriendlyName": "Plug Mini",
         "func": process_woplugmini,
     },
     "u": {
-        "modelName": "WoBulb",
+        "modelName": SwitchbotModel.COLOR_BULB,
         "modelFriendlyName": "Color Bulb",
         "func": process_color_bulb,
     },

+ 13 - 0
switchbot/const.py

@@ -4,3 +4,16 @@ from __future__ import annotations
 DEFAULT_RETRY_COUNT = 3
 DEFAULT_RETRY_TIMEOUT = 1
 DEFAULT_SCAN_TIMEOUT = 5
+
+from .enum import StrEnum
+
+
+class SwitchbotModel(StrEnum):
+
+    BOT = "WoHand"
+    CURTAIN = "WoCurtain"
+    PLUG_MINI = "WoPlug"
+    CONTACT_SENSOR = "WoContact"
+    METER = "WoSensorTH"
+    MOTION_SENSOR = "WoPresence"
+    COLOR_BULB = "WoBulb"

+ 23 - 0
switchbot/enum.py

@@ -0,0 +1,23 @@
+"""Enum backports from standard lib."""
+from __future__ import annotations
+
+from enum import Enum
+from typing import Any, TypeVar
+
+_StrEnumT = TypeVar("_StrEnumT", bound="StrEnum")
+
+
+class StrEnum(str, Enum):
+    """Partial backport of Python 3.11's StrEnum for our basic use cases."""
+
+    def __new__(
+        cls: type[_StrEnumT], value: str, *args: Any, **kwargs: Any
+    ) -> _StrEnumT:
+        """Create a new StrEnum instance."""
+        if not isinstance(value, str):
+            raise TypeError(f"{value!r} is not a string")
+        return super().__new__(cls, value, *args, **kwargs)
+
+    def __str__(self) -> str:
+        """Return self.value."""
+        return str(self.value)