Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python
import asyncio
import json
import re
import sys

from twinkly_client import TwinklyClient


async def twinkly_wrapper(host, calls):
c = TwinklyClient(host)
response = {}
for func_name, args, kwargs in calls:
try:
f = getattr(c, func_name)
except AttributeError:
print(f"No such function: {func_name}")
exit(1)
response[func_name] = await f(*args, **kwargs)
await c._session.close()
return response


def main():
commands = {
"get_mode": "",
"set_mode": "off|color|movie|effect|rt|demo",
"get_brightness": "",
"set_brightness": "1-100",
"get_color": "",
"set_color": "hue=0-360,saturation=0-255,value=0-255,red=0-255,green=0-255,blue=0-255,white=0-255",
"get_device_info": "",
}
args = sys.argv[1:]

if not args or args[0] == "-h":
print("Usage: cli.py <host> [<func_name>(:arg1,kwarg=7),...]")
print("Available functions:")
for cmd, cmd_args in commands.items():
print(f"{cmd}:{cmd_args}")
print(
"\nExample: cli.py 192.168.0.123 get_mode set_mode:color set_color:red=5,blue=10,green=255 "
"set_brightness:50 get_brightness"
)
exit(0)

host = args.pop(0)

calls = []
args_matches = re.findall("(\w+):?([\w=,]+)?", " ".join(args))
for cmd, cmd_args in args_matches:
if cmd not in commands:
continue
call_args = []
call_kwargs = {}
if cmd_args:
for cmd_arg in cmd_args.split(","):
if "=" in cmd_arg:
k, v = cmd_arg.split("=")
call_kwargs[k] = int(v) if v.isdigit() else v
else:
call_args.append(int(cmd_arg) if cmd_arg.isdigit() else cmd_arg)
calls.append((cmd, call_args, call_kwargs))

print(json.dumps(asyncio.run(twinkly_wrapper(host, calls))))


if __name__ == "__main__":
main()
41 changes: 40 additions & 1 deletion twinkly_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .const import (
EP_BRIGHTNESS,
EP_COLOR,
EP_DEVICE_INFO,
EP_LOGIN,
EP_MODE,
Expand Down Expand Up @@ -45,12 +46,20 @@ async def get_device_info(self) -> Any:

async def get_is_on(self) -> bool:
"""Get a boolean which indicates the current state of the device."""
return (await self.__send_request(EP_MODE))["mode"] != "off"
return await self.get_mode() != "off"

async def set_is_on(self, is_on: bool) -> None:
"""Turn the device on / off."""
await self.__send_request(EP_MODE, {"mode": "movie" if is_on else "off"})

async def get_mode(self) -> str:
"""Get the current mode of the device (off,color,demo,effect,movie,playlist,rt)."""
return (await self.__send_request(EP_MODE))["mode"]

async def set_mode(self, mode: str) -> None:
"""Set the device mode (off,color,demo,effect,movie,playlist,rt)"""
await self.__send_request(EP_MODE, {"mode": mode})

async def get_brightness(self) -> int:
"""Get the current brightness of the device, between 0 and 100."""
brightness = await self.__send_request(EP_BRIGHTNESS)
Expand All @@ -60,6 +69,36 @@ async def set_brightness(self, brightness: int) -> None:
"""Set the brightness of the device."""
await self.__send_request(EP_BRIGHTNESS, {"value": brightness, "type": "A"})

async def get_color(self) -> dict:
"""Get the current color, dict of h,s,v,r,g,b,w ints"""
response_data = await self.__send_request(EP_COLOR)
return response_data

async def set_color(
self,
hue: int = None,
saturation: int = None,
value: int = None,
red: int = None,
green: int = None,
blue: int = None,
white: int = None
) -> None:
"""Set the color of the device."""
# Only include set keys
payload = {
k: v for k, v in {
"hue": hue,
"saturation": saturation,
"value": value,
"red": red,
"green": green,
"blue": blue,
"white": white
}.items() if v is not None
}
await self.__send_request(EP_COLOR, payload)

async def __send_request(
self, endpoint: str, data: Any = None, retry: int = 1
) -> Any:
Expand Down
1 change: 1 addition & 0 deletions twinkly_client/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
EP_DEVICE_INFO = "gestalt"
EP_MODE = "led/mode"
EP_BRIGHTNESS = "led/out/brightness"
EP_COLOR = "led/color"
EP_LOGIN = "login"
EP_VERIFY = "verify"

Expand Down