Skip to content

Commit

Permalink
Extend yeelight support
Browse files Browse the repository at this point in the history
Adds more functionality and allows yeelights to be discovered.
* set_developer_mode(bool) allows enabling and disabling the developer mode (necessary for python-yeelight etc.)
* set_name(str) to set the internal name, note that this is not the same as shown in mobile apps
* set_save_state_on_change(bool) to enable saving the current bulb state when doing modifications
  • Loading branch information
rytilahti committed Oct 1, 2017
1 parent 82f38b8 commit 4eea494
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
1 change: 1 addition & 0 deletions mirobo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from mirobo.strip import Strip
from mirobo.ceil import Ceil
from mirobo.philips_eyecare import PhilipsEyecare
from mirobo.yeelight import Yeelight
from mirobo.chuangmi_ir import ChuangmiIr
from mirobo.fan import Fan
from mirobo.device import Device, DeviceException
Expand Down
6 changes: 3 additions & 3 deletions mirobo/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import inspect
import codecs
from . import (Device, Vacuum, Plug, PlugV1, Strip, AirPurifier, Ceil,
PhilipsEyecare, ChuangmiIr, AirHumidifier, WaterPurifier)
PhilipsEyecare, ChuangmiIr, AirHumidifier, WaterPurifier,
Yeelight)
from typing import Union, Callable, Dict, Optional # noqa: F401


Expand All @@ -31,8 +32,7 @@
"philips-light-bulb": Ceil,
"philips-light-ceil": Ceil,
"philips-light-sread1": PhilipsEyecare,
"yeelink-light-": lambda x: other_package_info(
x, "python-yeelight package"),
"yeelink-light-": Yeelight,
"lumi-gateway-": lambda x: other_package_info(
x, "https://github.com/Danielhiversen/PyXiaomiGateway")
} # type: Dict[str, Union[Callable, Device]]
Expand Down
55 changes: 50 additions & 5 deletions mirobo/yeelight.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .device import Device
from typing import Tuple, Optional
from enum import IntEnum
import warnings


class YeelightMode(IntEnum):
Expand All @@ -15,14 +16,17 @@ def __init__(self, data):

@property
def is_on(self) -> bool:
"""Return whether the bulb is on or off."""
return self.data["power"] == "on"

@property
def brightness(self) -> int:
"""Return current brightness."""
return int(self.data["bright"])

@property
def rgb(self) -> Optional[Tuple[int, int, int]]:
"""Return color in RGB if RGB mode is active."""
if self.color_mode == YeelightMode.RGB:
rgb = self.data["rgb"]
blue = rgb & 0xff
Expand All @@ -33,33 +37,49 @@ def rgb(self) -> Optional[Tuple[int, int, int]]:

@property
def color_mode(self) -> YeelightMode:
"""Return current color mode."""
return YeelightMode(int(self.data["color_mode"]))

@property
def hsv(self) -> Optional[Tuple[int, int, int]]:
"""Return current color in HSV if HSV mode is active."""
if self.color_mode == YeelightMode.HSV:
return self.data["hue"], self.data["sat"], self.data["bright"]
return None

@property
def color_temp(self) -> Optional[int]:
"""Return current color temperature, if applicable."""
if self.color_mode == YeelightMode.ColorTemperature:
return int(self.data["ct"])
return None

@property
def developer_mode(self) -> bool:
"""Return whether the developer mode is active."""
return bool(int(self.data["lan_ctrl"]))

@property
def save_state_on_change(self) -> bool:
"""Return whether the bulb state is saved on change."""
return bool(int(self.data["save_state"]))

@property
def name(self) -> str:
"""Return the internal name of the bulb."""
return self.data["name"]

def __repr__(self):
s = "<Yeelight on=%s mode=%s brightness=%s color_temp=%s " \
"rgb=%s hsv=%s name=%s>" % \
"rgb=%s hsv=%s dev=%s save_state=%s name=%s>" % \
(self.is_on,
self.color_mode,
self.brightness,
self.color_temp,
self.rgb,
self.hsv,
self.developer_mode,
self.save_state_on_change,
self.name)
return s

Expand All @@ -78,6 +98,11 @@ class Yeelight(Device):

SUPPORTED = ['yeelink-light-color1', 'yeelink-light-mono1']

def __init__(self, *args, **kwargs):
warnings.warn("Please consider using python-yeelight "
"for more complete support.", stacklevel=2)
super().__init__(*args, **kwargs)

def on(self):
"""Power on."""
return self.send("set_power", ["on"])
Expand All @@ -87,27 +112,45 @@ def off(self):
return self.send("set_power", ["off"])

def set_brightness(self, bright):
"""Set brightness."""
return self.send("set_bright", [bright])

def set_color_temp(self, ct):
"""Set color temp in kelvin."""
return self.send("set_ct_abx", [ct, "smooth", 500])

def set_rgb(self, rgb):
"""Set color in encoded RGB."""
return self.send("set_rgb", [rgb])

def set_hsv(self, hsv):
"""Set color in HSV."""
return self.send("set_hsv", [hsv])

def set_developer_mode(self, enable: bool) -> bool:
"""Enable or disable the developer mode."""
return self.send("set_ps", ["cfg_lan_ctrl", str(int(enable))])

def set_save_state(self, enable: bool) -> bool:
"""Enable or disable saving the state on changes."""
return self.send("set_ps", ["cfg_save_state"], str(int(enable)))

def set_name(self, name: str) -> bool:
"""Set an internal name for the bulb."""
return self.send("set_name", [name])

def toggle(self):
"""Toggles bulb state."""
"""Toggle bulb state."""
return self.send("toggle")

def set_default(self):
"""Sets current state as default."""
"""Set current state as default."""
return self.send("set_default")

def set_scene(self, scene, *vals):
return self.send("set_scene", [scene, *vals])
"""Set the scene."""
raise NotImplementedError("Setting the scene is not implemented yet.")
# return self.send("set_scene", [scene, *vals])

def status(self):
"""Retrieve properties."""
Expand All @@ -119,7 +162,9 @@ def status(self):
"hue",
"sat",
"color_mode",
"name"
"name",
"lan_ctrl",
"save_state"
]

values = self.send(
Expand Down

0 comments on commit 4eea494

Please sign in to comment.