Skip to content
Open
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
5 changes: 5 additions & 0 deletions docs/documentation/atvscript.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ $ atvscript -s 10.0.10.81 menu
{"result": "success", "datetime": "2020-04-06T18:51:04.758569+02:00", "command": "menu"}
```

`volume_up` and `volume_down` use the {% include api i="interface.Audio" %}
interface. `turn_on` and `turn_off` are also supported through
{% include api i="interface.Power" %}. These commands return the same success
output as remote control buttons.

## Push, Power, Audio and Keyboard Updates

Push, power, audio and keyboard updates are printed to the terminal as they happen:
Expand Down
8 changes: 8 additions & 0 deletions pyatv/scripts/atvscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ async def _run_command(atv, args, abort_sem, loop):
await wait_for_input(loop, abort_sem)
return output(True, values={"push_updates": "finished"})

if args.command in ("volume_up", "volume_down"):
await getattr(atv.audio, args.command)()
return output(True, values={"command": args.command})

if args.command in ("turn_on", "turn_off"):
await getattr(atv.power, args.command)()
return output(True, values={"command": args.command})

if args.command in retrieve_commands(RemoteControl):
await getattr(atv.remote_control, args.command)()
return output(True, values={"command": args.command})
Expand Down
36 changes: 36 additions & 0 deletions tests/scripts/test_atvscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import json
import logging
from types import SimpleNamespace
from unittest.mock import AsyncMock

from deepdiff import DeepDiff
import pytest

from pyatv.const import Protocol
from pyatv.scripts import atvscript

from tests.scripts.conftest import AIRPLAY_ID, DMAP_ID, IP_1, IP_2, MRP_ID

Expand Down Expand Up @@ -107,3 +110,36 @@ async def test_mrp_idle(scriptenv):
},
)
assert exit_code == 0


@pytest.mark.parametrize(
"command,interface",
[
("volume_up", "audio"),
("volume_down", "audio"),
("turn_on", "power"),
("turn_off", "power"),
("play", "remote_control"),
],
)
async def test_command_interface(command, interface):
atv = SimpleNamespace(
audio=AsyncMock(), power=AsyncMock(), remote_control=AsyncMock()
)
result = await atvscript._run_command(
atv, SimpleNamespace(command=command), None, None
)
assert_json_output(json.dumps(result), {"result": "success", "command": command})
getattr(getattr(atv, interface), command).assert_awaited_once_with()
if interface != "remote_control":
getattr(atv.remote_control, command).assert_not_awaited()


@pytest.mark.parametrize("command", ["volume", "set_volume", "power_state", "unknown"])
async def test_unsupported_command(command):
result = await atvscript._run_command(
SimpleNamespace(), SimpleNamespace(command=command), None, None
)
assert_json_output(
json.dumps(result), {"result": "failure", "error": "unsupported_command"}
)