Controlling Apple TV with pyatv#

pyatv is an open-source tool (MIT license) for controlling Apple TV devices over the network. It uses AirPlay and other network protocols supported by the Apple TV. The most relevant features for us are: Listing the installed apps, launching an app, and sending text to the on-screen keyboard.

You can always do these actions by using stbt.press to navigate the relevant AppleTV screens, but pyatv is much faster because it doesn’t require navigation:

Action

Stb-tester

pyatv

Launch an app

Navigate the AppleTV home grid

Send the command over the network

Enter text

Navigate the on-screen keyboard

Send the entire text over the network

Using pyatv is optional. For the standard remote-control configuration see Device Configuration: Apple TV.

Usage#

Stb-tester provides a pytest fixture called appletv_pyatv. To use it, pass it as an argument to your test-case function, like this:

import pyatv

def test_my_app(appletv_pyatv: pyatv.interface.AppleTV):
    ...

By “injecting” the fixture like this into your test, Stb-tester will automatically create an instance of the pyatv.interface.AppleTV class, and will pair it with your AppleTV device automatically (if it isn’t already paired).

pyatv’s API is all async, so to use it you need to call its functions from an asyncio event loop, like this:

import asyncio
import pyatv

def test_my_app(appletv_pyatv: pyatv.interface.AppleTV):
    # 1. Launch the app
    asyncio.get_event_loop().run_until_complete(
        appletv_pyatv.apps.launch_app("com.google.ios.youtube"))

    # 2. Navigate to search keyboard
    # ...implementation using `stbt.press()` etc not shown...

    # 3. Enter the search text
    asyncio.get_event_loop().run_until_complete(
        appletv_pyatv.keyboard.text_set("Really really long programme title"))

In future, we may implement a more convenient API for the most common pyatv functions.

Note

We have done the “integration” work to make pyatv work on the Stb-tester Node (solving the usual challenges of Python packaging and dependency management) but we are not the authors of pyatv, and we don’t provide support for bugs in pyatv itself.

Pairing#

By using our appletv_pyatv fixture in your test-case function, Stb-tester will automatically pair the AppleTV with the Stb-tester Node (if it isn’t already paired). The pairing credentials are stored on the Stb-tester Node, so it should only need to pair once.

If, for any reason, you want to un-pair the Stb-tester Node from the AppleTV, you can do so by going to Settings > Remotes and Devices > Remote App and Devices on the AppleTV.

_images/Settings.png

Configuration#

IP address#

Stb-tester needs to know the IP address of the AppleTV, so you need to specify it in the appropriate configuration file for each Stb-tester Node (see Node-specific configuration files). For example:

config/test-farm/stb-tester-00044b5af1d3.conf#
[device_under_test]
ip_address = 192.168.84.101

You can find the IP address of your AppleTV by going to Settings > Network on the AppleTV.

The Stb-tester Node needs to be on the same network as the AppleTV.

Apple TV settings#

To help Stb-tester detect the Pairing PIN when it appears on screen, you need to configure the Apple TV settings documented in Device Configuration: Apple TV.

Installation#

  1. In your test-pack git repository, create the file config/setup/setup (if it doesn’t exist already) with the following contents:

    #!/bin/bash -ex
    
    # pyatv dependencies:
    sudo apt-get update
    sudo apt-get install -y \
        python3-aiohttp \
        python3-idna \
        python3-mediafile \
        python3-protobuf \
        python3-pydantic \
        python3-tabulate \
        python3-zeroconf
    
  2. Commit the file to git.

See Customising the test-run environment to learn more about this setup script.

In the next Stb-tester release (v35) these dependencies will be installed already. For now we can’t add them to the v34 container unconditionally because those new dependencies might conflict with other versions installed by customers with custom setup scripts of their own.