-
-
Notifications
You must be signed in to change notification settings - Fork 568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for Xiaomi Philips Eyecare Smart Lamp 2 #34
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
from .device import Device | ||
from typing import Any, Dict | ||
import enum | ||
|
||
class PhilipsEyecare(Device): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
"""Main class representing Xiaomi Philips Eyecare Smart Lamp 2.""" | ||
|
||
def on(self): | ||
"""Power on.""" | ||
return self.send("set_power", ["on"]) | ||
|
||
def off(self): | ||
"""Power off.""" | ||
return self.send("set_power", ["off"]) | ||
|
||
def eyecare_on(self): | ||
"""Eyecare on.""" | ||
return self.send("set_eyecare", ["on"]) | ||
|
||
def eyecare_off(self): | ||
"""Eyecare off.""" | ||
return self.send("set_eyecare", ["off"]) | ||
|
||
def set_bright(self, level: int): | ||
"""Set brightness level.""" | ||
return self.send("set_bright", [level]) | ||
|
||
def set_user_scene(self, num: int): | ||
"""Set eyecare user scene.""" | ||
return self.send("set_user_scene", [num]) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
def delay_off(self, minutes: int): | ||
"""Set delay off minutes.""" | ||
return self.send("delay_off", [minutes]) | ||
|
||
def bl_on(self): | ||
"""Night Light On.""" | ||
return self.send("enable_bl", ["on"]) | ||
|
||
def bl_off(self): | ||
"""Night Light Off.""" | ||
return self.send("enable_bl", ["off"]) | ||
|
||
def notify_user_on(self): | ||
"""Notify User On.""" | ||
return self.send("set_notifyuser", ["on"]) | ||
|
||
def notify_user_off(self): | ||
"""Notify USer Off.""" | ||
return self.send("set_notifyuser", ["off"]) | ||
|
||
def amb_on(self): | ||
"""Amblient Light On.""" | ||
return self.send("enable_amb", ["on"]) | ||
|
||
def amb_off(self): | ||
"""Ambient Light Off.""" | ||
return self.send("enable_amb", ["off"]) | ||
|
||
def set_amb_bright(self, level: int): | ||
"""Set Ambient Light brightness level.""" | ||
return self.send("set_amb_bright", [level]) | ||
|
||
def status(self): | ||
"""Retrieve properties.""" | ||
properties = ['power', 'bright', 'notifystatus', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
'ambstatus', 'ambvalue', 'eyecare', 'scene_num', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line under-indented for visual indent |
||
'bls', 'dvalue',] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. continuation line under-indented for visual indent |
||
values = self.send( | ||
"get_prop", | ||
properties | ||
) | ||
return PhilipsEyecareStatus(dict(zip(properties, values))) | ||
|
||
class PhilipsEyecareStatus: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
"""Container for status reports from Xiaomi Philips Eyecare Smart Lamp 2""" | ||
|
||
def __init__(self, data: Dict[str, Any]) -> None: | ||
# ["power","bright","notifystatus","ambstatus","ambvalue","eyecare", | ||
# "scene_num","bls","dvalue"]} | ||
# ["off",5,"off","off",41,"on",3,"on",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 bright(self) -> int: | ||
return self.data["bright"] | ||
|
||
@property | ||
def notifystatus(self) -> str: | ||
return self.data["notifystatus"] | ||
|
||
@property | ||
def ambstatus(self) -> str: | ||
return self.data["ambstatus"] | ||
|
||
@property | ||
def ambvalue(self) -> int: | ||
return self.data["ambvalue"] | ||
|
||
@property | ||
def eyecare(self) -> str: | ||
return self.data["eyecare"] | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
@property | ||
def scene_num(self) -> str: | ||
return self.data["scene_num"] | ||
|
||
@property | ||
def bls(self) -> str: | ||
return self.data["bls"] | ||
|
||
@property | ||
def dvalue(self) -> int: | ||
return self.data["dvalue"] | ||
|
||
|
||
def __str__(self) -> str: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too many blank lines (2) |
||
s = "<PhilipsEyecareStatus power=%s, bright=%s, " \ | ||
"notifystatus=%s, ambstatus=%s, ambvalue=%s, " \ | ||
"eyecare=%s, scene_num=%s, bls=%s, " \ | ||
"dvalue=%s >" % \ | ||
(self.power, self.bright, | ||
self.notifystatus, self.ambstatus, self.ambvalue, | ||
self.eyecare, self.scene_num, | ||
self.bls) | ||
return s |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
# -*- coding: UTF-8 -*- | ||
import logging | ||
import click | ||
import ast | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'ast' imported but unused |
||
import sys | ||
import ipaddress | ||
|
||
if sys.version_info < (3, 4): | ||
print("To use this script you need python 3.4 or newer, got %s" % | ||
sys.version_info) | ||
sys.exit(1) | ||
|
||
import mirobo # noqa: E402 | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
pass_dev = click.make_pass_decorator(mirobo.PhilipsEyecare) | ||
|
||
def validate_bright(ctx, param, value): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
value = int(value) | ||
if value < 1 or value > 100: | ||
raise click.BadParameter('Should be a positive int between 1-100.') | ||
return value | ||
|
||
|
||
def validate_minutes(ctx, param, value): | ||
value = int(value) | ||
if value < 0 or value > 60: | ||
raise click.BadParameter('Should be a positive int between 1-60.') | ||
return value | ||
|
||
|
||
def validate_scene(ctx, param, value): | ||
value = int(value) | ||
if value < 1 or value > 3: | ||
raise click.BadParameter('Should be a positive int between 1-3.') | ||
return value | ||
|
||
|
||
def validate_ip(ctx, param, value): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
try: | ||
ipaddress.ip_address(value) | ||
return value | ||
except ValueError as ex: | ||
raise click.BadParameter("Invalid IP: %s" % ex) | ||
|
||
|
||
def validate_token(ctx, param, value): | ||
token_len = len(value) | ||
if token_len != 32: | ||
raise click.BadParameter("Token length != 32 chars: %s" % token_len) | ||
return value | ||
|
||
|
||
@click.group(invoke_without_command=True) | ||
@click.option('--ip', envvar="DEVICE_IP", callback=validate_ip) | ||
@click.option('--token', envvar="DEVICE_TOKEN", callback=validate_token) | ||
@click.option('-d', '--debug', default=False, count=True) | ||
@click.pass_context | ||
def cli(ctx, ip: str, token: str, debug: int): | ||
"""A tool to command Xiaomi Philips Eyecare Smart Lamp 2.""" | ||
|
||
if debug: | ||
logging.basicConfig(level=logging.DEBUG) | ||
_LOGGER.info("Debug mode active") | ||
else: | ||
logging.basicConfig(level=logging.INFO) | ||
|
||
# if we are scanning, we do not try to connect. | ||
if ctx.invoked_subcommand == "discover": | ||
return | ||
|
||
if ip is None or token is None: | ||
click.echo("You have to give ip and token!") | ||
sys.exit(-1) | ||
|
||
dev = mirobo.PhilipsEyecare(ip, token, debug) | ||
_LOGGER.debug("Connecting to %s with token %s", ip, token) | ||
|
||
ctx.obj = dev | ||
|
||
if ctx.invoked_subcommand is None: | ||
ctx.invoke(status) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
def discover(): | ||
"""Search for plugs in the network.""" | ||
mirobo.PhilipsEyecare.discover() | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def status(dev: mirobo.PhilipsEyecare): | ||
"""Returns the state information.""" | ||
res = dev.status() | ||
if not res: | ||
return # bail out | ||
|
||
click.echo(click.style("Power: %s" % res.power, bold=True)) | ||
click.echo("Brightness: %s" % res.bright) | ||
click.echo("Eye Fatigue Reminder: %s" % res.notifystatus) | ||
click.echo("Ambient Light: %s" % res.ambstatus) | ||
click.echo("Ambient Light Brightness: %s" % res.ambvalue) | ||
click.echo("Eyecare Mode: %s" % res.eyecare) | ||
click.echo("Eyecare Scene: %s" % res.scene_num) | ||
click.echo("Night Light: %s " % res.bls) | ||
click.echo("Delay Off: %s minutes" % res.dvalue) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def on(dev: mirobo.PhilipsEyecare): | ||
"""Power on.""" | ||
click.echo("Power on: %s" % dev.on()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def off(dev: mirobo.PhilipsEyecare): | ||
"""Power off.""" | ||
click.echo("Power off: %s" % dev.off()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@click.argument('level', callback=validate_bright, required=True,) | ||
@pass_dev | ||
def set_bright(dev: mirobo.PhilipsEyecare, level): | ||
"""Set brightness level.""" | ||
click.echo("Brightness: %s" % dev.set_bright(level)) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@click.argument('scene', callback=validate_scene, required=True,) | ||
@pass_dev | ||
def set_scene(dev: mirobo.PhilipsEyecare, scene): | ||
"""Set eyecare scene number.""" | ||
click.echo("Eyecare Scene: %s" % dev.set_user_scene(scene)) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@click.argument('minutes', callback=validate_minutes, required=True,) | ||
@pass_dev | ||
def delay_off(dev: mirobo.PhilipsEyecare, minutes): | ||
"""Set delay off in minutes.""" | ||
click.echo("Delay off: %s" % dev.delay_off(minutes)) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def bl_on(dev: mirobo.PhilipsEyecare): | ||
"""Night Light on.""" | ||
click.echo("Night Light On: %s" % dev.bl_on()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def bl_off(dev: mirobo.PhilipsEyecare): | ||
"""Night Light off.""" | ||
click.echo("Night Light off: %s" % dev.bl_off()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def notify_on(dev: mirobo.PhilipsEyecare): | ||
"""Eye Fatigue Reminder On.""" | ||
click.echo("Eye Fatigue Reminder On: %s" % dev.notify_user_on()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def notify_off(dev: mirobo.PhilipsEyecare): | ||
"""Eye Fatigue Reminder off.""" | ||
click.echo("Eye Fatigue Reminder Off: %s" % dev.notify_user_off()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def ambient_on(dev: mirobo.PhilipsEyecare): | ||
"""Ambient Light on.""" | ||
click.echo("Ambient Light On: %s" % dev.amb_on()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@pass_dev | ||
def ambient_off(dev: mirobo.PhilipsEyecare): | ||
"""Ambient Light off.""" | ||
click.echo("Ambient Light Off: %s" % dev.amb_off()) | ||
|
||
|
||
@cli.command() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
@click.argument('level', callback=validate_bright, required=True,) | ||
@pass_dev | ||
def set_amb_bright(dev: mirobo.PhilipsEyecare, level): | ||
"""Set Ambient Light brightness level.""" | ||
click.echo("Ambient Light Brightness: %s" % dev.set_amb_bright(level)) | ||
|
||
|
||
if __name__ == "__main__": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines after class or function definition, found 1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines after class or function definition, found 1 |
||
cli() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'enum' imported but unused