From ec717762fcee6cb9472d7ac8ebfbaa60b7c980ea Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 21 Oct 2017 16:17:26 +0200 Subject: [PATCH] Device support of the Xioami Philips Smart LED Ball Lamp (#94) * Device support of the Xioami Philips Smart LED Ball Lamp. * Some glitches fixed. * Missing import added. * Line too long fixed. --- miio/__init__.py | 1 + miio/discovery.py | 6 +-- miio/philips_bulb.py | 92 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 miio/philips_bulb.py diff --git a/miio/__init__.py b/miio/__init__.py index 0fc881331..8afae63f2 100644 --- a/miio/__init__.py +++ b/miio/__init__.py @@ -10,6 +10,7 @@ from miio.waterpurifier import WaterPurifier from miio.strip import Strip from miio.ceil import Ceil +from miio.philips_bulb import PhilipsBulb from miio.philips_eyecare import PhilipsEyecare from miio.chuangmi_ir import ChuangmiIr from miio.fan import Fan diff --git a/miio/discovery.py b/miio/discovery.py index 59d0e2ac5..0f7c1b548 100644 --- a/miio/discovery.py +++ b/miio/discovery.py @@ -4,8 +4,8 @@ import inspect import codecs from . import (Device, Vacuum, Plug, PlugV1, Strip, AirPurifier, Ceil, - PhilipsEyecare, ChuangmiIr, AirHumidifier, WaterPurifier, - WifiSpeaker, Yeelight) + PhilipsBulb, PhilipsEyecare, ChuangmiIr, AirHumidifier, + WaterPurifier, WifiSpeaker, Yeelight) from typing import Union, Callable, Dict, Optional # noqa: F401 @@ -29,7 +29,7 @@ "zhimi-humidifier-v1": AirHumidifier, "yunmi-waterpuri-v2": WaterPurifier, # It looks like philips devices cannot be discovered via mdns - "philips-light-bulb": Ceil, + "philips-light-bulb": PhilipsBulb, "philips-light-ceil": Ceil, "philips-light-sread1": PhilipsEyecare, "xiaomi-wifispeaker-v1": WifiSpeaker, # name needs to be checked diff --git a/miio/philips_bulb.py b/miio/philips_bulb.py new file mode 100644 index 000000000..1ddc5f39e --- /dev/null +++ b/miio/philips_bulb.py @@ -0,0 +1,92 @@ +import logging +from .device import Device +from typing import Any, Dict +from collections import defaultdict + +_LOGGER = logging.getLogger(__name__) + + +class PhilipsBulbStatus: + """Container for status reports from Xiaomi Philips LED Ceiling Lamp""" + + def __init__(self, data: Dict[str, Any]) -> None: + # ['power': 'on', 'bright': 85, 'cct': 9, 'snm': 0, 'dv': 0] + self.data = data + + @property + def power(self) -> str: + return self.data["power"] + + @property + def is_on(self) -> bool: + return self.power == "on" + + @property + def brightness(self) -> int: + return self.data["bright"] + + @property + def color_temperature(self) -> int: + return self.data["cct"] + + @property + def scene(self) -> int: + return self.data["snm"] + + @property + def delay_off_countdown(self) -> int: + return self.data["dv"] + + def __str__(self) -> str: + s = "" % \ + (self.power, self.brightness, + self.color_temperature, self.scene, self.delay_off_countdown) + return s + + +class PhilipsBulb(Device): + """Main class representing Xiaomi Philips LED Ball Lamp.""" + + def on(self): + """Power on.""" + return self.send("set_power", ["on"]) + + def off(self): + """Power off.""" + return self.send("set_power", ["off"]) + + def set_brightness(self, level: int): + """Set brightness level.""" + return self.send("set_bright", [level]) + + def set_color_temperature(self, level: int): + """Set Correlated Color Temperature.""" + return self.send("set_cct", [level]) + + def delay_off(self, seconds: int): + """Set delay off seconds.""" + return self.send("delay_off", [seconds]) + + def set_scene(self, num: int): + """Set scene number.""" + return self.send("apply_fixed_scene", [num]) + + def status(self) -> PhilipsBulbStatus: + """Retrieve properties.""" + properties = ['power', 'bright', 'cct', 'snm', 'dv', ] + 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 PhilipsBulbStatus( + defaultdict(lambda: None, zip(properties, values)))