androidtv Documentation

ADB Setup

This package works by sending ADB commands to your Android TV / Fire TV device. There are two ways to accomplish this.

1. ADB Server

androidtv can use a running ADB server to send ADB commands (credit: pure-python-adb). More info about ADB can be found here: Android Debug Bridge (adb). There are 3 main ways to setup an ADB server.

Note

The ADB server must be connected to your device(s) before starting Home Assistant. Otherwise, the components will not be setup.

1a) Hass.io ADB Addon

For Hass.io users, this is the easiest option. Information about the addon can be found here: Community Hass.io Add-ons: Android Debug Bridge. The configuration for the addon will look like:

{
  "log_level": "info",
  "devices": [
    "192.168.0.111",
    "192.168.0.222"
  ],
  "reconnect_timeout": 90,
  "keys_path": "/config/.android"
}

Your Home Assistant configuration will look like:

media_player:
- platform: androidtv
  name: Android TV 1
  host: 192.168.0.111
  adb_server_ip: 127.0.0.1

media_player:
- platform: androidtv
  name: Android TV 2
  host: 192.168.0.222
  adb_server_ip: 127.0.0.1

1b) Docker Container

Since Home Assistant isn’t able to start the connection with the Android device directly, the ADB Server must do it instead. The ADB Server must already be connected to the Android device when Home Assistant attempts to access the ADB Server, or else Home Assistant will be unable to set up the Android device.

A modified script provided on the Home Assistant forums (source) demonstrates an example startup script for a Docker container that will automatically attempt, and continue to connect to a device when run:

startup.sh
#!/bin/sh

# for a single device, use: DEVICES=("192.168.0.111")
DEVICES=("192.168.0.111" "192.168.0.222")

echo "Starting up ADB..."

while true; do
  adb -a server nodaemon > /dev/null 2>&1
  sleep 10
done &

echo "Server started. Waiting for 30 seconds..."
sleep 30

echo "Connecting to devices."
for device in ${DEVICES[@]}; do
   adb connect $device
done
echo "Done."

while true; do
  for device in ${DEVICES[@]}; do
    adb connect $device > /dev/null 2>&1
  done
  sleep 60
done

Assuming the address of the ADB server is 192.168.0.101, your Home Assistant configuration will look like:

media_player:
- platform: androidtv
  name: Android TV 1
  host: 192.168.0.111
  adb_server_ip: 192.168.0.101

media_player:
- platform: androidtv
  name: Android TV 2
  host: 192.168.0.222
  adb_server_ip: 192.168.0.101

1c) Linux Service

TODO

Your Home Assistant configuration will look like:

media_player:
- platform: androidtv
  name: Android TV 1
  host: 192.168.0.111
  adb_server_ip: 127.0.0.1

media_player:
- platform: androidtv
  name: Android TV 2
  host: 192.168.0.222
  adb_server_ip: 127.0.0.1

2. Python ADB Implementation

The second way that androidtv can communicate with devices is using the Python ADB implementation (credit: python-adb).

If your device requires ADB authentication, you will need to follow the instructions in the “ADB Authentication” section below. Once you have an authenticated key, this approach does not require any additional setup or addons. However, users with newer devices may find that the ADB connection is unstable. For a Fire TV device, you can try setting the get_sources configuration option to false. If the problem cannot be resolved, you should use the ADB server option.

Assuming you have 2 devices that require authentication, your configuration will look like this (update the adbkey path accordingly):

media_player:
- platform: androidtv
  name: Android TV 1
  host: 192.168.0.111
  adbkey: "/config/.android/adbkey"

media_player:
- platform: androidtv
  name: Android TV 2
  host: 192.168.0.222
  adbkey: "/config/.android/adbkey"

ADB Authentication

If you get a “Device authentication required, no keys available” error when trying to set up your Android TV or Fire TV, then you’ll need to create an adbkey and add its path to your configuration. Follow the instructions on this page to connect to your device from your computer: Connecting to Fire TV Through adb.

Note

In the dialog appearing on your Android TV / Fire TV, you must check the box that says “always allow connections from this device.” ADB authentication in Home Assistant will only work using a trusted key.

Once you’ve successfully connected to your Android TV / Fire TV via the command adb connect <ipaddress>, the file adbkey will be created on your computer. The default location for this file is (from https://developer.android.com/studio/command-line/adb):

  • Linux and Mac: $HOME/.android
  • Windows: %userprofile%\.android

Copy the adbkey file to your Home Assistant folder and add the path to your configuration.

androidtv

androidtv package

Submodules

androidtv.androidtv module

Communicate with an Android TV device via ADB over a network.

ADB Debugging must be enabled.

class androidtv.androidtv.AndroidTV(host, adbkey='', adb_server_ip='', adb_server_port=5037)[source]

Bases: androidtv.basetv.BaseTV

Representation of an Android TV device.

DEVICE_CLASS = 'androidtv'
get_properties(lazy=False)[source]

Get the properties needed for Home Assistant updates.

Parameters:lazy (bool) – Whether or not to continue retrieving properties if the device is off or the screensaver is running
Returns:
  • screen_on (bool, None) – Whether or not the device is on, or None if it was not determined
  • awake (bool, None) – Whether or not the device is awake (screensaver is not running), or None if it was not determined
  • wake_lock_size (int, None) – The size of the current wake lock, or None if it was not determined
  • current_app (str, None) – The current app property, or None if it was not determined
  • media_session_state (int, None) – The state from the output of dumpsys media_session, or None if it was not determined
  • audio_state (str, None) – The audio state, as determined from “dumpsys audio”, or None if it was not determined
  • device (str, None) – The current playback device, or None if it was not determined
  • is_volume_muted (bool, None) – Whether or not the volume is muted, or None if it was not determined
  • volume (int, None) – The absolute volume level, or None if it was not determined
get_properties_dict(lazy=True)[source]

Get the properties needed for Home Assistant updates and return them as a dictionary.

Parameters:lazy (bool) – Whether or not to continue retrieving properties if the device is off or the screensaver is running
Returns:A dictionary with keys 'screen_on', 'awake', 'wake_lock_size', 'current_app', 'media_session_state', 'audio_state', 'device', 'is_volume_muted', and 'volume'
Return type:dict
start_intent(uri)[source]

Start an intent on the device.

Parameters:uri (str) – The intent that will be sent is am start -a android.intent.action.VIEW -d <uri>
turn_off()[source]

Send POWER action if the device is not off.

turn_on()[source]

Send POWER action if the device is off.

update()[source]

Get the info needed for a Home Assistant update.

Returns:
  • state (str) – The state of the device
  • current_app (str) – The current running app
  • device (str) – The current playback device
  • is_volume_muted (bool) – Whether or not the volume is muted
  • volume_level (float) – The volume level (between 0 and 1)
androidtv.basetv module

Communicate with an Android TV or Amazon Fire TV device via ADB over a network.

ADB Debugging must be enabled.

class androidtv.basetv.BaseTV(host, adbkey='', adb_server_ip='', adb_server_port=5037)[source]

Bases: object

Base class for representing an Android TV / Fire TV device.

_adb_shell_pure_python_adb(cmd)[source]

Send an ADB command using an ADB server.

Parameters:cmd (str) – The ADB command to be sent
Returns:The response from the device, if there is a response
Return type:str, None
_adb_shell_python_adb(cmd)[source]

Send an ADB command using the Python ADB implementation.

Parameters:cmd (str) – The ADB command to be sent
Returns:The response from the device, if there is a response
Return type:str, None
static _audio_state(dumpsys_audio_response)[source]

Parse the audio_state property from the output of adb shell dumpsys audio.

Parameters:dumpsys_audio_response (str, None) – The output of adb shell dumpsys audio
Returns:The audio state, or None if it could not be determined
Return type:str, None
static _current_app(current_app_response)[source]

Get the current app from the output of the command androidtv.constants.CMD_CURRENT_APP.

Parameters:current_app_response (str, None) – The output from the ADB command androidtv.constants.CMD_CURRENT_APP
Returns:The current app, or None if it could not be determined
Return type:str, None
_current_app_media_session_state(media_session_state_response)[source]

Get the current app and the media session state properties from the output of androidtv.constants.CMD_MEDIA_SESSION_STATE_FULL.

Parameters:media_session_state_response (str, None) – The output of androidtv.constants.CMD_MEDIA_SESSION_STATE_FULL
Returns:
  • current_app (str, None) – The current app, or None if it could not be determined
  • media_session_state (int, None) – The state from the output of the ADB shell command, or None if it could not be determined
static _device(stream_music)[source]

Get the current playback device from the STREAM_MUSIC block from adb shell dumpsys audio.

Parameters:stream_music (str, None) – The STREAM_MUSIC block from adb shell dumpsys audio
Returns:The current playback device, or None if it could not be determined
Return type:str, None
_get_stream_music(dumpsys_audio_response=None)[source]

Get the STREAM_MUSIC block from adb shell dumpsys audio.

Parameters:dumpsys_audio_response (str, None) – The output of adb shell dumpsys audio
Returns:The STREAM_MUSIC block from adb shell dumpsys audio, or None if it could not be determined
Return type:str, None
static _is_volume_muted(stream_music)[source]

Determine whether or not the volume is muted from the STREAM_MUSIC block from adb shell dumpsys audio.

Parameters:stream_music (str, None) – The STREAM_MUSIC block from adb shell dumpsys audio
Returns:Whether or not the volume is muted, or None if it could not be determined
Return type:bool, None
_key(key)[source]

Send a key event to device.

Parameters:key (str, int) – The Key constant
static _media_session_state(media_session_state_response, current_app)[source]

Get the state from the output of androidtv.constants.CMD_MEDIA_SESSION_STATE.

Parameters:
Returns:

The state from the output of the ADB shell command, or None if it could not be determined

Return type:

int, None

static _running_apps(running_apps_response)[source]

Get the running apps from the output of androidtv.constants.CMD_RUNNING_APPS.

Parameters:running_apps_response (str, None) – The output of androidtv.constants.CMD_RUNNING_APPS
Returns:A list of the running apps, or None if it could not be determined
Return type:list, None
_volume(stream_music, device)[source]

Get the absolute volume level from the STREAM_MUSIC block from adb shell dumpsys audio.

Parameters:
  • stream_music (str, None) – The STREAM_MUSIC block from adb shell dumpsys audio
  • device (str, None) – The current playback device
Returns:

The absolute volume level, or None if it could not be determined

Return type:

int, None

_volume_level(volume)[source]

Get the relative volume level from the absolute volume level.

Parameters:volume (int, None) – The absolute volume level
Returns:The volume level (between 0 and 1), or None if it could not be determined
Return type:float, None
static _wake_lock_size(wake_lock_size_response)[source]

Get the size of the current wake lock from the output of androidtv.constants.CMD_WAKE_LOCK_SIZE.

Parameters:wake_lock_size_response (str, None) – The output of androidtv.constants.CMD_WAKE_LOCK_SIZE
Returns:The size of the current wake lock, or None if it could not be determined
Return type:int, None
audio_state

Check if audio is playing, paused, or idle.

Returns:The audio state, as determined from the ADB shell command dumpsys audio, or None if it could not be determined
Return type:str, None
available

Check whether the ADB connection is intact.

Returns:Whether or not the ADB connection is intact
Return type:bool
awake

Check if the device is awake (screensaver is not running).

Returns:Whether or not the device is awake (screensaver is not running)
Return type:bool
back()[source]

Send back action.

connect(always_log_errors=True)[source]

Connect to an Android TV / Fire TV device.

Parameters:always_log_errors (bool) – If True, errors will always be logged; otherwise, errors will only be logged on the first failed reconnect attempt
Returns:Whether or not the connection was successfully established and the device is available
Return type:bool
current_app

Return the current app.

Returns:The ID of the current app, or None if it could not be determined
Return type:str, None
device

Get the current playback device.

Returns:The current playback device, or None if it could not be determined
Return type:str, None
down()[source]

Send down action.

enter()[source]

Send enter action.

get_device_properties()[source]

Return a dictionary of device properties.

Returns:props – A dictionary with keys 'wifimac', 'ethmac', 'serialno', 'manufacturer', 'model', and 'sw_version'
Return type:dict
home()[source]

Send home action.

is_volume_muted

Whether or not the volume is muted.

Returns:Whether or not the volume is muted, or None if it could not be determined
Return type:bool, None
key_0()[source]

Send 0 keypress.

key_1()[source]

Send 1 keypress.

key_2()[source]

Send 2 keypress.

key_3()[source]

Send 3 keypress.

key_4()[source]

Send 4 keypress.

key_5()[source]

Send 5 keypress.

key_6()[source]

Send 6 keypress.

key_7()[source]

Send 7 keypress.

key_8()[source]

Send 8 keypress.

key_9()[source]

Send 9 keypress.

key_a()[source]

Send a keypress.

key_b()[source]

Send b keypress.

key_c()[source]

Send c keypress.

key_d()[source]

Send d keypress.

key_e()[source]

Send e keypress.

key_f()[source]

Send f keypress.

key_g()[source]

Send g keypress.

key_h()[source]

Send h keypress.

key_i()[source]

Send i keypress.

key_j()[source]

Send j keypress.

key_k()[source]

Send k keypress.

key_l()[source]

Send l keypress.

key_m()[source]

Send m keypress.

key_n()[source]

Send n keypress.

key_o()[source]

Send o keypress.

key_p()[source]

Send p keypress.

key_q()[source]

Send q keypress.

key_r()[source]

Send r keypress.

key_s()[source]

Send s keypress.

key_t()[source]

Send t keypress.

key_u()[source]

Send u keypress.

key_v()[source]

Send v keypress.

key_w()[source]

Send w keypress.

key_x()[source]

Send x keypress.

key_y()[source]

Send y keypress.

key_z()[source]

Send z keypress.

left()[source]

Send left action.

media_next_track()[source]

Send media next action (results in fast-forward).

media_pause()[source]

Send media pause action.

media_play()[source]

Send media play action.

media_play_pause()[source]

Send media play/pause action.

media_previous_track()[source]

Send media previous action (results in rewind).

media_session_state

Get the state from the output of dumpsys media_session.

Returns:The state from the output of the ADB shell command dumpsys media_session, or None if it could not be determined
Return type:int, None
media_stop()[source]

Send media stop action.

menu()[source]

Send menu action.

mute_volume()[source]

Mute the volume.

power()[source]

Send power action.

right()[source]

Send right action.

running_apps

Return a list of running user applications.

Returns:A list of the running apps
Return type:list
screen_on

Check if the screen is on.

Returns:Whether or not the device is on
Return type:bool
set_volume_level(volume_level, current_volume_level=None)[source]

Set the volume to the desired level.

Note

This method works by sending volume up/down commands with a 1 second pause in between. Without this pause, the device will do a quick power cycle. This is the most robust solution I’ve found so far.

Parameters:
  • volume_level (float) – The new volume level (between 0 and 1)
  • current_volume_level (float, None) – The current volume level (between 0 and 1); if it is not provided, it will be determined
Returns:

The new volume level (between 0 and 1), or None if self.max_volume could not be determined

Return type:

float, None

sleep()[source]

Send sleep action.

space()[source]

Send space keypress.

up()[source]

Send up action.

volume

Get the absolute volume level.

Returns:The absolute volume level, or None if it could not be determined
Return type:int, None
volume_down(current_volume_level=None)[source]

Send volume down action.

Parameters:current_volume_level (float, None) – The current volume level (between 0 and 1); if it is not provided, it will be determined
Returns:The new volume level (between 0 and 1), or None if self.max_volume could not be determined
Return type:float, None
volume_level

Get the relative volume level.

Returns:The volume level (between 0 and 1), or None if it could not be determined
Return type:float, None
volume_up(current_volume_level=None)[source]

Send volume up action.

Parameters:current_volume_level (float, None) – The current volume level (between 0 and 1); if it is not provided, it will be determined
Returns:The new volume level (between 0 and 1), or None if self.max_volume could not be determined
Return type:float, None
wake_lock_size

Get the size of the current wake lock.

Returns:The size of the current wake lock, or None if it could not be determined
Return type:int, None
androidtv.constants module

Constants used in the BaseTV, AndroidTV, and FireTV classes.

androidtv.constants.CMD_AUDIO_STATE = "dumpsys audio | grep -v 'Buffer Queue' | grep -q paused && echo -e '1\\c' || (dumpsys audio | grep -v 'Buffer Queue' | grep -q started && echo '2\\c' || echo '0\\c')"

Get the audio state

androidtv.constants.CMD_AWAKE = 'dumpsys power | grep mWakefulness | grep -q Awake'

Determine whether the device is awake

androidtv.constants.CMD_CURRENT_APP = 'CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP'

Get the current app

androidtv.constants.CMD_MEDIA_SESSION_STATE = "dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {'"

Get the state from dumpsys media_session; this assumes that the variable CURRENT_APP has been defined

androidtv.constants.CMD_MEDIA_SESSION_STATE_FULL = "CURRENT_APP=$(dumpsys window windows | grep mCurrentFocus) && CURRENT_APP=${CURRENT_APP#*{* * } && CURRENT_APP=${CURRENT_APP%%/*} && echo $CURRENT_APP && dumpsys media_session | grep -A 100 'Sessions Stack' | grep -A 100 $CURRENT_APP | grep -m 1 'state=PlaybackState {'"

Determine the current app and get the state from dumpsys media_session

androidtv.constants.CMD_RUNNING_APPS = 'ps | grep u0_a'

Get the running apps

androidtv.constants.CMD_SCREEN_ON = "dumpsys power | grep 'Display Power' | grep -q 'state=ON'"

Determine if the device is on

androidtv.constants.CMD_WAKE_LOCK_SIZE = "dumpsys power | grep Locks | grep 'size='"

Get the wake lock size

androidtv.firetv module

Communicate with an Amazon Fire TV device via ADB over a network.

ADB Debugging must be enabled.

class androidtv.firetv.FireTV(host, adbkey='', adb_server_ip='', adb_server_port=5037)[source]

Bases: androidtv.basetv.BaseTV

Representation of an Amazon Fire TV device.

DEVICE_CLASS = 'firetv'
_send_intent(pkg, intent, count=1)[source]

Send an intent to the device.

Parameters:
  • pkg (str) – The command that will be sent is monkey -p <intent> -c <pkg> <count>; echo $?
  • intent (str) – The command that will be sent is monkey -p <intent> -c <pkg> <count>; echo $?
  • count (int, str) – The command that will be sent is monkey -p <intent> -c <pkg> <count>; echo $?
Returns:

A dictionary with keys 'output' and 'retcode', if they could be determined; otherwise, an empty dictionary

Return type:

dict

get_properties(get_running_apps=True, lazy=False)[source]

Get the properties needed for Home Assistant updates.

Parameters:
  • get_running_apps (bool) – Whether or not to get the running_apps property
  • lazy (bool) – Whether or not to continue retrieving properties if the device is off or the screensaver is running
Returns:

  • screen_on (bool, None) – Whether or not the device is on, or None if it was not determined
  • awake (bool, None) – Whether or not the device is awake (screensaver is not running), or None if it was not determined
  • wake_lock_size (int, None) – The size of the current wake lock, or None if it was not determined
  • current_app (str, None) – The current app property, or None if it was not determined
  • media_session_state (int, None) – The state from the output of dumpsys media_session, or None if it was not determined
  • running_apps (list, None) – A list of the running apps, or None if it was not determined

get_properties_dict(get_running_apps=True, lazy=True)[source]

Get the properties needed for Home Assistant updates and return them as a dictionary.

Parameters:
  • get_running_apps (bool) – Whether or not to get the running_apps property
  • lazy (bool) – Whether or not to continue retrieving properties if the device is off or the screensaver is running
Returns:

A dictionary with keys 'screen_on', 'awake', 'wake_lock_size', 'current_app', 'media_session_state', and 'running_apps'

Return type:

dict

launch_app(app)[source]

Launch an app.

Parameters:app (str) – The ID of the app that will be launched
Returns:A dictionary with keys 'output' and 'retcode', if they could be determined; otherwise, an empty dictionary
Return type:dict
stop_app(app)[source]

Stop an app.

Parameters:app (str) – The ID of the app that will be stopped
Returns:The output of the am force-stop ADB shell command, or None if the device is unavailable
Return type:str, None
turn_off()[source]

Send SLEEP action if the device is not off.

turn_on()[source]

Send POWER and HOME actions if the device is off.

update(get_running_apps=True)[source]

Get the info needed for a Home Assistant update.

Parameters:get_running_apps (bool) – Whether or not to get the running_apps property
Returns:
  • state (str) – The state of the device
  • current_app (str) – The current running app
  • running_apps (list) – A list of the running apps if get_running_apps is True, otherwise the list [current_app]

Module contents

Connect to a device and determine whether it’s an Android TV or an Amazon Fire TV.

ADB Debugging must be enabled.

androidtv.setup(host, adbkey='', adb_server_ip='', adb_server_port=5037, device_class='auto')[source]

Connect to a device and determine whether it’s an Android TV or an Amazon Fire TV.

Parameters:
  • host (str) – The address of the device in the format <ip address>:<host>
  • adbkey (str) – The path to the adbkey file for ADB authentication
  • adb_server_ip (str) – The IP address of the ADB server
  • adb_server_port (int) – The port for the ADB server
  • device_class (str) – The type of device: 'auto' (detect whether it is an Android TV or Fire TV device), 'androidtv', or 'firetv'`
Returns:

aftv – The representation of the device

Return type:

AndroidTV, FireTV

androidtv is a Python 3 package that provides state information and control of Android TV and Fire TV devices via ADB. This package is used by the Android TV integration in Home Assistant.

Installation

Be sure you install into a Python 3.x environment.

pip install androidtv

ADB Intents and Commands

A collection of useful intents and commands can be found here (credit: mcfrojd).

Acknowledgments

This is based on python-firetv by happyleavesaoc and the androidtv component for Home Assistant by a1ex4, and it depends on python-adb and pure-python-adb.

Indices and tables