diff --git a/kasa/cli.py b/kasa/cli.py index d2ac9589..47f53d18 100755 --- a/kasa/cli.py +++ b/kasa/cli.py @@ -613,6 +613,32 @@ async def off(dev: SmartDevice, index: int, name: str, transition: int): return await dev.turn_off(transition=transition) +@cli.command() +@click.option("--index", type=int, required=False) +@click.option("--name", type=str, required=False) +@click.option("--transition", type=int, required=False) +@pass_dev +async def toggle(dev: SmartDevice, index: int, name: str, transition: int): + """Toggle the device on/off.""" + if index is not None or name is not None: + if not dev.is_strip: + echo("Index and name are only for power strips!") + return + + dev = cast(SmartStrip, dev) + if index is not None: + dev = dev.get_plug_by_index(index) + elif name: + dev = dev.get_plug_by_name(name) + + if dev.is_on: + echo(f"Turning off {dev.alias}") + return await dev.turn_off(transition=transition) + + echo(f"Turning on {dev.alias}") + return await dev.turn_on(transition=transition) + + @cli.command() @click.option("--delay", default=1) @pass_dev diff --git a/kasa/tests/test_cli.py b/kasa/tests/test_cli.py index 953c3bd4..f7e04619 100644 --- a/kasa/tests/test_cli.py +++ b/kasa/tests/test_cli.py @@ -5,7 +5,7 @@ import pytest from asyncclick.testing import CliRunner from kasa import SmartDevice -from kasa.cli import alias, brightness, cli, emeter, raw_command, state, sysinfo +from kasa.cli import alias, brightness, cli, emeter, raw_command, state, sysinfo, toggle from .conftest import handle_turn_on, turn_on @@ -30,6 +30,18 @@ async def test_state(dev, turn_on): assert "Device state: False" in res.output +@turn_on +async def test_toggle(dev, turn_on, mocker): + await handle_turn_on(dev, turn_on) + runner = CliRunner() + await runner.invoke(toggle, obj=dev) + + if turn_on: + assert not dev.is_on + else: + assert dev.is_on + + async def test_alias(dev): runner = CliRunner()