From 6d513a118db0649fc2fec158c44fd71516a771f8 Mon Sep 17 00:00:00 2001 From: XiaoLing-git Date: Wed, 25 Jun 2025 11:24:56 +0800 Subject: [PATCH 1/5] adjust file struct --- switchbot_api/__init__.py | 297 +++++------------------------- switchbot_api/commands.py | 370 ++++++++++++++++++++++++++++++++++++++ switchbot_api/models.py | 42 +++++ 3 files changed, 452 insertions(+), 257 deletions(-) create mode 100644 switchbot_api/commands.py create mode 100644 switchbot_api/models.py diff --git a/switchbot_api/__init__.py b/switchbot_api/__init__.py index 75d6f1a..8322d3c 100644 --- a/switchbot_api/__init__.py +++ b/switchbot_api/__init__.py @@ -4,13 +4,12 @@ import base64 from dataclasses import dataclass -from enum import Enum, StrEnum import hashlib import hmac import logging import socket import time -from typing import Any, Self, TypeVar +from typing import Any, Self import uuid from aiohttp import ClientError, ClientResponseError, ClientSession @@ -22,6 +21,45 @@ SwitchBotDeviceOfflineError, ) +from switchbot_api.commands import ( + Commands, + CommonCommands, + OthersCommands, + AirConditionerCommands, + HumidifierCommands, + HumidifierV2Commands, + AirPurifierCommands, + CurtainCommands, + SwitchCommands, + Switch2PMCommands, + RGBWLightCommands, + RGBWWLightCommands, + DoorBellCommands, + VacuumCleanerV2Commands, + VacuumCleanerV3Commands, + BlindTiltCommands, + RollerShadeCommands, + TVCommands, + DVDCommands, + SpeakerCommands, + FanCommands, + BatteryCirculatorFanCommands, + LightCommands, + LockCommands, + CeilingLightCommands, + VacuumCommands, + BotCommands, + T, +) + +from switchbot_api.models import ( + PowerState, + BatteryCirculatorFanMode, + VacuumFanSpeed, +VacuumFanSpeedV2, + VacuumCleanMode, +) + _API_HOST = "https://api.switch-bot.com" _LOGGER = logging.getLogger(__name__) @@ -66,261 +104,6 @@ def __init__(self, **kwargs: Any) -> None: self.hub_device_id = kwargs["hubDeviceId"] -class PowerState(Enum): - """Power state.""" - - ON = "on" - OFF = "off" - - -class Commands(Enum): - """Base command class.""" - - -class CommonCommands(Commands): - """Common commands.""" - - ON = "turnOn" - OFF = "turnOff" - TOGGLE = "toggle" - - -class OthersCommands(Commands): - """Others commands.""" - - CUSTOMIZE = "customize" # Command {user-defined button name} - - -class AirConditionerCommands(Commands): - """Air conditioner commands.""" - - SET_ALL = "setAll" # parameter: {temperature},{mode},{fan speed},{power state} - - -class HumidifierCommands(Commands): - """Humidifier commands.""" - - # parameter: auto, set to Auto Mode - # 101, set atomization efficiency to 34% - # 102, set atomization efficiency to 67% - # 103, set atomization efficiency to 100% - SET_MODE = "setMode" - - -class HumidifierV2Commands(Commands): - """Humidifier 2 commands.""" - - SET_MODE = "setMode" - SET_CHILD_LOCK = "setChildLock" - - -class AirPurifierCommands(Commands): - """Purifier commands.""" - - # Supported Device List: - # Air Purifier VOC - # Air Purifier Table VOC - # Air Purifier PM2.5 - # Air Purifier Table PM2.5 - - SET_MODE = "setMode" - SET_CHILD_LOCK = "setChildLock" - - -class CurtainCommands(Commands): - """Curtain & Curtain3 commands.""" - - SET_POSITION = "setPosition" - PAUSE = "pause" - - -class SwitchCommands(Commands): - """Switch commands.""" - - # Supported Device List: - # Relay Switch 1 - # Relay Switch 1PM - SET_MODE = "setMode" - - -class Switch2PMCommands(Commands): - """Switch commands.""" - - # Supported Device List: - # Relay Switch 2PM - SET_MODE = "setMode" - SET_POSITION = "setPosition" - - -class RGBWLightCommands(Commands): - """RGBWLight commands.""" - - # Supported Device List: - # Strip Light - SET_BRIGHTNESS = "setBrightness" - SET_COLOR = "setColor" - - -class RGBWWLightCommands(Commands): - """RGBWwLight commands.""" - - # Supported Device List: - # Floor Lamp - # Strip Light 3 - # Color Bulb - SET_BRIGHTNESS = "setBrightness" - SET_COLOR = "setColor" - SET_COLOR_TEMPERATURE = "setColorTemperature" - - -class DoorBellCommands(Commands): - """Door Bell commands.""" - - ENABLE = "enableMotionDetection" - DISABLE = "disableMotionDetection" - - -class VacuumCleanerV2Commands(Commands): - """VacuumCleanerV2 commands.""" - - # Supported Device List: - # K20+ Pro - # Robot Vacuum Cleaner K10+ Pro Combo - START_CLEAN = "startClean" - PAUSE = "pause" - DOCK = "dock" - SET_VOLUME = "setVolume" - CHANGE_PARAM = "changeParam" - - -class VacuumCleanerV3Commands(Commands): - """VacuumCleanerV3 commands.""" - - # Supported Device List: - # Floor Cleaning Robot S10 - # S20 - START_CLEAN = "startClean" - PAUSE = "pause" - DOCK = "dock" - SET_VOLUME = "setVolume" - CHANGE_PARAM = "changeParam" - ADD_WATER_FOR_HUMI = "addWaterForHumi" - SELF_CLEAN = "selfClean" - - -class BlindTiltCommands(Commands): - """Blind Tilt commands.""" - - SET_POSITION = "setPosition" - FULLY_OPEN = "fullyOpen" - CLOSE_UP = "closeUp" - CLOSE_DOWN = "closeDown" - - -class RollerShadeCommands(Commands): - """Roller Shade commands.""" - - SET_POSITION = "setPosition" - - -class TVCommands(Commands): - """TV commands.""" - - SET_CHANNEL = "SetChannel" - VOLUME_ADD = "volumeAdd" - VOLUME_SUB = "volumeSub" - CHANNEL_ADD = "channelAdd" - CHANNEL_SUB = "channelSub" - - -class DVDCommands(Commands): - """DVD commands.""" - - SET_MUTE = "setMute" - FAST_FORWARD = "FastForward" - REWIND = "Rewind" - NEXT = "Next" - PREVIOUS = "Previous" - PAUSE = "Pause" - PLAY = "Play" - STOP = "Stop" - - -class SpeakerCommands(Commands): - """Speaker commands.""" - - VOLUME_ADD = "volumeAdd" - VOLUME_SUB = "volumeSub" - - -class FanCommands(Commands): - """Fan commands.""" - - SWING = "swing" - TIMER = "timer" - LOW_SPEED = "lowSpeed" - MIDDLE_SPEED = "middleSpeed" - HIGH_SPEED = "highSpeed" - - -class BatteryCirculatorFanCommands(Commands): - """Command types for [Battery Circulator Fan] API.""" - - SET_WIND_SPEED = "setWindSpeed" - SET_WIND_MODE = "setWindMode" - SET_NIGHT_LIGHT_MODE = "setNightLightMode" - - -class LightCommands(Commands): - """Light commands.""" - - BRIGHTNESS_UP = "brightnessUp" - BRIGHTNESS_DOWN = "brightnessDown" - - -class LockCommands(Commands): - """Lock commands.""" - - LOCK = "lock" - UNLOCK = "unlock" - - -class CeilingLightCommands(Commands): - """Ceiling light commands.""" - - # 1-100 - SET_BRIGHTNESS = "setBrightness" - # 2700-6500 - SET_COLOR_TEMPERATURE = "setColorTemperature" - - -class VacuumCommands(Commands): - """Vacuum commands.""" - - START = "start" - STOP = "stop" - DOCK = "dock" - POW_LEVEL = "PowLevel" - - -class BotCommands(Commands): - """Bot commands.""" - - PRESS = "press" - - -class BatteryCirculatorFanMode(StrEnum): - """Fan mode types [Battery Circulator Fan] API.""" - - DIRECT = "direct" - NATURAL = "natural" - SLEEP = "sleep" - BABY = "baby" - - -T = TypeVar("T", bound=CommonCommands) - - class SwitchBotAPI: """SwitchBot API.""" diff --git a/switchbot_api/commands.py b/switchbot_api/commands.py new file mode 100644 index 0000000..e510e8a --- /dev/null +++ b/switchbot_api/commands.py @@ -0,0 +1,370 @@ +from enum import Enum +from typing import TypeVar, List + + +class Commands(Enum): + """Base command class.""" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """ + get supported devices. + return Value + if True -> CommonCommands + if False -> Unknown + if List[str] -> supported devices list + """ + return False + + +class CommonCommands(Commands): + """Common commands.""" + + ON = "turnOn" + OFF = "turnOff" + TOGGLE = "toggle" + PRESS = "press" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + """ + return Value + if True -> CommonCommands + if False -> Unknown + if List[str] -> supported devices list + """ + return True + + +class BotCommands(Commands): + """Bot commands.""" + + PRESS = "press" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Bot"] + + +class OthersCommands(Commands): + """Others commands.""" + + CUSTOMIZE = "customize" # Command {user-defined button name} + + +class CurtainCommands(Commands): + """Curtain & Curtain3 commands.""" + + SET_POSITION = "setPosition" # parameter(str): index0,mode0,position0 e.g. 0,ff,80 + PAUSE = "pause" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Curtain", "Curtain 3"] + + +class LockCommands(Commands): + """Lock commands.""" + + LOCK = "lock" + UNLOCK = "unlock" + DEADBOLT = "deadbolt" # Lock Lite does not support DEADBOLT control + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Smart Lock", "Smart Lock Lite", "Smart Lock Pro", "Smart Lock Ultra"] + + +class HumidifierCommands(Commands): + """Humidifier commands.""" + + # parameter: auto, set to Auto Mode + # 101, set atomization efficiency to 34% + # 102, set atomization efficiency to 67% + # 103, set atomization efficiency to 100% + SET_MODE = "setMode" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Humidifier"] + + +class HumidifierV2Commands(Commands): + """Humidifier 2 commands.""" + + SET_MODE = "setMode" + SET_CHILD_LOCK = "setChildLock" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Humidifier 2"] + + +class AirPurifierCommands(Commands): + """Purifier commands.""" + + # Supported Device List: + # Air Purifier VOC + # Air Purifier Table VOC + # Air Purifier PM2.5 + # Air Purifier Table PM2.5 + + SET_MODE = "setMode" + SET_CHILD_LOCK = "setChildLock" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return [ + "Air Purifier VOC", + "Air Purifier Table VOC", + "Air Purifier PM2.5", + "Air Purifier Table PM2.5", + ] + + +class AirConditionerCommands(Commands): + """Air conditioner commands.""" + + SET_ALL = "setAll" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return False + + +class SwitchCommands(Commands): + """Switch commands.""" + + # Supported Device List: + # Relay Switch 1 + # Relay Switch 1PM + SET_MODE = "setMode" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Relay Switch 1", "Relay Switch 1PM"] + + +class Switch2PMCommands(Commands): + """Switch commands.""" + + # Supported Device List: + # Relay Switch 2PM + SET_MODE = "setMode" + SET_POSITION = "setPosition" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Relay Switch 2PM"] + + +class RGBWLightCommands(Commands): + """RGBWLight commands.""" + + # Supported Device List: + # Strip Light + SET_BRIGHTNESS = "setBrightness" + SET_COLOR = "setColor" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Strip Light"] + + +class RGBWWLightCommands(Commands): + """RGBWwLight commands.""" + + # Supported Device List: + # Floor Lamp + # Strip Light 3 + # Color Bulb + SET_BRIGHTNESS = "setBrightness" + SET_COLOR = "setColor" + SET_COLOR_TEMPERATURE = "setColorTemperature" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Strip Light 3", "Floor Lamp", "Color Bulb"] + + +class DoorBellCommands(Commands): + """Door Bell commands.""" + + ENABLE = "enableMotionDetection" + DISABLE = "disableMotionDetection" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Video Doorbell"] + + +class VacuumCommands(Commands): + """Vacuum commands.""" + + START = "start" + STOP = "stop" + DOCK = "dock" + POW_LEVEL = "PowLevel" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return [ + "K10+", + "K10+ Pro", + "Robot Vacuum Cleaner S1", + "Robot Vacuum Cleaner S1 Plus", + ] + + +class VacuumCleanerV2Commands(Commands): + """VacuumCleanerV2 commands.""" + + # Supported Device List: + # K20+ Pro + # Robot Vacuum Cleaner K10+ Pro Combo + START_CLEAN = "startClean" + PAUSE = "pause" + DOCK = "dock" + SET_VOLUME = "setVolume" + CHANGE_PARAM = "changeParam" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["K20+ Pro", "Robot Vacuum Cleaner K10+ Pro Combo"] + + +class VacuumCleanerV3Commands(Commands): + """VacuumCleanerV3 commands.""" + + # Supported Device List: + # Floor Cleaning Robot S10 + # S20 + START_CLEAN = "startClean" + PAUSE = "pause" + DOCK = "dock" + SET_VOLUME = "setVolume" + CHANGE_PARAM = "changeParam" + ADD_WATER_FOR_HUMI = "addWaterForHumi" + SELF_CLEAN = "selfClean" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Robot Vacuum Cleaner S10", "S20"] + + +class CeilingLightCommands(Commands): + """Ceiling light commands.""" + + # 1-100 + SET_BRIGHTNESS = "setBrightness" + # 2700-6500 + SET_COLOR_TEMPERATURE = "setColorTemperature" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Ceiling Light", "Ceiling Light Pro"] + + +class BlindTiltCommands(Commands): + """Blind Tilt commands.""" + + SET_POSITION = "setPosition" + FULLY_OPEN = "fullyOpen" + CLOSE_UP = "closeUp" + CLOSE_DOWN = "closeDown" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Blind Tilt"] + + +class RollerShadeCommands(Commands): + """Roller Shade commands.""" + + SET_POSITION = "setPosition" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Roller Shade"] + + +class BatteryCirculatorFanCommands(Commands): + """Command types for [Battery Circulator Fan] API.""" + + SET_WIND_SPEED = "setWindSpeed" + SET_WIND_MODE = "setWindMode" + SET_NIGHT_LIGHT_MODE = "setNightLightMode" + + @classmethod + def get_supported_devices(cls) -> bool | List[str]: + """get supported devices.""" + return ["Circulator Fan", "Battery Circulator Fan"] + + +class TVCommands(Commands): + """TV commands.""" + + SET_CHANNEL = "SetChannel" + VOLUME_ADD = "volumeAdd" + VOLUME_SUB = "volumeSub" + CHANNEL_ADD = "channelAdd" + CHANNEL_SUB = "channelSub" + + +class DVDCommands(Commands): + """DVD commands.""" + + SET_MUTE = "setMute" + FAST_FORWARD = "FastForward" + REWIND = "Rewind" + NEXT = "Next" + PREVIOUS = "Previous" + PAUSE = "Pause" + PLAY = "Play" + STOP = "Stop" + + +class SpeakerCommands(Commands): + """Speaker commands.""" + + VOLUME_ADD = "volumeAdd" + VOLUME_SUB = "volumeSub" + + +class FanCommands(Commands): + """Fan commands.""" + + SWING = "swing" + TIMER = "timer" + LOW_SPEED = "lowSpeed" + MIDDLE_SPEED = "middleSpeed" + HIGH_SPEED = "highSpeed" + + +class LightCommands(Commands): + """Light commands.""" + + BRIGHTNESS_UP = "brightnessUp" + BRIGHTNESS_DOWN = "brightnessDown" + + +T = TypeVar("T", bound=CommonCommands) diff --git a/switchbot_api/models.py b/switchbot_api/models.py new file mode 100644 index 0000000..347e433 --- /dev/null +++ b/switchbot_api/models.py @@ -0,0 +1,42 @@ +from enum import Enum, StrEnum + + +class PowerState(Enum): + """Power state.""" + + ON = "on" + OFF = "off" + + +class BatteryCirculatorFanMode(StrEnum): + """Fan mode types [Battery Circulator Fan] API.""" + + DIRECT = "direct" + NATURAL = "natural" + SLEEP = "sleep" + BABY = "baby" + + +class VacuumFanSpeed(StrEnum): + """Fan options for VacuumCommands supported devices.""" + + VACUUM_FAN_SPEED_QUIET = "0" + VACUUM_FAN_SPEED_STANDARD = "1" + VACUUM_FAN_SPEED_STRONG = "2" + VACUUM_FAN_SPEED_MAX = "3" + +class VacuumFanSpeedV2(StrEnum): + """Fan options for VacuumV2Commands & VacuumV3Commands supported devices.""" + + VACUUM_FAN_SPEED_QUIET = "1" + VACUUM_FAN_SPEED_STANDARD = "2" + VACUUM_FAN_SPEED_STRONG = "3" + VACUUM_FAN_SPEED_MAX = "4" + + +class VacuumCleanMode(StrEnum): + """Clean mode for Vacuum.""" + + SWEEP = "sweep" + MOP = "mop" + SWEEP_MOP = "sweep_mop" From 273f83e38fadd6101e0ca082edcc9dd35e5c92c3 Mon Sep 17 00:00:00 2001 From: XiaoLing-git Date: Wed, 25 Jun 2025 11:42:41 +0800 Subject: [PATCH 2/5] update version to 2.7.0 --- pyproject.toml | 2 +- switchbot_api/__init__.py | 2 +- switchbot_api/models.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index eca652b..fd195d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "switchbot_api" -version = "2.6.0" +version = "2.7.0" description = "An asynchronous library to use Switchbot API" authors = ["Ravaka Razafimanantsoa "] license = "MIT" diff --git a/switchbot_api/__init__.py b/switchbot_api/__init__.py index 8322d3c..85fa23c 100644 --- a/switchbot_api/__init__.py +++ b/switchbot_api/__init__.py @@ -56,7 +56,7 @@ PowerState, BatteryCirculatorFanMode, VacuumFanSpeed, -VacuumFanSpeedV2, + VacuumFanSpeedV2, VacuumCleanMode, ) diff --git a/switchbot_api/models.py b/switchbot_api/models.py index 347e433..1bbef91 100644 --- a/switchbot_api/models.py +++ b/switchbot_api/models.py @@ -25,6 +25,7 @@ class VacuumFanSpeed(StrEnum): VACUUM_FAN_SPEED_STRONG = "2" VACUUM_FAN_SPEED_MAX = "3" + class VacuumFanSpeedV2(StrEnum): """Fan options for VacuumV2Commands & VacuumV3Commands supported devices.""" From d0118f8cb8baf37b515aa9c65d595f57706155c9 Mon Sep 17 00:00:00 2001 From: XiaoLing-git Date: Wed, 25 Jun 2025 12:09:18 +0800 Subject: [PATCH 3/5] format code --- makefile | 2 + switchbot_api/__init__.py | 90 ++++++++++++++++++++--------- switchbot_api/commands.py | 117 ++++++++++++++++++++------------------ switchbot_api/models.py | 4 ++ 4 files changed, 129 insertions(+), 84 deletions(-) diff --git a/makefile b/makefile index 8d91a38..8a70cbc 100644 --- a/makefile +++ b/makefile @@ -8,6 +8,8 @@ build: format:pre_commit poetry run black switchbot_api/ poetry run mypy switchbot_api/ + poetry run ruff check --fix switchbot_api/__init__.py + poetry run ruff check --output-format=github . clean: rm -rf dist diff --git a/switchbot_api/__init__.py b/switchbot_api/__init__.py index 85fa23c..e7f08c1 100644 --- a/switchbot_api/__init__.py +++ b/switchbot_api/__init__.py @@ -15,51 +15,85 @@ from aiohttp import ClientError, ClientResponseError, ClientSession from aiohttp.hdrs import METH_GET, METH_POST -from switchbot_api.exceptions import ( - SwitchBotAuthenticationError, - SwitchBotConnectionError, - SwitchBotDeviceOfflineError, -) - from switchbot_api.commands import ( - Commands, - CommonCommands, - OthersCommands, AirConditionerCommands, - HumidifierCommands, - HumidifierV2Commands, AirPurifierCommands, + BatteryCirculatorFanCommands, + BlindTiltCommands, + BotCommands, + CeilingLightCommands, + Commands, + CommonCommands, CurtainCommands, - SwitchCommands, - Switch2PMCommands, - RGBWLightCommands, - RGBWWLightCommands, DoorBellCommands, - VacuumCleanerV2Commands, - VacuumCleanerV3Commands, - BlindTiltCommands, - RollerShadeCommands, - TVCommands, DVDCommands, - SpeakerCommands, FanCommands, - BatteryCirculatorFanCommands, + HumidifierCommands, + HumidifierV2Commands, LightCommands, LockCommands, - CeilingLightCommands, - VacuumCommands, - BotCommands, + OthersCommands, + RGBWLightCommands, + RGBWWLightCommands, + RollerShadeCommands, + SpeakerCommands, + Switch2PMCommands, + SwitchCommands, T, + TVCommands, + VacuumCleanerV2Commands, + VacuumCleanerV3Commands, + VacuumCommands, +) +from switchbot_api.exceptions import ( + SwitchBotAuthenticationError, + SwitchBotConnectionError, + SwitchBotDeviceOfflineError, ) - from switchbot_api.models import ( - PowerState, BatteryCirculatorFanMode, + PowerState, + VacuumCleanMode, VacuumFanSpeed, VacuumFanSpeedV2, - VacuumCleanMode, ) +__all__ = [ + "AirConditionerCommands", + "AirPurifierCommands", + "BatteryCirculatorFanCommands", + "BatteryCirculatorFanMode", + "BlindTiltCommands", + "BotCommands", + "CeilingLightCommands", + "Commands", + "CommonCommands", + "CurtainCommands", + "DVDCommands", + "DoorBellCommands", + "FanCommands", + "HumidifierCommands", + "HumidifierV2Commands", + "LightCommands", + "LockCommands", + "OthersCommands", + "PowerState", + "RGBWLightCommands", + "RGBWWLightCommands", + "RollerShadeCommands", + "SpeakerCommands", + "Switch2PMCommands", + "SwitchCommands", + "T", + "TVCommands", + "VacuumCleanMode", + "VacuumCleanerV2Commands", + "VacuumCleanerV3Commands", + "VacuumCommands", + "VacuumFanSpeed", + "VacuumFanSpeedV2", +] + _API_HOST = "https://api.switch-bot.com" _LOGGER = logging.getLogger(__name__) diff --git a/switchbot_api/commands.py b/switchbot_api/commands.py index e510e8a..4ca44cb 100644 --- a/switchbot_api/commands.py +++ b/switchbot_api/commands.py @@ -1,18 +1,23 @@ +"""Base Commands for SwitchBot API.""" + +from __future__ import annotations + from enum import Enum -from typing import TypeVar, List +from typing import TypeVar class Commands(Enum): """Base command class.""" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """ - get supported devices. - return Value - if True -> CommonCommands - if False -> Unknown - if List[str] -> supported devices list + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices. + + Return: + True -> CommonCommands + False -> Unknown + List[str] -> supported devices list + """ return False @@ -26,13 +31,13 @@ class CommonCommands(Commands): PRESS = "press" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" """ return Value if True -> CommonCommands if False -> Unknown - if List[str] -> supported devices list + if list[str] -> supported devices list """ return True @@ -43,8 +48,8 @@ class BotCommands(Commands): PRESS = "press" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Bot"] @@ -61,8 +66,8 @@ class CurtainCommands(Commands): PAUSE = "pause" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Curtain", "Curtain 3"] @@ -74,8 +79,8 @@ class LockCommands(Commands): DEADBOLT = "deadbolt" # Lock Lite does not support DEADBOLT control @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Smart Lock", "Smart Lock Lite", "Smart Lock Pro", "Smart Lock Ultra"] @@ -89,8 +94,8 @@ class HumidifierCommands(Commands): SET_MODE = "setMode" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Humidifier"] @@ -101,15 +106,15 @@ class HumidifierV2Commands(Commands): SET_CHILD_LOCK = "setChildLock" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Humidifier 2"] class AirPurifierCommands(Commands): """Purifier commands.""" - # Supported Device List: + # Supported Device list: # Air Purifier VOC # Air Purifier Table VOC # Air Purifier PM2.5 @@ -119,8 +124,8 @@ class AirPurifierCommands(Commands): SET_CHILD_LOCK = "setChildLock" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return [ "Air Purifier VOC", "Air Purifier Table VOC", @@ -135,57 +140,57 @@ class AirConditionerCommands(Commands): SET_ALL = "setAll" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return False class SwitchCommands(Commands): """Switch commands.""" - # Supported Device List: + # Supported Device list: # Relay Switch 1 # Relay Switch 1PM SET_MODE = "setMode" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Relay Switch 1", "Relay Switch 1PM"] class Switch2PMCommands(Commands): """Switch commands.""" - # Supported Device List: + # Supported Device list: # Relay Switch 2PM SET_MODE = "setMode" SET_POSITION = "setPosition" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Relay Switch 2PM"] class RGBWLightCommands(Commands): """RGBWLight commands.""" - # Supported Device List: + # Supported Device list: # Strip Light SET_BRIGHTNESS = "setBrightness" SET_COLOR = "setColor" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Strip Light"] class RGBWWLightCommands(Commands): """RGBWwLight commands.""" - # Supported Device List: + # Supported Device list: # Floor Lamp # Strip Light 3 # Color Bulb @@ -194,8 +199,8 @@ class RGBWWLightCommands(Commands): SET_COLOR_TEMPERATURE = "setColorTemperature" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Strip Light 3", "Floor Lamp", "Color Bulb"] @@ -206,8 +211,8 @@ class DoorBellCommands(Commands): DISABLE = "disableMotionDetection" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Video Doorbell"] @@ -220,8 +225,8 @@ class VacuumCommands(Commands): POW_LEVEL = "PowLevel" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return [ "K10+", "K10+ Pro", @@ -233,7 +238,7 @@ def get_supported_devices(cls) -> bool | List[str]: class VacuumCleanerV2Commands(Commands): """VacuumCleanerV2 commands.""" - # Supported Device List: + # Supported Device list: # K20+ Pro # Robot Vacuum Cleaner K10+ Pro Combo START_CLEAN = "startClean" @@ -243,15 +248,15 @@ class VacuumCleanerV2Commands(Commands): CHANGE_PARAM = "changeParam" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["K20+ Pro", "Robot Vacuum Cleaner K10+ Pro Combo"] class VacuumCleanerV3Commands(Commands): """VacuumCleanerV3 commands.""" - # Supported Device List: + # Supported Device list: # Floor Cleaning Robot S10 # S20 START_CLEAN = "startClean" @@ -263,8 +268,8 @@ class VacuumCleanerV3Commands(Commands): SELF_CLEAN = "selfClean" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Robot Vacuum Cleaner S10", "S20"] @@ -277,8 +282,8 @@ class CeilingLightCommands(Commands): SET_COLOR_TEMPERATURE = "setColorTemperature" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Ceiling Light", "Ceiling Light Pro"] @@ -291,8 +296,8 @@ class BlindTiltCommands(Commands): CLOSE_DOWN = "closeDown" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Blind Tilt"] @@ -302,8 +307,8 @@ class RollerShadeCommands(Commands): SET_POSITION = "setPosition" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Roller Shade"] @@ -315,8 +320,8 @@ class BatteryCirculatorFanCommands(Commands): SET_NIGHT_LIGHT_MODE = "setNightLightMode" @classmethod - def get_supported_devices(cls) -> bool | List[str]: - """get supported devices.""" + def get_supported_devices(cls) -> bool | list[str]: + """Get supported devices.""" return ["Circulator Fan", "Battery Circulator Fan"] diff --git a/switchbot_api/models.py b/switchbot_api/models.py index 1bbef91..93bfd57 100644 --- a/switchbot_api/models.py +++ b/switchbot_api/models.py @@ -1,3 +1,7 @@ +"""constant for SwitchBot API.""" + +from __future__ import annotations + from enum import Enum, StrEnum From 0d1b14d1fd44f6cb422f6fa33fe1baf8c88d67d8 Mon Sep 17 00:00:00 2001 From: XiaoLing-git Date: Fri, 27 Jun 2025 10:09:57 +0800 Subject: [PATCH 4/5] commit suggeestion as copilot --- switchbot_api/commands.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/switchbot_api/commands.py b/switchbot_api/commands.py index 4ca44cb..67b4741 100644 --- a/switchbot_api/commands.py +++ b/switchbot_api/commands.py @@ -1,4 +1,4 @@ -"""Base Commands for SwitchBot API.""" +"""Base Commands for SwitchBot API.""" from __future__ import annotations @@ -12,12 +12,10 @@ class Commands(Enum): @classmethod def get_supported_devices(cls) -> bool | list[str]: """Get supported devices. - - Return: + Return Value: True -> CommonCommands False -> Unknown List[str] -> supported devices list - """ return False From f0ee99687027ee714f27a96496129ec08b1ca812 Mon Sep 17 00:00:00 2001 From: XiaoLing-git Date: Fri, 27 Jun 2025 11:15:44 +0800 Subject: [PATCH 5/5] commit suggeestion --- switchbot_api/__init__.py | 2 + switchbot_api/commands.py | 88 +++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/switchbot_api/__init__.py b/switchbot_api/__init__.py index e7f08c1..60cb9b4 100644 --- a/switchbot_api/__init__.py +++ b/switchbot_api/__init__.py @@ -32,6 +32,7 @@ HumidifierV2Commands, LightCommands, LockCommands, + LockV2Commands, OthersCommands, RGBWLightCommands, RGBWWLightCommands, @@ -76,6 +77,7 @@ "HumidifierV2Commands", "LightCommands", "LockCommands", + "LockV2Commands", "OthersCommands", "PowerState", "RGBWLightCommands", diff --git a/switchbot_api/commands.py b/switchbot_api/commands.py index 67b4741..580ee7b 100644 --- a/switchbot_api/commands.py +++ b/switchbot_api/commands.py @@ -10,14 +10,14 @@ class Commands(Enum): """Base command class.""" @classmethod - def get_supported_devices(cls) -> bool | list[str]: - """Get supported devices. - Return Value: - True -> CommonCommands - False -> Unknown - List[str] -> supported devices list - """ - return False + def is_supported(cls, device_type: str) -> bool: + """Is this commands supported this device type.""" + return device_type in cls.get_supported_devices() + + @classmethod + def get_supported_devices(cls) -> list[str]: + """Get supported devices.""" + return [] class CommonCommands(Commands): @@ -28,16 +28,18 @@ class CommonCommands(Commands): TOGGLE = "toggle" PRESS = "press" + # Considering the wide range of CommonCommands, they are not inherited here. @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def is_supported(cls, device_type: str) -> bool: + """Is this commands supported this device type.""" + error_msg = "CommonCommands not implement this method" + raise NotImplementedError(error_msg) + + @classmethod + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" - """ - return Value - if True -> CommonCommands - if False -> Unknown - if list[str] -> supported devices list - """ - return True + error_msg = "CommonCommands not implement this method" + raise NotImplementedError(error_msg) class BotCommands(Commands): @@ -46,7 +48,7 @@ class BotCommands(Commands): PRESS = "press" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Bot"] @@ -64,7 +66,7 @@ class CurtainCommands(Commands): PAUSE = "pause" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Curtain", "Curtain 3"] @@ -74,14 +76,26 @@ class LockCommands(Commands): LOCK = "lock" UNLOCK = "unlock" - DEADBOLT = "deadbolt" # Lock Lite does not support DEADBOLT control @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Smart Lock", "Smart Lock Lite", "Smart Lock Pro", "Smart Lock Ultra"] +class LockV2Commands(Commands): + """Lock commands.""" + + LOCK = "lock" + UNLOCK = "unlock" + DEADBOLT = "deadbolt" + + @classmethod + def get_supported_devices(cls) -> list[str]: + """Get supported devices.""" + return ["Smart Lock", "Smart Lock Pro", "Smart Lock Ultra"] + + class HumidifierCommands(Commands): """Humidifier commands.""" @@ -92,7 +106,7 @@ class HumidifierCommands(Commands): SET_MODE = "setMode" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Humidifier"] @@ -104,7 +118,7 @@ class HumidifierV2Commands(Commands): SET_CHILD_LOCK = "setChildLock" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Humidifier 2"] @@ -122,7 +136,7 @@ class AirPurifierCommands(Commands): SET_CHILD_LOCK = "setChildLock" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return [ "Air Purifier VOC", @@ -138,9 +152,9 @@ class AirConditionerCommands(Commands): SET_ALL = "setAll" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" - return False + return ["Air Conditioner"] class SwitchCommands(Commands): @@ -152,7 +166,7 @@ class SwitchCommands(Commands): SET_MODE = "setMode" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Relay Switch 1", "Relay Switch 1PM"] @@ -166,7 +180,7 @@ class Switch2PMCommands(Commands): SET_POSITION = "setPosition" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Relay Switch 2PM"] @@ -180,7 +194,7 @@ class RGBWLightCommands(Commands): SET_COLOR = "setColor" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Strip Light"] @@ -197,7 +211,7 @@ class RGBWWLightCommands(Commands): SET_COLOR_TEMPERATURE = "setColorTemperature" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Strip Light 3", "Floor Lamp", "Color Bulb"] @@ -209,7 +223,7 @@ class DoorBellCommands(Commands): DISABLE = "disableMotionDetection" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Video Doorbell"] @@ -223,7 +237,7 @@ class VacuumCommands(Commands): POW_LEVEL = "PowLevel" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return [ "K10+", @@ -246,7 +260,7 @@ class VacuumCleanerV2Commands(Commands): CHANGE_PARAM = "changeParam" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["K20+ Pro", "Robot Vacuum Cleaner K10+ Pro Combo"] @@ -266,7 +280,7 @@ class VacuumCleanerV3Commands(Commands): SELF_CLEAN = "selfClean" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Robot Vacuum Cleaner S10", "S20"] @@ -280,7 +294,7 @@ class CeilingLightCommands(Commands): SET_COLOR_TEMPERATURE = "setColorTemperature" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Ceiling Light", "Ceiling Light Pro"] @@ -294,7 +308,7 @@ class BlindTiltCommands(Commands): CLOSE_DOWN = "closeDown" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Blind Tilt"] @@ -305,7 +319,7 @@ class RollerShadeCommands(Commands): SET_POSITION = "setPosition" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Roller Shade"] @@ -318,7 +332,7 @@ class BatteryCirculatorFanCommands(Commands): SET_NIGHT_LIGHT_MODE = "setNightLightMode" @classmethod - def get_supported_devices(cls) -> bool | list[str]: + def get_supported_devices(cls) -> list[str]: """Get supported devices.""" return ["Circulator Fan", "Battery Circulator Fan"]