Native support for Android TV / Android devices

That’s odd that the androidtv.adb_command service is almost instant but the other controls are slow. The command is sent the same way. For example, hitting volume up is equivalent to sending the command input keyevent 24. A list of key events can be found here.

But if you’re just referring to how fast the state in HA updates, then I think that’s just a matter of the state getting updated after the androidtv.adb_command service.

Ah okay, I thought there was a more practical way of executing it via lovelace, no worries thanks.

Is there a way to force a quicker status update for the media player? I dont mind the delay selecting sources, but the volume, play/pause and specially the states is a deal breaker for me.
I have a automation to turn on my lights at night if any media is paused and match the light color whit the app color (Ej: pausing youtube turn light red, kodi blue, etc), and another one to turn the lights off whenever the media resumes.

That automation using the androitv component takes 5 to 6 seconds to do it, and for example using the kodi component everything is seamless and instant

That’s just how it is with a polling integration.

https://www.home-assistant.io/integrations/androidtv/#custom-state-detection

You can provide a scan_interval parameter to make it update more often. The default is10.

But when media is playing and you press pause in HA, does the media pause right away? (On the device, not in HA)

Hi there,

I’ve been struggling with setting up the connection to my Sony Android TV (KD-55X8505C) for a while now. I’ve tried the ADB Server approach and the Python ADB Implementation.
Both approaches end up in connection issues after running OK for around 3 hours.

You’ll find the debug logs attached. Do you have any advise what to do and how to fix it, based on the logs?

2020-01-29 03:19:02 DEBUG (SyncWorker_14) [androidtv.adb_manager] Sending command to 192.168.0.11:5555 via adb-shell: (dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true') && echo -e '1\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\c' && (dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\c' || echo '0\c')) && dumpsys power | grep Locks | grep 'size=' && 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 {' || echo) && dumpsys audio | grep '\- STREAM_MUSIC:' -A 12
2020-01-29 03:19:02 DEBUG (SyncWorker_14) [adb_shell.adb_device] bulk_write: b'OPEN\x01\x00\x00\x00\x00\x00\x00\x00\xe2\x02\x00\x00\x19\xeb\x00\x00\xb0\xaf\xba\xb1'
2020-01-29 03:19:02 DEBUG (SyncWorker_14) [adb_shell.adb_device] bulk_write: b"shell:(dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true') && echo -e '1\\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\\c' && (dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\\c' || echo '0\\c')) && dumpsys power | grep Locks | grep 'size=' && 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 {' || echo) && dumpsys audio | grep '\\- STREAM_MUSIC:' -A 12\x00"
2020-01-29 03:19:03 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.sony_tv fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 281, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 461, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 271, in _adb_exception_catcher
    return func(self, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 471, in update
    ) = self.aftv.update()
  File "/usr/local/lib/python3.7/site-packages/androidtv/androidtv.py", line 79, in update
    screen_on, awake, audio_state, wake_lock_size, current_app, media_session_state, device, is_volume_muted, volume = self.get_properties(lazy=True)
  File "/usr/local/lib/python3.7/site-packages/androidtv/androidtv.py", line 225, in get_properties
    output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY)
  File "/usr/local/lib/python3.7/site-packages/androidtv/adb_manager.py", line 165, in shell
    return self._adb.shell(cmd)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 212, in shell
    return b''.join(self._streaming_command(b'shell', command.encode('utf8'), timeout_s, total_timeout_s)).decode('utf8')
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 506, in _streaming_command
    local_id, remote_id = self._open(b'%s:%s' % (service, command), timeout_s, total_timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 269, in _open
    _, remote_id, their_local_id, _ = self._read([constants.OKAY], timeout_s, total_timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 319, in _read
    msg = self._handle.bulk_read(constants.MESSAGE_SIZE, timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/tcp_handle.py", line 107, in bulk_read
    return self._connection.recv(numbytes)
ConnectionResetError: [Errno 104] Connection reset by peer
2020-01-29 03:19:13 DEBUG (SyncWorker_8) [androidtv.adb_manager] Sending command to 192.168.0.11:5555 via adb-shell: (dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true') && echo -e '1\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\c' && (dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\c' || echo '0\c')) && dumpsys power | grep Locks | grep 'size=' && 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 {' || echo) && dumpsys audio | grep '\- STREAM_MUSIC:' -A 12
2020-01-29 03:19:13 DEBUG (SyncWorker_8) [adb_shell.adb_device] bulk_write: b'OPEN\x01\x00\x00\x00\x00\x00\x00\x00\xe2\x02\x00\x00\x19\xeb\x00\x00\xb0\xaf\xba\xb1'
2020-01-29 03:19:13 ERROR (SyncWorker_8) [homeassistant.components.androidtv.media_player] Failed to execute an ADB command. ADB connection re-establishing attempt in the next update. Error: [Errno 32] Broken pipe
2020-01-29 03:19:13 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.sony_tv fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 271, in _adb_exception_catcher
    return func(self, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 471, in update
    ) = self.aftv.update()
  File "/usr/local/lib/python3.7/site-packages/androidtv/androidtv.py", line 79, in update
    screen_on, awake, audio_state, wake_lock_size, current_app, media_session_state, device, is_volume_muted, volume = self.get_properties(lazy=True)
  File "/usr/local/lib/python3.7/site-packages/androidtv/androidtv.py", line 225, in get_properties
    output = self._adb.shell(constants.CMD_ANDROIDTV_PROPERTIES_LAZY)
  File "/usr/local/lib/python3.7/site-packages/androidtv/adb_manager.py", line 165, in shell
    return self._adb.shell(cmd)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 212, in shell
    return b''.join(self._streaming_command(b'shell', command.encode('utf8'), timeout_s, total_timeout_s)).decode('utf8')
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 506, in _streaming_command
    local_id, remote_id = self._open(b'%s:%s' % (service, command), timeout_s, total_timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 268, in _open
    self._send(msg, timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 472, in _send
    self._handle.bulk_write(msg.pack(), timeout_s)
  File "/usr/local/lib/python3.7/site-packages/adb_shell/tcp_handle.py", line 136, in bulk_write
    return self._connection.send(data)
BrokenPipeError: [Errno 32] Broken pipe

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 281, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 461, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 278, in _adb_exception_catcher
    self.aftv.adb_close()
  File "/usr/local/lib/python3.7/site-packages/androidtv/basetv.py", line 150, in adb_close
    self._adb.close()
  File "/usr/local/lib/python3.7/site-packages/androidtv/adb_manager.py", line 66, in close
    self._adb.close()
  File "/usr/local/lib/python3.7/site-packages/adb_shell/adb_device.py", line 95, in close
    self._handle.close()
  File "/usr/local/lib/python3.7/site-packages/adb_shell/tcp_handle.py", line 63, in close
    self._connection.shutdown(socket.SHUT_RDWR)
OSError: [Errno 107] Socket not connected
2020-01-29 03:19:24 DEBUG (SyncWorker_12) [androidtv.adb_manager] ADB command not sent to 192.168.0.11:5555 because adb-shell connection is not established: (dumpsys power | grep 'Display Power' | grep -q 'state=ON' || dumpsys power | grep -q 'mScreenOn=true') && echo -e '1\c' && dumpsys power | grep mWakefulness | grep -q Awake && echo -e '1\c' && (dumpsys audio | grep paused | grep -qv 'Buffer Queue' && echo -e '1\c' || (dumpsys audio | grep started | grep -qv 'Buffer Queue' && echo '2\c' || echo '0\c')) && dumpsys power | grep Locks | grep 'size=' && 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 {' || echo) && dumpsys audio | grep '\- STREAM_MUSIC:' -A 12

I’ve noticed one main difference between the two approaches.
While the ADB Server approach seems trying to recover itself for a few seconds in between,


the Python ADB approach remains in broken / unavailable state.
It won’t connect anymore to my TV, but instead throws the above seen error message in my HA logs.

I’m running HASSio as Docker installation on RPi 4. Currently installed version is 103.3
RPi and TV are both connected to the network by wire.

Any help would be highly appreciated :slight_smile:

Thanks for the logs!

There are two issues with the HA integration. One is fixed in 0.104, the other will be fixed in 0.105. If you don’t want to wait, you can use this custom component in the meantime: https://github.com/JeffLIrion/ha-androidtv

But the real problem is that your TV goes into deep sleep mode, breaking the ADB connection. You could try installing a Wakelock utility. See #6 here: https://www.home-assistant.io/integrations/androidtv/#adb-troubleshooting

If I may ask you as a specialist. If the TV goes to deep sleep, how is it possible, to wake it up via Bluetooth (that’s what I do with my remote)? Can one (me) use that BT to avoid the unavailable state or start it with a BT command?

And on a second, not unrelated question: I’m using a new device in Germany, from Telekom. It’s called MagentaTV stick. It’s basically a normal stick like FireTV, with a launcher for the MagentaTV services and the possibility, to install apps via playstore. This is a unit, that will get broad attention, when it leaves the beta stadium. That brings me to the point: right now there is a very good communication between beta users and the development team from Telekom. How do I explain them, things like the wakelock_size or audio_state and what we, as users, want them to show to make the stick work good to very good with HA? Are there any related documents I could dive into?

Thanks for your help and for the component, it is imho one of the key components in HA. :slight_smile: Controlling a TV is essential. :slight_smile:

Thanks for the kind words! But I’m no expert. Regarding your first question, all I can say is that the TV must always be listening for Bluetooth signals, but at some point it decides that it doesn’t need to keep running ADB.

Regarding your second point, what the Android TV integration does is parse properties from the output of ADB commands. I think it’s all standard Android stuff. Media session state is probably the best of these properties for determining state. The commands used to get these properties can be found here.

If this MagentaTV Stick is an Android device with ADB, then the Android TV integration will probably work for it.

hi, recently i am experiencing an error that i can’t fix while loading androidtv component:

Error while setting up platform androidtv
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 158, in _async_setup_platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/androidtv/media_player.py", line 207, in setup_platform
    state_detection_rules=config[CONF_STATE_DETECTION_RULES],
  File "/usr/local/lib/python3.7/site-packages/androidtv/__init__.py", line 52, in setup
    aftv = BaseTV(host, port, adbkey, adb_server_ip, adb_server_port, state_detection_rules, auth_timeout_s)
  File "/usr/local/lib/python3.7/site-packages/androidtv/basetv.py", line 100, in __init__
    self.device_properties = self.get_device_properties()
  File "/usr/local/lib/python3.7/site-packages/androidtv/basetv.py", line 206, in get_device_properties
    constants.CMD_MAC_ETH0)
  File "/usr/local/lib/python3.7/site-packages/androidtv/adb_manager.py", line 435, in shell
    return self._adb_device.shell(cmd)
  File "/usr/local/lib/python3.7/site-packages/ppadb/command/transport/__init__.py", line 20, in shell
    conn = self.create_connection(timeout=timeout)
  File "/usr/local/lib/python3.7/site-packages/ppadb/device.py", line 45, in create_connection
    self.transport(conn)
  File "/usr/local/lib/python3.7/site-packages/ppadb/command/transport/__init__.py", line 15, in transport
    connection.send(cmd)
  File "/usr/local/lib/python3.7/site-packages/ppadb/connection.py", line 77, in send
    return self._check_status()
  File "/usr/local/lib/python3.7/site-packages/ppadb/connection.py", line 83, in _check_status
    raise RuntimeError("ERROR: {} {}".format(repr(recv), error))
RuntimeError: ERROR: 'FAIL' 000edevice offline

no changes has been done from my side apart from updating home assistant from 0.103 to 0.104 (latest), anyone knows how to fix it and what it really means?

i have tried using custom component as provided couple of posts before - but that didn’t help.

thank you in advance!

Thanks for the help. And no when i pause (or anything) is also takes a a few seconds to pause the tv. Idk what is causing the closest comparison i can do ( as i don’t know the adb shell command to pause tv) is launching netflix selecting from media player source list (3 to 8 seconds to start) and launching it from androidtv.adb_command or adb shell which is instant

ill try to change the scan_interval, but i think this will only solve the states delay, the delay will still be present when launching anything. I don’t see more people whit this problem so something has to be wrong on my setup? I even facory rest my tv and do a fresh install for home assitant only for this >_<

Look at the link in this post: Native support for Android TV / Android devices

Find the right key event on the linked page, then run the androidtv.adb_command service with input keyevent 127 (that’s pause, but you can substitute the number with whatever you want).

If that’s instant but pressing pause in the UI is not, then there’s something strange going on.

Hi, exactly the same result (3 seconds delay). Maybe the delay is only whit input keyevents commands? the regular am start -n sended whit androidtv.adb_command are always instant

Hi HA team

I have a new Amazon FireTV Cube and have successfully installed the ADB add-on. Configuration looks good and I am able to connect without issue. I looked through the documentation for ADB but was unable to find the answer:

Is there a way to launch a specific youtube URL or video using the service? Say if I wanted to stream a live channel on youtube on the device.

Thank you team!

Fire Cube, been getting a lot of these in the logs

2020-02-24 21:07:11 WARNING (SyncWorker_7) [androidtv.adb_manager] Couldn't connect to 192.168.1.234:5555.  ConnectionResetError: Connection reset by peer
2020-02-24 21:07:11 WARNING (SyncWorker_7) [homeassistant.components.androidtv.media_player] Could not connect to LR Fire TV at X.X.X.X:5555 using Python ADB implementation with adbkey='/config/.storage/androidtv_adbkey'

but nothing had changed.

FIXED by simply turning off ADB Debugging OFF, and ON again - the dialogue then popped up again on the Fire Cube to allow incomming connections.
(i’d tried deleting the keys, so that maybe needed also but can’t confirm)
Anyway HTH someone else should they find this post.

1 Like

Anyone have any smart ideas for using this with Mibox 4 / S ?

I have two of them and the first problem is no built in option to enable network ADB, so this has to be done via USB Adb first…
Which is the second issue… I don’t want to have to do that each time I reboot the box.

Is there anyway to automate that without root?

Another thought I had was to have an app on the box that monitors media state and posts it to HA, but there doesn’t seem to be a simple way to get media state…

So just wanted to check back to mention something as after moving my setup to a new computer… all my disconnect problems started over again and I couldn’t figure out what was happening. Had adb server set back up with the same startup/connect services but no matter what I did a few minutes maybe (6-7) after a tv was turned off it disconnected and would not reconnect… in the course of fooling around I noticed that my version of adb was extremely old. I only noticed because some examples of adb showed it showing the word “device” after the ip when listing connected devices. Mine did not, so I updated my version of adb from the android-tools/sdk website and everything was rock-solid again. I just wanted to mention it in case anyone else using the adb-server method has issues with disconnects and can’t figure it out, hopefully that will help.

Where did you update your adb version? :slight_smile:

for me it was in /usr/bin and this link should get you the package with all the tools, I’m not sure if correct or not to do this way but I simply renamed the current adb, adb_old and took the one out if the download and placed it in /usr/bin, I knew it worked because after connecting devices, typing adb devices looked like this now:

List of devices attached
192.168.1.174:5555	device
192.168.1.38:5555	device

where with the old version it just listed the IP and that’s it

I also added a systemd service to start adb-server and connect to the devices on boot

https://developer.android.com/studio/releases/platform-tools

1 Like

Also, in the course of my troubleshooting I made an automation to tell me when the firetvs became unavailable… don’t do that, it just made it take longer to figure out because once I updated they would still get marked as unavailable for a split second but by the time I brought up the page in my UI with the firetvs it had already reconnected and stayed that way…

1 Like

So I’ve been controlling my FireTV devices in a semi-broken way for a while now, but just recently cleaned everything up with a solid ADB implementation. However, there’s one feature I still can’t get to work, and am wondering if anyone can confirm whether it’s possible – input switching.

I can switch TV inputs via voice/remote on my FireTV sticks, so seems like the functionality is there via CEC (I don’t think the remotes use IR). I also have a FireTV Cube that does have IR capabilities. However, I can’t seem to get the HDMI commands to do anything via ADB service calls. Is this possible or should I just give up and focus on controlling the TV’s directly?