From ed80c50981e26dee34abc9a5f201a6b2a8ecc9fa Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 21 Oct 2017 15:52:20 +0200 Subject: [PATCH 1/2] Some typing hints added and the code order aligned. --- miio/airhumidifier.py | 102 +++++++++++++++--------------- miio/airpurifier.py | 130 +++++++++++++++++++------------------- miio/airqualitymonitor.py | 5 +- miio/ceil.py | 36 +++++------ miio/fan.py | 2 +- miio/plug.py | 19 +++--- miio/plug_v1.py | 73 ++++++++++++--------- miio/strip.py | 18 +++--- miio/waterpurifier.py | 38 +++++------ miio/wifispeaker.py | 2 +- miio/yeelight.py | 45 ++++++------- 11 files changed, 242 insertions(+), 228 deletions(-) diff --git a/miio/airhumidifier.py b/miio/airhumidifier.py index 27aca22d1..c80361b61 100644 --- a/miio/airhumidifier.py +++ b/miio/airhumidifier.py @@ -19,10 +19,60 @@ class LedBrightness(enum.Enum): Off = 2 +class AirHumidifierStatus: + """Container for status reports from the air humidifier.""" + + def __init__(self, data: Dict[str, Any]) -> None: + self.data = data + + @property + def power(self) -> str: + return self.data["power"] + + @property + def is_on(self) -> bool: + return self.power == "on" + + @property + def mode(self) -> OperationMode: + return OperationMode(self.data["mode"]) + + @property + def temperature(self) -> Optional[float]: + if self.data["temp_dec"] is not None: + return self.data["temp_dec"] / 10.0 + return None + + @property + def humidity(self) -> int: + return self.data["humidity"] + + @property + def buzzer(self) -> bool: + return self.data["buzzer"] == "on" + + @property + def led(self) -> bool: + return self.data["led"] == "on" + + @property + def led_brightness(self) -> Optional[LedBrightness]: + if self.data["led_b"] is not None: + return LedBrightness(self.data["led_b"]) + return None + + def __str__(self) -> str: + s = "" % \ + (self.power, self.mode, self.temperature, + self.humidity, self.led, self.led_brightness, self.buzzer) + return s + + class AirHumidifier(Device): """Main class representing the air humidifier.""" - def status(self): + def status(self) -> AirHumidifierStatus: """Retrieve properties.""" properties = ['power', 'mode', 'temp_dec', 'humidity', 'buzzer', @@ -73,53 +123,3 @@ def set_buzzer(self, buzzer: bool): return self.send("set_buzzer", ["on"]) else: return self.send("set_buzzer", ["off"]) - - -class AirHumidifierStatus: - """Container for status reports from the air humidifier.""" - - def __init__(self, data: Dict[str, Any]) -> None: - self.data = data - - @property - def power(self) -> str: - return self.data["power"] - - @property - def is_on(self) -> bool: - return self.power == "on" - - @property - def mode(self) -> OperationMode: - return OperationMode(self.data["mode"]) - - @property - def temperature(self) -> Optional[float]: - if self.data["temp_dec"] is not None: - return self.data["temp_dec"] / 10.0 - return None - - @property - def humidity(self) -> int: - return self.data["humidity"] - - @property - def buzzer(self) -> bool: - return self.data["buzzer"] == "on" - - @property - def led(self) -> bool: - return self.data["led"] == "on" - - @property - def led_brightness(self) -> Optional[LedBrightness]: - if self.data["led_b"] is not None: - return LedBrightness(self.data["led_b"]) - return None - - def __str__(self) -> str: - s = "" % \ - (self.power, self.mode, self.temperature, - self.humidity, self.led, self.led_brightness, self.buzzer) - return s diff --git a/miio/airpurifier.py b/miio/airpurifier.py index 2e1b97d34..bd4b89674 100644 --- a/miio/airpurifier.py +++ b/miio/airpurifier.py @@ -20,71 +20,6 @@ class LedBrightness(enum.Enum): Off = 2 -class AirPurifier(Device): - """Main class representing the air purifier.""" - - def status(self): - """Retrieve properties.""" - - properties = ['power', 'aqi', 'humidity', 'temp_dec', - 'mode', 'led', 'led_b', 'buzzer', 'child_lock', - 'bright', 'favorite_level', 'filter1_life', - 'f1_hour_used', 'use_time', 'motor1_speed'] - - values = self.send( - "get_prop", - properties - ) - - properties_count = len(properties) - values_count = len(values) - if properties_count != values_count: - _LOGGER.debug( - "Count (%s) of requested properties does not match the " - "count (%s) of received values.", - properties_count, values_count) - - return AirPurifierStatus( - defaultdict(lambda: None, zip(properties, values))) - - def on(self): - """Power on.""" - return self.send("set_power", ["on"]) - - def off(self): - """Power off.""" - return self.send("set_power", ["off"]) - - def set_mode(self, mode: OperationMode): - """Set mode.""" - return self.send("set_mode", [mode.value]) - - def set_favorite_level(self, level: int): - """Set favorite level.""" - - # Set the favorite level used when the mode is `favorite`, - # should be between 0 and 17. - return self.send("set_favorite_level", [level]) # 0 ... 17 - - def set_led_brightness(self, brightness: LedBrightness): - """Set led brightness.""" - return self.send("set_led_b", [brightness.value]) - - def set_led(self, led: bool): - """Turn led on/off.""" - if led: - return self.send("set_led", ['on']) - else: - return self.send("set_led", ['off']) - - def set_buzzer(self, buzzer: bool): - """Set buzzer on/off.""" - if buzzer: - return self.send("set_buzzer", ["on"]) - else: - return self.send("set_buzzer", ["off"]) - - class AirPurifierStatus: """Container for status reports from the air purifier.""" @@ -194,3 +129,68 @@ def __str__(self) -> str: self.filter_hours_used, self.use_time, self.motor_speed) return s + + +class AirPurifier(Device): + """Main class representing the air purifier.""" + + def status(self) -> AirPurifierStatus: + """Retrieve properties.""" + + properties = ['power', 'aqi', 'humidity', 'temp_dec', + 'mode', 'led', 'led_b', 'buzzer', 'child_lock', + 'bright', 'favorite_level', 'filter1_life', + 'f1_hour_used', 'use_time', 'motor1_speed'] + + values = self.send( + "get_prop", + properties + ) + + properties_count = len(properties) + values_count = len(values) + if properties_count != values_count: + _LOGGER.debug( + "Count (%s) of requested properties does not match the " + "count (%s) of received values.", + properties_count, values_count) + + return AirPurifierStatus( + defaultdict(lambda: None, zip(properties, values))) + + def on(self): + """Power on.""" + return self.send("set_power", ["on"]) + + def off(self): + """Power off.""" + return self.send("set_power", ["off"]) + + def set_mode(self, mode: OperationMode): + """Set mode.""" + return self.send("set_mode", [mode.value]) + + def set_favorite_level(self, level: int): + """Set favorite level.""" + + # Set the favorite level used when the mode is `favorite`, + # should be between 0 and 17. + return self.send("set_favorite_level", [level]) # 0 ... 17 + + def set_led_brightness(self, brightness: LedBrightness): + """Set led brightness.""" + return self.send("set_led_b", [brightness.value]) + + def set_led(self, led: bool): + """Turn led on/off.""" + if led: + return self.send("set_led", ['on']) + else: + return self.send("set_led", ['off']) + + def set_buzzer(self, buzzer: bool): + """Set buzzer on/off.""" + if buzzer: + return self.send("set_buzzer", ["on"]) + else: + return self.send("set_buzzer", ["off"]) diff --git a/miio/airqualitymonitor.py b/miio/airqualitymonitor.py index 467649591..a2d14d371 100644 --- a/miio/airqualitymonitor.py +++ b/miio/airqualitymonitor.py @@ -32,10 +32,7 @@ def battery(self) -> int: class AirQualityMonitor(Device): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - def status(self): + def status(self) -> AirQualityMonitorStatus: """Return device status.""" properties = ['power', 'aqi', 'battery', 'usb_state'] diff --git a/miio/ceil.py b/miio/ceil.py index 9a6bf1fac..155f6a420 100644 --- a/miio/ceil.py +++ b/miio/ceil.py @@ -64,6 +64,24 @@ class Ceil(Device): # TODO: - Auto On/Off Not Supported # - Adjust Scenes with Wall Switch Not Supported + def status(self) -> CeilStatus: + """Retrieve properties.""" + properties = ['power', 'bright', 'cct', 'snm', 'dv', 'bl', 'ac', ] + values = self.send( + "get_prop", + properties + ) + + properties_count = len(properties) + values_count = len(values) + if properties_count != values_count: + _LOGGER.debug( + "Count (%s) of requested properties does not match the " + "count (%s) of received values.", + properties_count, values_count) + + return CeilStatus(defaultdict(lambda: None, zip(properties, values))) + def on(self): """Power on.""" return self.send("set_power", ["on"]) @@ -103,21 +121,3 @@ def automatic_color_temperature_on(self): def automatic_color_temperature_off(self): """Automatic color temperature off.""" return self.send("enable_ac", [0]) - - def status(self) -> CeilStatus: - """Retrieve properties.""" - properties = ['power', 'bright', 'cct', 'snm', 'dv', 'bl', 'ac', ] - values = self.send( - "get_prop", - properties - ) - - properties_count = len(properties) - values_count = len(values) - if properties_count != values_count: - _LOGGER.debug( - "Count (%s) of requested properties does not match the " - "count (%s) of received values.", - properties_count, values_count) - - return CeilStatus(defaultdict(lambda: None, zip(properties, values))) diff --git a/miio/fan.py b/miio/fan.py index 5349f9ad2..8bc489b91 100644 --- a/miio/fan.py +++ b/miio/fan.py @@ -113,7 +113,7 @@ def __str__(self) -> str: class Fan(Device): """Main class representing the Xiaomi Smart Fan.""" - def status(self): + def status(self) -> FanStatus: """Retrieve properties.""" properties = ['temp_dec', 'humidity', 'angle', 'speed', 'poweroff_time', 'power', 'ac_power', 'battery', diff --git a/miio/plug.py b/miio/plug.py index 0baf5c933..b5f10e45c 100644 --- a/miio/plug.py +++ b/miio/plug.py @@ -8,6 +8,7 @@ class PlugStatus: """Container for status reports from the plug.""" + def __init__(self, data: Dict[str, Any]) -> None: self.data = data @@ -42,15 +43,7 @@ def __str__(self) -> str: class Plug(Device): """Main class representing the smart wifi socket / plug.""" - def on(self): - """Power on.""" - return self.send("set_power", ["on"]) - - def off(self): - """Power off.""" - return self.send("set_power", ["off"]) - - def status(self): + def status(self) -> PlugStatus: """Retrieve properties.""" properties = ['power', 'temperature', 'current'] values = self.send( @@ -68,3 +61,11 @@ def status(self): return PlugStatus( defaultdict(lambda: None, zip(properties, values))) + + def on(self): + """Power on.""" + return self.send("set_power", ["on"]) + + def off(self): + """Power off.""" + return self.send("set_power", ["off"]) diff --git a/miio/plug_v1.py b/miio/plug_v1.py index 96bb00514..f48ba3b97 100644 --- a/miio/plug_v1.py +++ b/miio/plug_v1.py @@ -1,38 +1,14 @@ +import logging +from typing import Dict, Any, Optional +from collections import defaultdict from .device import Device -from typing import Any, Dict - -class PlugV1(Device): - """Main class representing the chuangmi plug v1.""" - - def on(self): - """Power on.""" - return self.send("set_on", []) - - def off(self): - """Power off.""" - return self.send("set_off", []) - - def usb_on(self): - """Power on.""" - return self.send("set_usb_on", []) - - def usb_off(self): - """Power off.""" - return self.send("set_usb_off", []) - - def status(self): - """Retrieve properties.""" - properties = ['on', 'usb_on'] - values = self.send( - "get_prop", - properties - ) - return PlugV1Status(dict(zip(properties, values))) +_LOGGER = logging.getLogger(__name__) class PlugV1Status: """Container for status reports from the plug.""" + def __init__(self, data: Dict[str, Any]) -> None: self.data = data @@ -53,3 +29,42 @@ def __str__(self) -> str: (self.power, self.usb_power) return s + + +class PlugV1(Device): + """Main class representing the chuangmi plug v1.""" + + def status(self) -> PlugV1Status: + """Retrieve properties.""" + properties = ['on', 'usb_on'] + values = self.send( + "get_prop", + properties + ) + + properties_count = len(properties) + values_count = len(values) + if properties_count != values_count: + _LOGGER.debug( + "Count (%s) of requested properties does not match the " + "count (%s) of received values.", + properties_count, values_count) + + return PlugV1Status( + defaultdict(lambda: None, zip(properties, values))) + + def on(self): + """Power on.""" + return self.send("set_on", []) + + def off(self): + """Power off.""" + return self.send("set_off", []) + + def usb_on(self): + """Power on.""" + return self.send("set_usb_on", []) + + def usb_off(self): + """Power off.""" + return self.send("set_usb_off", []) diff --git a/miio/strip.py b/miio/strip.py index 48a400070..4f704847f 100644 --- a/miio/strip.py +++ b/miio/strip.py @@ -59,15 +59,7 @@ def __str__(self) -> str: class Strip(Device): """Main class representing the smart strip.""" - def on(self): - """Power on.""" - return self.send("set_power", ["on"]) - - def off(self): - """Power off.""" - return self.send("set_power", ["off"]) - - def status(self): + def status(self) -> StripStatus: """Retrieve properties.""" properties = ['power', 'temperature', 'current', 'mode'] values = self.send( @@ -86,6 +78,14 @@ def status(self): return StripStatus( defaultdict(lambda: None, zip(properties, values))) + def on(self): + """Power on.""" + return self.send("set_power", ["on"]) + + def off(self): + """Power off.""" + return self.send("set_power", ["off"]) + def set_power_mode(self, mode: PowerMode): """Set mode.""" diff --git a/miio/waterpurifier.py b/miio/waterpurifier.py index 2186cd376..5777526de 100644 --- a/miio/waterpurifier.py +++ b/miio/waterpurifier.py @@ -6,10 +6,28 @@ _LOGGER = logging.getLogger(__name__) +class WaterPurifierStatus: + """Container for status reports from the water purifier.""" + + def __init__(self, data: Dict[str, Any]) -> None: + self.data = data + + @property + def power(self) -> str: + return self.data["power"] + + @property + def is_on(self) -> bool: + return self.power == "on" + + def __str__(self) -> str: + return "" % self.power + + class WaterPurifier(Device): """Main class representing the waiter purifier.""" - def status(self): + def status(self) -> WaterPurifierStatus: """Retrieve properties.""" properties = ['power'] @@ -37,21 +55,3 @@ def on(self): def off(self): """Power off.""" return self.send("set_power", ["off"]) - - -class WaterPurifierStatus: - """Container for status reports from the water purifier.""" - - def __init__(self, data: Dict[str, Any]) -> None: - self.data = data - - @property - def power(self) -> str: - return self.data["power"] - - @property - def is_on(self) -> bool: - return self.power == "on" - - def __str__(self) -> str: - return "" % self.power diff --git a/miio/wifispeaker.py b/miio/wifispeaker.py index 2b64268e5..689a5b552 100644 --- a/miio/wifispeaker.py +++ b/miio/wifispeaker.py @@ -69,7 +69,7 @@ def __init__(self, *args, **kwargs): "`play_mode` and `transport_channel`.", stacklevel=2) super().__init__(*args, **kwargs) - def status(self): + def status(self) -> WifiSpeakerStatus: """Return device status.""" return WifiSpeakerStatus(self.send("get_prop", ["umi"])) diff --git a/miio/yeelight.py b/miio/yeelight.py index 8c8b49851..85ee3a30d 100644 --- a/miio/yeelight.py +++ b/miio/yeelight.py @@ -97,11 +97,34 @@ class Yeelight(Device): (https://yeelight.readthedocs.io/en/latest/), which however requires enabling the developer mode on the bulbs. """ + def __init__(self, *args, **kwargs): warnings.warn("Please consider using python-yeelight " "for more complete support.", stacklevel=2) super().__init__(*args, **kwargs) + def status(self) -> YeelightStatus: + """Retrieve properties.""" + properties = [ + "power", + "bright", + "ct", + "rgb", + "hue", + "sat", + "color_mode", + "name", + "lan_ctrl", + "save_state" + ] + + values = self.send( + "get_prop", + properties + ) + + return YeelightStatus(dict(zip(properties, values))) + def on(self): """Power on.""" """ @@ -161,27 +184,5 @@ def set_scene(self, scene, *vals): raise NotImplementedError("Setting the scene is not implemented yet.") # return self.send("set_scene", [scene, *vals]) - def status(self): - """Retrieve properties.""" - properties = [ - "power", - "bright", - "ct", - "rgb", - "hue", - "sat", - "color_mode", - "name", - "lan_ctrl", - "save_state" - ] - - values = self.send( - "get_prop", - properties - ) - - return YeelightStatus(dict(zip(properties, values))) - def __str__(self): return "" % (self.ip, self.token) From ab662103bcd3ab8a9ee4385eadcec0bc7333b7ea Mon Sep 17 00:00:00 2001 From: Teemu R Date: Sat, 21 Oct 2017 16:15:14 +0200 Subject: [PATCH 2/2] remove unnused optional --- miio/plug_v1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miio/plug_v1.py b/miio/plug_v1.py index f48ba3b97..c3ead53ad 100644 --- a/miio/plug_v1.py +++ b/miio/plug_v1.py @@ -1,5 +1,5 @@ import logging -from typing import Dict, Any, Optional +from typing import Dict, Any from collections import defaultdict from .device import Device