Native support for Android TV / Android devices

Great news here !
I’m using this for a while now and it works really good for my needs. As you said, with the ‘adb connect’ command issued as a script.

But I must say I don’t demand a lot to the media players, mostly because I expect a more interactive experience from it. This is a problem from HA generic component, not from your implementation for Android devices.
I’ve enhanced the Denon component so that it can control the network music player/Internet radio, but the only way I could make the arrows in the media player is to define them as entries to select. Never actually use it, it’s a pain ! :cry:
I wish it looked more like a remote control, full featured.

Anyway… So I’m using this component mostly to monitor the TV use, change the volume when I’m not in the room. Sad.

What are your plans ? Have you ideas about features to add in, or are you looking for testers ?

I run this component (client version) now for two Nvidia Shield TV devices. Since they always remain online, I have not faced any disconnects, not even when I restart the HA service. Only booting the RPi requires to “adb connect” again, but that is absolutely acceptable.

The player state updates after a few seconds (3-7 sec) which is OK for my purpose.

Services usage
While the Android device is controlled like any media player, there are 3 services used to interact with it:

You should update the documentation, the key names are “action”, “key” and “intent”, not “androidtv_action” etc. I managed to execute the services for actions and keys, but intents are still unclear to me… Could you please elaborate how to e. g. open a specific app?

@Mister_Slowhand That’s great if you’ve been using for this long, thanks again for sharing your automation! I get what you’re saying, although for the media players I use Home Assistant to extend their actions and make them interact with other items, like lights, or in this case with services.

Definitely looking for testers! Their are so many different Android box around, I hope most of them can be handled. For the future I kind of gave up trying to get rid of the initial ADB setup, I wanted the component to be available for everyone (including hass.io) and easy as possible, but I don’t have the time to dive in the official adb lib. So my focus is going to be on the ‘client’ version, and I have a couple of things I want to add, more services and states. Also create a better doc! :sweat_smile:

@cicero222 Awesome, I’m very glad this is working for you! Yep, good catch for the services, I still had them like that on my Nodered so I was confused, I’ll update the post.
Don’t hesitate if you have more ideas or suggestions :slight_smile:

EDIT: as for the intents, they are basically ‘urls’ that when opened on Android will execute an action within a specific app. For example when you click on a location and that opens Maps with the location, or when you want to add a calendar link, it will open the app and you can confirm if you want to add it.

You can look them up on Google, ‘app android intent/actions’. For Youtube simply passing the video/playlist URL will start the app and the video. For Spotify the URL is spotify:playlist:PLAYLIST-ID:play. You can do some pretty cool stuff with it, originally I created this component so I can wake up to a Spotify playlist playing on random :wink:

@a1ex4 (or anyone else interested), how about this idea…

  1. Fork the pure-python-adb repo and call it something other than adb, such as adb_pure, so that it can coexist with the python-adb package. Host this modified library on pypi.
  2. Modify the androidtv package. Specifically, add a keyword argument adb_client (and adb_device?) to the AndroidTV class such that if it is provided, it will execute its ADB commands using the “pure-python-adb” library instead of the “python-adb” library. Ideally, do it in a way such that the syntax for sending ADB commands is the same either way (e.g., self._adb.Shell(cmd)).
  3. The HA component will use the androidtv package, which will use “pure-python-adb” if the adb_client configuration entry is provided and the “python-adb” library otherwise.

And then I can copy this for the firetv package and HA component :smile:!

That’s EXACTLY what I was thinking too! As we speak I’m writing ha-androidtv, which is my first Pypi package, so I’m taking my time and learning how to do that, mostly from yours :wink:
So I was thinking about it but as I don’t know enough about Pypi packaging I decided to go one baby step at a time, but clearly this is the ideal solution :+1:

I got a basic chinese box, with Android (not Android TV) 6. N95X something.
I run Plex (local, no registration, manual connect to my server), Netflix (from local APK install…), TinyCam for the cameras.

Tell me if you want me to try anything, I don’t mind breaking its integration into HA for a while.

What I’d love to have : interact with Plex server, choose a movie, a song, an album and play it on the box ! No Plex component offers that right now.

Awesome idea. Is exactly what i’m looking for.
I will try it !

1 Like

How to run app from HA with intent service? For example how to run Netflix?

on my mibox no network debugging :frowning:
so adb connect : connexion refused :frowning:
Any help ?
EDIT : mistakes on the IP :slight_smile:

i try to add app “tv.molotov.app” but not working. :confused:

@Mister_Slowhand This Plex integration seems way too specific to be part of this component, such tool should work on any Plex instance, not only on an Android TV.

@Bieniu I’m planning on adding another service, that will be used to open apps. I’ll try to add a dropdown to the card, similar to the modes on a light, to open installed app.

@max5962 What’s your config like ? This should be:

media_player:
  - platform: androidtv
    host: 192.168.1.37
    apps:
      "molotov": "Molotov"

Right now I’m working on having the best code possible to interact with Home Assistant, adding other features will come later :wink:

1 Like

Excellent project ! very excited about it !
I use the client version androidtv.py file. But when restarting HA, I have an error when setting up platform.
line 129 “from adb.client import Client as AdbClient”

I have adb installed.

Am I missing something ?

Great job man !!! :slight_smile:

1 Like

Thanks for the kind words!
Ok the original post is a bit outdated, I’ve been working on newer version of the component that handle both implementations (client and standalone) that should work way better :wink:
I’ve opened a pull request to hopefully get this component into Home Assistant, meanwhile you can find the latest version here.
You should probably uninstall any adb related Python package before trying this out, a lot of changes were made.

:slight_smile:
Thank you for that update !
I’ve downloaded the right package from your link. First restart and seems that I missed the androidtv-0.0.4 pypi package. Will try with ot installed.
If my Shield TV is already paired with my raspberry I can omit the adb server and ports parameters ?

Thank you for your work (and sorry for my english… I’m french :stuck_out_tongue: )

French here too! I will continue in english for the other users though :stuck_out_tongue:
Ok so you should install androitv, with pip3 install androidtv, if you already connected the Shield with the ADB server then all you need in your config is:

media_player:
  - platform: androidtv
    host: ip.of.the.shield
    name: Shield TV

and that should work! This will use the “standalone” implementation by default. Please report here how it works with an RPi 3 and a Shield :slight_smile:

Hi from Toulouse so :slight_smile:

So, I have installed androidtv, configured the shield as described.
Command /usr/bin/adb connect 192.168.0.49 returns “already connected to 192.168.0.49:5555”
BUT I Have this error in home-assistant.log after restart.

File "/home/homeassistant/.homeassistant/custom_components/media_player/androidtv.py", line 181, in 
setup_platform
atv = AndroidTV(host, adbkey)

Of course the component does not work.
Missing something ?

@jncanches I think your problem is that your pi is already connected to your Android TV via ADB, and this component is trying to make another connection. I think you can do one of two things:

  1. Use the “pure-python-adb” version of the component that makes calls to the adb binaries by adding adb_server_ip: '127.0.0.1' to your config.
  2. Close your ADB connection and retry. To be safe, follow the “ADB Troubleshooting” steps from the Fire TV component documentation: https://www.home-assistant.io/components/media_player.firetv/.

Thanks for the reply @JeffLIrion
I already solved my adbkey issue with the help of @a1ex4 :slight_smile:

Now I’m beta testing the component using an nvidia shield.

Didn’t about your FireTV component. Really good documentation. It helped me to understand adb permissions.

Great job thank you !

This does not work at all for me…

I did pip3 install androidtv (for the homeassistant user, since I use Hassbian).

When I use the component without any additional parameters (i. e. standalone), I get

Could not connect to Android TV at 192.168.1.8:5555 using adbkey='/home/homeassistant/.android/adbkey'

which is kind of clear because I did not install the adb server for homeassistant user and there are no adb keys. But installing android-tools-adb does not work when switched to the homeassistant user… :rage:

When I try to use adb_server_ip: 127.0.0.1, I get this error, no matter if I define the adb_server_port or not:

2018-12-16 12:43:19 ERROR (MainThread) [homeassistant.components.media_player] Error while setting up platform androidtv
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/lib/python3.5/asyncio/tasks.py", line 400, in wait_for
    return fut.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/media_player/androidtv.py", line 191, in setup_platform
    adb_server_port=config[CONF_ADB_SERVER_PORT])
  File "/srv/homeassistant/lib/python3.5/site-packages/androidtv/__init__.py", line 230, in __init__
    self.properties = self.device_info()
  File "/srv/homeassistant/lib/python3.5/site-packages/androidtv/__init__.py", line 327, in device_info
    btmac = re.findall(BTMAC_REGEX_PATTERN, properties)[0]
IndexError: list index out of range

You should either copy the adbkeys somewhere, then use them in your configuration file, or simply run the server and use adb_server_ip: 127.0.0.1. The error you are seeing came from a recent addition that we made, and that’s because your Android TV device behave differently than mine. But hey that’s what a development thread is for.

In the terminal, run
adb connect 192.168.1.8
adb shell getprop

And paste the results here.

EDIT: ok you have a Shield, for now installing a newer version and using the server should work:
cd /srv/homeassistant/lib/python3.5/site-packages/androidtv/
mv __init__.py __init__.py.bak
wget https://raw.githubusercontent.com/JeffLIrion/python-androidtv/fe6e9ffadfd86ef4c45ce75c3a87e0495bfa45c1/androidtv/__init__.py

This will backup and update the androitv python package, running and using the ADB server should work for you.

Hello,

Thank you for your work on this component.

I installed the new version as you suggested in your last post but still get an error. I’ve saved my adbkey in my config file like below :

media_player:
  - platform: androidtv
    host: 192.168.10.20
    name: Shield
    adbkey: /data/data/com.termux/files/home/.homeassistant/.android/adbkey 

error message :

Error while setting up platform androidtv
Traceback (most recent call last):
  File "/data/data/com.termux/files/usr/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/data/data/com.termux/files/usr/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "/data/data/com.termux/files/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/data/data/com.termux/files/home/.homeassistant/custom_components/media_player/androidtv.py", line 181, in setup_platform
    atv = AndroidTV(host, adbkey)
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/androidtv/__init__.py", line 230, in __init__
    self.properties = self.device_info()
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/androidtv/__init__.py", line 330, in device_info
    wifi_out = self._adb_shell('ip addr show wlan0')
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/androidtv/__init__.py", line 474, in _adb_shell_python_adb
    return self._adb.Shell(cmd)
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/adb/adb_commands.py", line 376, in Shell
    timeout_ms=timeout_ms)
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/adb/adb_protocol.py", line 411, in Command
    return ''.join(cls.StreamingCommand(usb, service, command, timeout_ms))
  File "/data/data/com.termux/files/home/.homeassistant/deps/lib/python3.7/site-packages/adb/adb_protocol.py", line 439, in StreamingCommand
    for data in connection.ReadUntilClose():
AttributeError: 'NoneType' object has no attribute 'ReadUntilClose'