diff --git a/pyproject.toml b/pyproject.toml index e6f6889..edc88e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "switchbot_api" -version = "2.11.1" +version = "2.12.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 d41a234..9055019 100644 --- a/switchbot_api/__init__.py +++ b/switchbot_api/__init__.py @@ -62,6 +62,10 @@ AirPurifierMode, BatteryCirculatorFanMode, BatteryLevel, + DeviceSupportMap, + DoorState, + EntityType, + LockState, PowerState, SmartRadiatorThermostatMode, VacuumCleanMode, @@ -86,13 +90,17 @@ "CurtainCommands", "DVDCommands", "Device", + "DeviceSupportMap", "DoorBellCommands", + "DoorState", + "EntityType", "FanCommands", "HumidifierCommands", "HumidifierV2Commands", "KeyPadCommands", "LightCommands", "LockCommands", + "LockState", "LockV2Commands", "LockV3Commands", "OthersCommands", diff --git a/switchbot_api/models.py b/switchbot_api/models.py index 7dbf0b8..ff5995e 100644 --- a/switchbot_api/models.py +++ b/switchbot_api/models.py @@ -12,6 +12,184 @@ class PowerState(Enum): OFF = "off" +class EntityType(Enum): + """Entity Type.""" + + BINARY_SENSOR = "binary_sensors" + BUTTON = "buttons" + CLIMATE = "climates" + COVER = "covers" + FAN = "fans" + HUMIDIFIER = "humidifiers" + IMAGE = "images" + LIGHT = "lights" + LOCK = "locks" + SENSOR = "sensors" + SWITCH = "switches" + VACUUM = "vacuums" + + +DeviceSupportMap: dict[str, dict[str, bool | list[EntityType]]] = { + "Smart Radiator Thermostat": { + "webhook": False, + "entity_list": [EntityType.CLIMATE, EntityType.SENSOR], + }, + "Relay Switch 1PM": { + "webhook": False, + "entity_list": [EntityType.SWITCH, EntityType.SENSOR], + }, + "Relay Switch 1": {"webhook": False, "entity_list": [EntityType.SWITCH]}, + "Relay Switch 2PM": { + "webhook": False, + "entity_list": [EntityType.SWITCH, EntityType.SENSOR], + }, + "K10+": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "K10+ Pro": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "Robot Vacuum Cleaner S1": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "Robot Vacuum Cleaner S1 Plus": { + "webhook": True, + "entity_list": [EntityType.VACUUM], + }, + "K20+ Pro": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "Robot Vacuum Cleaner K10+ Pro Combo": { + "webhook": True, + "entity_list": [EntityType.VACUUM], + }, + "Robot Vacuum Cleaner S10": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "Robot Vacuum Cleaner S20": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "S20": {"webhook": True, "entity_list": [EntityType.VACUUM]}, + "Robot Vacuum Cleaner K11 Plus": { + "webhook": True, + "entity_list": [EntityType.VACUUM], + }, + "Smart Lock": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Lite": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Pro": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Ultra": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Vision": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Vision Pro": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Smart Lock Pro Wifi": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Lock Vision": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Lock Vision Pro": { + "webhook": False, + "entity_list": [EntityType.LOCK, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Motion Sensor": { + "webhook": True, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "Contact Sensor": { + "webhook": True, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "Presence Sensor": { + "webhook": True, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "Hub 3": { + "webhook": True, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "Water Detector": { + "webhook": True, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "Battery Circulator Fan": { + "webhook": False, + "entity_list": [EntityType.FAN, EntityType.SENSOR], + }, + "Standing Fan": { + "webhook": False, + "entity_list": [EntityType.FAN, EntityType.SENSOR], + }, + "Circulator Fan": {"webhook": False, "entity_list": [EntityType.FAN]}, + "Curtain": { + "webhook": False, + "entity_list": [EntityType.COVER, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Curtain3": { + "webhook": False, + "entity_list": [EntityType.COVER, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Roller Shade": { + "webhook": False, + "entity_list": [EntityType.COVER, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Blind Tilt": { + "webhook": False, + "entity_list": [EntityType.COVER, EntityType.SENSOR, EntityType.BINARY_SENSOR], + }, + "Strip Light": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Strip Light 3": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Floor Lamp": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Color Bulb": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "RGBICWW Floor Lamp": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "RGBICWW Strip Light": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Ceiling Light": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Ceiling Light Pro": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "RGBIC Neon Rope Light": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "RGBIC Neon Wire Rope Light": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Candle Warmer Lamp": {"webhook": False, "entity_list": [EntityType.LIGHT]}, + "Humidifier2": {"webhook": False, "entity_list": [EntityType.HUMIDIFIER]}, + "Humidifier": { + "webhook": False, + "entity_list": [EntityType.HUMIDIFIER, EntityType.SENSOR], + }, + "Home Climate Panel": { + "webhook": False, + "entity_list": [EntityType.BINARY_SENSOR, EntityType.SENSOR], + }, + "AI Art Frame": { + "webhook": False, + "entity_list": [EntityType.BUTTON, EntityType.SENSOR, EntityType.IMAGE], + }, + "WeatherStation": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "Meter": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "MeterPlus": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "WoIOSensor": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "Hub 2": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "MeterPro": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "MeterPro(CO2)": {"webhook": False, "entity_list": [EntityType.SENSOR]}, + "Plug": {"webhook": False, "entity_list": [EntityType.SWITCH]}, + "Plug Mini (US)": { + "webhook": False, + "entity_list": [EntityType.SENSOR, EntityType.SWITCH], + }, + "Plug Mini (JP)": { + "webhook": False, + "entity_list": [EntityType.SENSOR, EntityType.SWITCH], + }, + "Plug Mini (EU)": { + "webhook": False, + "entity_list": [EntityType.SENSOR, EntityType.SWITCH], + }, +} + + class BatteryCirculatorFanMode(StrEnum): """Fan mode types [Battery Circulator Fan] API.""" @@ -108,3 +286,22 @@ def get_battery_level(cls, value: int) -> BatteryLevel: if 10 > value >= 0: return cls.Critical return cls.Unknown + + +class DoorState(Enum): + """Door State.""" + + OPEN = "open" + CLOSED = "close" + + +class LockState(Enum): + """Lock State.""" + + LOCKED = "locked" + UNLOCKED = "unlocked" + LOCKING = "locking" + UNLOCKING = "unlocking" + JAMMED = "jammed" + LATCH_BOLT_LOCKED = "latchBoltLocked" + HALF_LOCKED = "halfLocked" diff --git a/switchbot_api/utils.py b/switchbot_api/utils.py index f8e068b..96f1905 100644 --- a/switchbot_api/utils.py +++ b/switchbot_api/utils.py @@ -3,6 +3,7 @@ import aiohttp from aiohttp import ClientResponse +from . import DeviceSupportMap from .exceptions import SwitchBotDeviceRequestError @@ -26,3 +27,8 @@ async def get_file_stream_from_cloud(url: str, timeout: float = 5) -> bytes: except Exception as e: msg = f"{e}" raise SwitchBotDeviceRequestError(msg) from e + + +def assert_device_is_supported(device_model: str) -> bool: + """Determine whether the device is included in the supported list.""" + return device_model in DeviceSupportMap