From 07b1c88b7e4ee90f270166172f195a013019e500 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sun, 3 Sep 2017 22:37:32 +0200 Subject: [PATCH 1/3] Device support for the Xiaomi Mi Smart Fan added. --- README.md | 1 + mirobo/__init__.py | 1 + mirobo/airpurifier.py | 4 - mirobo/fan.py | 188 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 mirobo/fan.py diff --git a/README.md b/README.md index 3510e108d..a16e8e786 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Thanks for the nice people over [ioBroker forum](http://forum.iobroker.net/viewt * Xiaomi Philips LED Ceiling Lamp * Xiaomi Philips LED Ball Lamp * Xiaomi Universal IR Remote Controller (Chuangmi IR) +* Xiaomi Mi Smart Fan ### Adding support for other devices diff --git a/mirobo/__init__.py b/mirobo/__init__.py index c51860290..3e4d2bd9f 100644 --- a/mirobo/__init__.py +++ b/mirobo/__init__.py @@ -9,5 +9,6 @@ from mirobo.ceil import Ceil from mirobo.philips_eyecare import PhilipsEyecare from mirobo.chuangmi_ir import ChuangmiIr +from mirobo.fan import Fan from mirobo.device import Device, DeviceException from mirobo.discovery import Discovery diff --git a/mirobo/airpurifier.py b/mirobo/airpurifier.py index d45bc0ca7..465e82851 100644 --- a/mirobo/airpurifier.py +++ b/mirobo/airpurifier.py @@ -57,8 +57,6 @@ def off(self): def set_mode(self, mode: OperationMode): """Set mode.""" - - # auto, silent, favorite, idle return self.send("set_mode", [mode.value]) def set_favorite_level(self, level: int): @@ -70,8 +68,6 @@ def set_favorite_level(self, level: int): def set_led_brightness(self, brightness: LedBrightness): """Set led brightness.""" - - # bright: 0, dim: 1, off: 2 return self.send("set_led_b", [brightness.value]) def set_led(self, led: bool): diff --git a/mirobo/fan.py b/mirobo/fan.py new file mode 100644 index 000000000..20014d0bc --- /dev/null +++ b/mirobo/fan.py @@ -0,0 +1,188 @@ +import logging +from .device import Device +from typing import Any, Dict +import enum + +_LOGGER = logging.getLogger(__name__) + + +class LedBrightness(enum.Enum): + Bright = 0 + Dim = 1 + Off = 2 + + +class MoveDirection(enum.Enum): + Left = 'left' + Right = 'right' + + +class FanStatus: + """Container for status reports from the Xiaomi Smart Fan.""" + + def __init__(self, data: Dict[str, Any]) -> None: + # ['temp_dec', 'humidity', 'angle', 'speed', 'poweroff_time', 'power', + # 'ac_power', 'battery', 'angle_enable', 'speed_level', + # 'natural_level', 'child_lock', 'buzzer', 'led_b', 'led'] + # + # [232, 46, 30, 298, 0, 'on', 'off', 98, 'off', 1, 0, 'off', 'on', + # 1, 'on'] + self.data = data + + @property + def power(self) -> str: + return self.data["power"] + + @property + def is_on(self) -> bool: + return self.power == "on" + + @property + def humidity(self) -> int: + return self.data["humidity"] + + @property + def temperature(self) -> float: + if self.data["temp_dec"] is not None: + return self.data["temp_dec"] / 10.0 + + @property + def led(self) -> bool: + return self.data["led"] == "on" + + @property + def led_brightness(self) -> LedBrightness: + if self.data["led_b"] is not None: + return LedBrightness(self.data["led_b"]) + + @property + def buzzer(self) -> bool: + return self.data["buzzer"] == "on" + + @property + def child_lock(self) -> bool: + return self.data["child_lock"] == "on" + + @property + def natural_level(self) -> int: + return self.data["natural_level"] + + @property + def speed_level(self) -> int: + return self.data["speed_level"] + + @property + def oscillate(self) -> bool: + return self.data["angle_enable"] == "on" + + @property + def battery(self) -> int: + return self.data["battery"] + + @property + def ac_power(self) -> bool: + return self.data["ac_power"] == "on" + + @property + def poweroff_time(self) -> int: + return self.data["poweroff_time"] + + @property + def speed(self) -> int: + return self.data["speed"] + + @property + def angle(self) -> int: + return self.data["angle"] + + def __str__(self) -> str: + s = " Date: Mon, 4 Sep 2017 07:45:52 +0200 Subject: [PATCH 2/3] Some returns added. --- mirobo/fan.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mirobo/fan.py b/mirobo/fan.py index 20014d0bc..e2e4a7ffc 100644 --- a/mirobo/fan.py +++ b/mirobo/fan.py @@ -45,6 +45,8 @@ def humidity(self) -> int: def temperature(self) -> float: if self.data["temp_dec"] is not None: return self.data["temp_dec"] / 10.0 + else: + return None @property def led(self) -> bool: @@ -54,6 +56,8 @@ def led(self) -> bool: def led_brightness(self) -> LedBrightness: if self.data["led_b"] is not None: return LedBrightness(self.data["led_b"]) + else: + return None @property def buzzer(self) -> bool: From e99be3b850c49cf2d2f6a2b1d37c0c036f2200a0 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Tue, 5 Sep 2017 06:30:50 +0200 Subject: [PATCH 3/3] Typing relaxed to allow a return value of "None". --- mirobo/fan.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mirobo/fan.py b/mirobo/fan.py index e2e4a7ffc..5349f9ad2 100644 --- a/mirobo/fan.py +++ b/mirobo/fan.py @@ -1,6 +1,6 @@ import logging from .device import Device -from typing import Any, Dict +from typing import Any, Dict, Optional import enum _LOGGER = logging.getLogger(__name__) @@ -42,22 +42,20 @@ def humidity(self) -> int: return self.data["humidity"] @property - def temperature(self) -> float: + def temperature(self) -> Optional[float]: if self.data["temp_dec"] is not None: return self.data["temp_dec"] / 10.0 - else: - return None + return None @property def led(self) -> bool: return self.data["led"] == "on" @property - def led_brightness(self) -> LedBrightness: + def led_brightness(self) -> Optional[LedBrightness]: if self.data["led_b"] is not None: return LedBrightness(self.data["led_b"]) - else: - return None + return None @property def buzzer(self) -> bool: