[androidtv.adb_manager] ADB device is unavailable; encountered an error when searching for device

Hey,

I use HA 0.99.3 in a pure docker install (host network) as well as an adb server on the same host in docker (host network). I even tested 2 different forked adb-server images but it looks like the adb server itself is working fine.
It used to work for months and now suddenly it does not anymore, I can’t really specifiy what happened when it stopped working since there happened different things like Server change, OS change, common update of HA and so on.

The log says:

2019-10-03 17:25:10 ERROR (SyncWorker_16) [androidtv.adb_manager] ADB device is unavailable; encountered an error when searching for device.
2019-10-03 17:25:10 WARNING (SyncWorker_16) [homeassistant.components.androidtv.media_player] Could not connect to Nvidia Shield at 192.168.178.21:5555 using ADB server at 127.0.0.1:5037
2019-10-03 17:25:10 WARNING (MainThread) [homeassistant.components.media_player] Platform androidtv not ready yet. Retrying in 90 seconds.
2019-10-03 17:25:10 ERROR (SyncWorker_13) [androidtv.adb_manager] ADB device is unavailable; encountered an error when searching for device.
2019-10-03 17:25:10 WARNING (SyncWorker_13) [homeassistant.components.androidtv.media_player] Could not connect to FireTV at 192.168.178.27:5555 using ADB server at 127.0.0.1:5037
2019-10-03 17:25:10 WARNING (MainThread) [homeassistant.components.media_player] Platform androidtv not ready yet. Retrying in 90 seconds.

While the log of the adb server is fine:

Starting up ADB...
Server started. Waiting for 30 seconds...
Connecting to devices.
connected to 192.168.178.21:5555
connected to 192.168.178.27:5555
Done.

And also from within the container:

/ # adb devices
List of devices attached
192.168.178.21:5555     device
192.168.178.27:5555     device
emulator-5570   offline
emulator-5572   offline

Netstat shows the port:

tcp6 0 0 :::5037 :::* LISTEN 19102/adb

And checking from the HA container:

bash-5.0# nc -zv 127.0.0.1 5037
127.0.0.1 (127.0.0.1:5037) open

And my configs:

- platform: androidtv
  name: Nvidia Shield
  device_class: androidtv
  host: 192.168.178.21
  adb_server_ip: 127.0.0.1
  adb_server_port: 5037
  adbkey: "/config/adbkey"
  apps:
    "com.netflix.ninja": "Netflix"
    "com.nvidia.tegrazone3": "NVIDIA Games"
    "com.google.android.tvlauncher": "Launcher"
    "com.amazon.amazonvideo.livingroom": "Amazon Prime"
    "com.google.android.youtube.tv": "Youtube"
    "com.plexapp.android": "Plex"
    "com.spotify.tv.android": "Spotify"
    "tv.twitch.android.app": "Twitch"

- platform: androidtv
  name: FireTV
  device_class: firetv
  host: 192.168.178.27
  adb_server_ip: 127.0.0.1
  adb_server_port: 5037
  adbkey: "/config/adbkey"
  apps:
    "com.amazon.tv.launcher": "Launcher"
    "com.netflix.ninja": "Netflix"
    "com.google.android.youtube.tv": "Youtube"
    "com.plexapp.android": "Plex"
  turn_on_command: "input keyevent 3"
  turn_off_command: "input keyevent 223"

I really have no idea anymore what else to check… any ideas?

Thanks in advance.

Try using this custom component (HACS compatible): https://github.com/JeffLIrion/ha-androidtv

Don’t use the ADB server approach – remove adb_server_ip and adb_server_port from your config, stop your ADB server, reboot your Android TV devices, and restart HA.

3 Likes

New to HA I have been having ADB log errors on mine. Saw this post, gave it a try. got this error after restarting HA.

I removed the ADB server from my config, saved it.
stopped the ADB server, switched off the turn on with boot option.
Then restarted HA.

Unfortunately I’m away from home, so I did this through the remote UI. I am unable to restart my FireTV. But it is currently off, or idle anyway.

Error while setting up platform androidtv
Traceback (most recent call last):
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_message.py", line 82, in unpack
    cmd, arg0, arg1, data_length, data_checksum, _ = struct.unpack(constants.MESSAGE_FORMAT, message)
struct.error: unpack requires a buffer of 24 bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 150, 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 "/config/custom_components/androidtv/media_player.py", line 153, in setup_platform
    state_detection_rules=config[CONF_STATE_DETECTION_RULES],
  File "/config/custom_components/androidtv/androidtv/__init__.py", line 47, in setup
    aftv = BaseTV(host, adbkey, adb_server_ip, adb_server_port, state_detection_rules)
  File "/config/custom_components/androidtv/androidtv/basetv.py", line 95, in __init__
    self.device_properties = self.get_device_properties()
  File "/config/custom_components/androidtv/androidtv/basetv.py", line 167, in get_device_properties
    constants.CMD_MAC_ETH0)
  File "/config/custom_components/androidtv/androidtv/adb_manager.py", line 147, in shell
    return self._adb.shell(cmd)
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_device.py", line 202, in shell
    return ''.join(self._streaming_command(b'shell', command.encode('utf8'), timeout_s, total_timeout_s))
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_device.py", line 526, in _streaming_command
    local_id, remote_id = self._open(b'%s:%s' % (service, command), timeout_s, total_timeout_s)
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_device.py", line 261, in _open
    cmd, remote_id, their_local_id, _ = self._read([constants.CLSE, constants.OKAY], timeout_s, total_timeout_s)
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_device.py", line 324, in _read
    cmd, arg0, arg1, data_length, data_checksum = unpack(msg)
  File "/config/custom_components/androidtv/androidtv/adb_shell/adb_message.py", line 84, in unpack
    raise ValueError('Unable to unpack ADB command. (length={})'.format(len(message)), constants.MESSAGE_FORMAT, message, e)
ValueError: ('Unable to unpack ADB command. (length=0)', b'<6I', b'', error('unpack requires a buffer of 24 bytes'))

It might be necessary to restart the Fire TV. If you collect some debugging logs, I’ll take a look.

logger:
  custom_components.androidtv.androidtv.adb_shell: debug

Edit

I think because you didn’t restart the Fire TV device, it didn’t successfully connect to it. That should have been the end of it, but due to a bug where the ADB connection attempt was falsely reported as successful, it tried to send a command to the device, and that led to your error.

This bug is fixed in the custom component (same link as before). So now it should either correctly report that the ADB connection could not be established or successfully setup the device.

Sorry for late respond, but it seems to work fine yet. Haven’t really watched it yet much but I will.

Thanks.

Thanks for reporting back! Let me know if there are any issues.

Hey,

A real problem I yet recognized is that the Plex status “playing” is often not recognized which breaks my “playing - paused” automation. So it recognized Plex but says “paused”.
It also doesn’t get solved by pausing and playing again. I haven’t really debugged it yet and tested if I can get it to work by restarting the app or so tho.
I think that was kinda the case before when I went for the ADB Server…

State detection is a known limitation. Your options are:

  1. Implement custom state detection rules
  2. Modify androidtv.py and/or firetv.py and submit a pull request (so that other people don’t need to figure out the state detection rules for themselves)

I’m testing my first noob-edition of the python addition now.

Modifying backend packages can be tricky in HA, so for testing purposes you may want to use this androidtv custom component. Modify the androidtv.py and/or firetv.py files until you get the state detection working correctly, then submit a pull request to the androidtv repo.

I only edited your components in custom_components/androidtv/androidtv/ and added:

            # Plex
            elif current_app == constants.APP_PLEX:
                #state = audio_state
                if (wake_lock_size == 1 and media_session_state == 3):
                    state = constants.STATE_PAUSED
                elif (wake_lock_size == 3 and media_session_state == 3):
                    state = constants.STATE_PLAYING
                else:
                    state = constants.STATE_STANDBY

I also edited my automation to react to “standby”. I yet only quickly used the Shield and it was working fine 2-3 times by changing from:

standby - playing
playing - paused
playing - standby

Those values at least don’t apply for the FireTV… It used “else: Standby” the whole evening. I yet only took off the media_session_state there but honestly I have no idea how to find out these values otherwise.

There’s a pull request in progress that suggests the logic for an Android TV should be:

            # Plex
            elif current_app == constants.APP_PLEX:
                if media_session_state == 3:
                    if wake_lock_size == 1:
                        state = constants.STATE_PAUSED
                    else:
                        state = constants.STATE_PLAYING
                else:
                    state = constants.STATE_STANDBY

You could try that.

You could also use this python_script to log info that would help with determining detection rules: [Testers needed!] Custom state detection rules for Android TV / Fire TV

That is kinda what I have.

Btw. I got the values publicy available from https://androidtv.readthedocs.io/en/stable/androidtv.basetv.html that is why I wondered why noone did that yet since it was too easy to be true. :smiley:

However that is applyable to the Shield accordingly to my quick test yesterday but as said not working for the FireTV.

Testing

            # Plex
            elif current_app == constants.APP_PLEX:
                if (wake_lock_size == 2 and media_session_state == 3):
                    state = constants.STATE_PAUSED
                elif (wake_lock_size == 5 and media_session_state == 3):
                    state = constants.STATE_PLAYING
                else:
                    state = constants.STATE_STANDBY

accordingly to “GET_PROPERTIES” command.

Right, I think the way I tried was too restrictive. Trying the format of the pull request.