mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-23 03:33:35 +00:00
Make cli interface more consistent (#232)
This commit is contained in:
parent
c65705bbbf
commit
e06b9a71e5
@ -1 +0,0 @@
|
|||||||
include_merge = False
|
|
@ -1,5 +0,0 @@
|
|||||||
python:
|
|
||||||
enabled: true
|
|
||||||
config_file: tox.ini
|
|
||||||
flake8:
|
|
||||||
enabled: true
|
|
72
kasa/cli.py
72
kasa/cli.py
@ -84,6 +84,8 @@ async def cli(ctx, host, alias, target, debug, bulb, plug, lightstrip, strip):
|
|||||||
else:
|
else:
|
||||||
click.echo("Unable to detect type, use --strip or --bulb or --plug!")
|
click.echo("Unable to detect type, use --strip or --bulb or --plug!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
await dev.update()
|
||||||
ctx.obj = dev
|
ctx.obj = dev
|
||||||
|
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
@ -106,6 +108,8 @@ async def scan(dev):
|
|||||||
for dev in devs:
|
for dev in devs:
|
||||||
click.echo(f"\t {dev}")
|
click.echo(f"\t {dev}")
|
||||||
|
|
||||||
|
return devs
|
||||||
|
|
||||||
|
|
||||||
@wifi.command()
|
@wifi.command()
|
||||||
@click.argument("ssid")
|
@click.argument("ssid")
|
||||||
@ -120,18 +124,7 @@ async def join(dev: SmartDevice, ssid, password, keytype):
|
|||||||
f"Response: {res} - if the device is not able to join the network, it will revert back to its previous state."
|
f"Response: {res} - if the device is not able to join the network, it will revert back to its previous state."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return res
|
||||||
@cli.command()
|
|
||||||
@click.option("--scrub/--no-scrub", default=True)
|
|
||||||
@click.pass_context
|
|
||||||
async def dump_discover(ctx, scrub):
|
|
||||||
"""Dump discovery information.
|
|
||||||
|
|
||||||
Useful for dumping into a file to be added to the test suite.
|
|
||||||
"""
|
|
||||||
click.echo(
|
|
||||||
"This is deprecated, use the script inside devtools to generate a devinfo file."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -158,17 +151,13 @@ async def discover(ctx, timeout, discover_only, dump_raw):
|
|||||||
|
|
||||||
async def find_host_from_alias(alias, target="255.255.255.255", timeout=1, attempts=3):
|
async def find_host_from_alias(alias, target="255.255.255.255", timeout=1, attempts=3):
|
||||||
"""Discover a device identified by its alias."""
|
"""Discover a device identified by its alias."""
|
||||||
click.echo(
|
|
||||||
f"Trying to discover {alias} using {attempts} attempts of {timeout} seconds"
|
|
||||||
)
|
|
||||||
for attempt in range(1, attempts):
|
for attempt in range(1, attempts):
|
||||||
click.echo(f"Attempt {attempt} of {attempts}")
|
|
||||||
found_devs = await Discover.discover(target=target, timeout=timeout)
|
found_devs = await Discover.discover(target=target, timeout=timeout)
|
||||||
found_devs = found_devs.items()
|
for ip, dev in found_devs.items():
|
||||||
for ip, dev in found_devs:
|
|
||||||
if dev.alias.lower() == alias.lower():
|
if dev.alias.lower() == alias.lower():
|
||||||
host = dev.host
|
host = dev.host
|
||||||
return host
|
return host
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@ -176,9 +165,9 @@ async def find_host_from_alias(alias, target="255.255.255.255", timeout=1, attem
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def sysinfo(dev):
|
async def sysinfo(dev):
|
||||||
"""Print out full system information."""
|
"""Print out full system information."""
|
||||||
await dev.update()
|
|
||||||
click.echo(click.style("== System info ==", bold=True))
|
click.echo(click.style("== System info ==", bold=True))
|
||||||
click.echo(pf(dev.sys_info))
|
click.echo(pf(dev.sys_info))
|
||||||
|
return dev.sys_info
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -186,7 +175,6 @@ async def sysinfo(dev):
|
|||||||
@click.pass_context
|
@click.pass_context
|
||||||
async def state(ctx, dev: SmartDevice):
|
async def state(ctx, dev: SmartDevice):
|
||||||
"""Print out device state and versions."""
|
"""Print out device state and versions."""
|
||||||
await dev.update()
|
|
||||||
click.echo(click.style(f"== {dev.alias} - {dev.model} ==", bold=True))
|
click.echo(click.style(f"== {dev.alias} - {dev.model} ==", bold=True))
|
||||||
click.echo(f"\tHost: {dev.host}")
|
click.echo(f"\tHost: {dev.host}")
|
||||||
click.echo(
|
click.echo(
|
||||||
@ -234,7 +222,6 @@ async def state(ctx, dev: SmartDevice):
|
|||||||
@click.option("--index", type=int)
|
@click.option("--index", type=int)
|
||||||
async def alias(dev, new_alias, index):
|
async def alias(dev, new_alias, index):
|
||||||
"""Get or set the device (or plug) alias."""
|
"""Get or set the device (or plug) alias."""
|
||||||
await dev.update()
|
|
||||||
if index is not None:
|
if index is not None:
|
||||||
if not dev.is_strip:
|
if not dev.is_strip:
|
||||||
click.echo("Index can only used for power strips!")
|
click.echo("Index can only used for power strips!")
|
||||||
@ -244,8 +231,8 @@ async def alias(dev, new_alias, index):
|
|||||||
|
|
||||||
if new_alias is not None:
|
if new_alias is not None:
|
||||||
click.echo(f"Setting alias to {new_alias}")
|
click.echo(f"Setting alias to {new_alias}")
|
||||||
click.echo(await dev.set_alias(new_alias))
|
res = await dev.set_alias(new_alias)
|
||||||
await dev.update()
|
return res
|
||||||
|
|
||||||
click.echo(f"Alias: {dev.alias}")
|
click.echo(f"Alias: {dev.alias}")
|
||||||
if dev.is_strip:
|
if dev.is_strip:
|
||||||
@ -264,9 +251,11 @@ async def raw_command(dev: SmartDevice, module, command, parameters):
|
|||||||
|
|
||||||
if parameters is not None:
|
if parameters is not None:
|
||||||
parameters = ast.literal_eval(parameters)
|
parameters = ast.literal_eval(parameters)
|
||||||
|
|
||||||
res = await dev._query_helper(module, command, parameters)
|
res = await dev._query_helper(module, command, parameters)
|
||||||
await dev.update() # TODO: is this needed?
|
|
||||||
click.echo(res)
|
click.echo(res)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -280,7 +269,6 @@ async def emeter(dev: SmartDevice, year, month, erase):
|
|||||||
Daily and monthly data provided in CSV format.
|
Daily and monthly data provided in CSV format.
|
||||||
"""
|
"""
|
||||||
click.echo(click.style("== Emeter ==", bold=True))
|
click.echo(click.style("== Emeter ==", bold=True))
|
||||||
await dev.update()
|
|
||||||
if not dev.has_emeter:
|
if not dev.has_emeter:
|
||||||
click.echo("Device has no emeter")
|
click.echo("Device has no emeter")
|
||||||
return
|
return
|
||||||
@ -324,15 +312,15 @@ async def emeter(dev: SmartDevice, year, month, erase):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def brightness(dev: SmartBulb, brightness: int, transition: int):
|
async def brightness(dev: SmartBulb, brightness: int, transition: int):
|
||||||
"""Get or set brightness."""
|
"""Get or set brightness."""
|
||||||
await dev.update()
|
|
||||||
if not dev.is_dimmable:
|
if not dev.is_dimmable:
|
||||||
click.echo("This device does not support brightness.")
|
click.echo("This device does not support brightness.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if brightness is None:
|
if brightness is None:
|
||||||
click.echo(f"Brightness: {dev.brightness}")
|
click.echo(f"Brightness: {dev.brightness}")
|
||||||
else:
|
else:
|
||||||
click.echo(f"Setting brightness to {brightness}")
|
click.echo(f"Setting brightness to {brightness}")
|
||||||
click.echo(await dev.set_brightness(brightness, transition=transition))
|
return await dev.set_brightness(brightness, transition=transition)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -343,10 +331,10 @@ async def brightness(dev: SmartBulb, brightness: int, transition: int):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def temperature(dev: SmartBulb, temperature: int, transition: int):
|
async def temperature(dev: SmartBulb, temperature: int, transition: int):
|
||||||
"""Get or set color temperature."""
|
"""Get or set color temperature."""
|
||||||
await dev.update()
|
|
||||||
if not dev.is_variable_color_temp:
|
if not dev.is_variable_color_temp:
|
||||||
click.echo("Device does not support color temperature")
|
click.echo("Device does not support color temperature")
|
||||||
return
|
return
|
||||||
|
|
||||||
if temperature is None:
|
if temperature is None:
|
||||||
click.echo(f"Color temperature: {dev.color_temp}")
|
click.echo(f"Color temperature: {dev.color_temp}")
|
||||||
valid_temperature_range = dev.valid_temperature_range
|
valid_temperature_range = dev.valid_temperature_range
|
||||||
@ -359,7 +347,7 @@ async def temperature(dev: SmartBulb, temperature: int, transition: int):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
click.echo(f"Setting color temperature to {temperature}")
|
click.echo(f"Setting color temperature to {temperature}")
|
||||||
await dev.set_color_temp(temperature, transition=transition)
|
return await dev.set_color_temp(temperature, transition=transition)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -370,15 +358,18 @@ async def temperature(dev: SmartBulb, temperature: int, transition: int):
|
|||||||
@click.pass_context
|
@click.pass_context
|
||||||
@pass_dev
|
@pass_dev
|
||||||
async def hsv(dev, ctx, h, s, v, transition):
|
async def hsv(dev, ctx, h, s, v, transition):
|
||||||
"""Get or set color in HSV. (Bulb only)."""
|
"""Get or set color in HSV."""
|
||||||
await dev.update()
|
if not dev.is_color:
|
||||||
|
click.echo("Device does not support colors")
|
||||||
|
return
|
||||||
|
|
||||||
if h is None or s is None or v is None:
|
if h is None or s is None or v is None:
|
||||||
click.echo(f"Current HSV: {dev.hsv}")
|
click.echo(f"Current HSV: {dev.hsv}")
|
||||||
elif s is None or v is None:
|
elif s is None or v is None:
|
||||||
raise click.BadArgumentUsage("Setting a color requires 3 values.", ctx)
|
raise click.BadArgumentUsage("Setting a color requires 3 values.", ctx)
|
||||||
else:
|
else:
|
||||||
click.echo(f"Setting HSV: {h} {s} {v}")
|
click.echo(f"Setting HSV: {h} {s} {v}")
|
||||||
click.echo(await dev.set_hsv(h, s, v, transition=transition))
|
return await dev.set_hsv(h, s, v, transition=transition)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -386,10 +377,9 @@ async def hsv(dev, ctx, h, s, v, transition):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def led(dev, state):
|
async def led(dev, state):
|
||||||
"""Get or set (Plug's) led state."""
|
"""Get or set (Plug's) led state."""
|
||||||
await dev.update()
|
|
||||||
if state is not None:
|
if state is not None:
|
||||||
click.echo(f"Turning led to {state}")
|
click.echo(f"Turning led to {state}")
|
||||||
click.echo(await dev.set_led(state))
|
return await dev.set_led(state)
|
||||||
else:
|
else:
|
||||||
click.echo(f"LED state: {dev.led}")
|
click.echo(f"LED state: {dev.led}")
|
||||||
|
|
||||||
@ -398,7 +388,9 @@ async def led(dev, state):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def time(dev):
|
async def time(dev):
|
||||||
"""Get the device time."""
|
"""Get the device time."""
|
||||||
click.echo(await dev.get_time())
|
res = await dev.get_time()
|
||||||
|
click.echo(f"Current time: {res}")
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -408,11 +400,11 @@ async def time(dev):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def on(dev: SmartDevice, index: int, name: str, transition: int):
|
async def on(dev: SmartDevice, index: int, name: str, transition: int):
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
await dev.update()
|
|
||||||
if index is not None or name is not None:
|
if index is not None or name is not None:
|
||||||
if not dev.is_strip:
|
if not dev.is_strip:
|
||||||
click.echo("Index and name are only for power strips!")
|
click.echo("Index and name are only for power strips!")
|
||||||
return
|
return
|
||||||
|
|
||||||
dev = cast(SmartStrip, dev)
|
dev = cast(SmartStrip, dev)
|
||||||
if index is not None:
|
if index is not None:
|
||||||
dev = dev.get_plug_by_index(index)
|
dev = dev.get_plug_by_index(index)
|
||||||
@ -420,7 +412,7 @@ async def on(dev: SmartDevice, index: int, name: str, transition: int):
|
|||||||
dev = dev.get_plug_by_name(name)
|
dev = dev.get_plug_by_name(name)
|
||||||
|
|
||||||
click.echo(f"Turning on {dev.alias}")
|
click.echo(f"Turning on {dev.alias}")
|
||||||
await dev.turn_on(transition=transition)
|
return await dev.turn_on(transition=transition)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -430,11 +422,11 @@ async def on(dev: SmartDevice, index: int, name: str, transition: int):
|
|||||||
@pass_dev
|
@pass_dev
|
||||||
async def off(dev: SmartDevice, index: int, name: str, transition: int):
|
async def off(dev: SmartDevice, index: int, name: str, transition: int):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
await dev.update()
|
|
||||||
if index is not None or name is not None:
|
if index is not None or name is not None:
|
||||||
if not dev.is_strip:
|
if not dev.is_strip:
|
||||||
click.echo("Index and name are only for power strips!")
|
click.echo("Index and name are only for power strips!")
|
||||||
return
|
return
|
||||||
|
|
||||||
dev = cast(SmartStrip, dev)
|
dev = cast(SmartStrip, dev)
|
||||||
if index is not None:
|
if index is not None:
|
||||||
dev = dev.get_plug_by_index(index)
|
dev = dev.get_plug_by_index(index)
|
||||||
@ -442,7 +434,7 @@ async def off(dev: SmartDevice, index: int, name: str, transition: int):
|
|||||||
dev = dev.get_plug_by_name(name)
|
dev = dev.get_plug_by_name(name)
|
||||||
|
|
||||||
click.echo(f"Turning off {dev.alias}")
|
click.echo(f"Turning off {dev.alias}")
|
||||||
await dev.turn_off(transition=transition)
|
return await dev.turn_off(transition=transition)
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@ -451,7 +443,7 @@ async def off(dev: SmartDevice, index: int, name: str, transition: int):
|
|||||||
async def reboot(plug, delay):
|
async def reboot(plug, delay):
|
||||||
"""Reboot the device."""
|
"""Reboot the device."""
|
||||||
click.echo("Rebooting the device..")
|
click.echo("Rebooting the device..")
|
||||||
click.echo(await plug.reboot(delay))
|
return await plug.reboot(delay)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user