[Testers needed!] Custom state detection rules for Android TV / Fire TV

Sounds feasible. I wonder how much logic is reasonable to have in the component, that route looks like it would work for this use case but would it add too much complexity? Or perhaps following something along the line of quirks like the ZHA component uses so the logic isn’t kept in the config yaml?

I’m not familiar with the ZHA component.

That’s a valid point about too much complexity, and that’s the reason why I didn’t jump on this idea when it was first suggested in a GitHub issue. But I think the arguments in favor of this approach are:

  • It’s difficult, if not impossible, to include code in the androidtv package that will correctly detect the state for all apps on all devices.
  • I’ve asked for community support with the state detection and tried to make it as easy as possible to contribute, but that hasn’t gotten much traction.
  • Perhaps most importantly, this state_detection_rules config parameter is completely optional. If a user has no issues with how the state detection is working, they don’t need to do anything. But if they want the state detection to work better, this will allow them to fix it on their own instead of just posting on the forum that it doesn’t work.

Also, thanks for posting the output of those GET_PROPERTIES commands. I plan to incorporate that into some unit tests for this custom state detection code.

1 Like

Makes sense. I would suggest that adding a few of the relevant properties (media_session_state, audio_state, and wake_lock_size) as attributes would help debugging and creating better rules. It’s not like the androidtv.adb_command service is all that bad to run, just would be easier to be able to glance at the attributes to see what’s going on.

That’s a good idea, but it would require returning more values from the update method in the androidtv package. I’ll keep that in mind, but first I want to get custom state detection into the official HA component.

I updated the androidtv code and this revised approach is ready for testing.

https://github.com/JeffLIrion/ha-androidtv/tree/custom_state_detection/custom_components/androidtv

The only files you need to update are:

  • custom_components/androidtv/androidtv/basetv.py
  • custom_components/androidtv/androidtv/constants.py
  • custom_components/androidtv/androidtv/firetv.py

Modify your state_detection_rules parameter as above:

state_detection_rules:
  'com.plexapp.android':
    - 'playing':
        'media_session_state': 3
        'wake_lock_size': 3
    - 'paused':
        'media_session_state': 3
        'wake_lock_size': 1
    - 'standby'

That works perfectly!

For the record, I haven’t found any other apps so far that require this level of kludgery. All the rest (Hulu, Vudu, Google Movies, Netflix, Amazon, HBO Now) seem to set media_session_state to 3 when playing and 2 when paused. I’m using the rules to set that with a fallback to idle to prevent using audio_state completely.

1 Like

Thanks for testing it! I’ll submit a pull request shortly.

Sounds great. One other thought, any chance of being able to set a default set or exclusion for the state detection rules? I’m finding myself setting almost all of my video apps to exclude audio_state with this new Shield update as so:

      - 'media_session_state'
      - 'idle'

It would be nice to be able to just exclude that audio_state somehow by default rather than a bunch of duplicate entries.

You’re welcome to submit pull requests to the androidtv package and the HA component. My thoughts are:

  1. There’s already a lot of config variables for the Android TV component and the documentation is quite lengthy, so I’m reluctant to add more unless they provide a lot of value to the users (and I believe this state_detection_rules parameter does).
  2. Honestly, it’s much easier and less complicated – for both the user and the developers – to just have the user repeat those YAML lines a handful of times. Put it in your config, maybe use a !include, and then never look at it again!:smile:

Another approach to assisting with creating state detection rules would be a simple python script. Something like (not tested!):

# androidtv_state_detection_helper.py
entity_id = data.get('entity_id')
true_state = data.get('state')

hass.services.call('androidtv', 'adb_command', {'entity_id': entity_id, 'command': 'GET_PROPERTIES'})

time.sleep(1)

adb_response = hass.states.get(entity_id).attributes.get('adb_response')

logging.info('State = {0}: {1}'.format(true_state, adb_response))

Documentation in python_scripts/services.yaml

# services.yaml
androidtv_state_detection_helper:
  description: Log info about the current state of an Android TV / Fire TV device to help with creating custom state detection rules.
  fields:
    entity_id:
      description: The entity ID of the device. 
      example: media_player.android_tv_living_room
    state:
      description: The current state of the device.
      example: playing

Fair enough. I think I’m good, but that python script could be useful as others start using the feature.

This seems to be working pretty great. The stock androidtv component would rarely work for any apps on my 2 FireTVs for me. I think the only app that reported the correct state out of the box was Netflix.

With this setup however, the majority of them seem to work with any custom logic.

Those apps i tested with with were:

com.sling: “Sling”
org.chromium.youtube_apk: “YouTube”
com.netflix.ninja: “Netflix”

Hulu did need some custom logic which I was able to get to report an accurate Playing state with the following:

state_detection_rules:
      'com.hulu.plus':
        - 'playing':
              'wake_lock_size': 3
        - 'paused':
              'media_session_state': 3
              'wake_lock_size': 1
        - 'standby'

for me, when testing with androidtv.adb_command service with a command of GET_PROPERTIES, it would always return ‘None’ for a media_session_state and ‘wake_lock_size’: 3, which the above logic reflects.

This seems to work for me!

  - platform: androidtv
    name: 'SHIELD'
    device_class: androidtv
    host: x.x.x.x
    adb_server_ip: 127.0.0.1
    apps:
     org.xbmc.kodi: "Plex (Kodi)"
     com.netflix.ninja: "Netflix"
     com.plexapp.android: "Plex"
     com.spotify.tv.android: "Spotify"
     com.google.android.youtube.tv: "Youtube"
     com.android.tv.settings: "Settings"
     com.google.android.tvlauncher: "Dashboard"
    state_detection_rules:
      'com.netflix.ninja':
        - 'media_session_state'
        - 'playing':
            'wake_lock_size': 2
        - 'paused':
            'wake_lock_size': 1
        - 'standby'
      'org.xbmc.kodi':
        - 'media_session_state'
        - 'playing':
            'wake_lock_size': 3
        - 'paused':
            'wake_lock_size': 2
        - 'standby'
      'com.android.tv.settings':
        - 'standby'
      'com.google.android.tvlauncher':
        - 'standby'

2 Likes

Has this made it into the official releases?

Yes

1 Like

More of a heads up. I noticed Plex updated their media player in the last week or so for Android TV.

This is now my current config which seems to catch the new states correctly.

Playing seems to almost always be:

wake_lock_size: 3
media_session_state: 3

(Sometimes the wake_lock_size changes to a 4 or something else)

Paused always seems almost to always be:

wake_lock_size: 1
media_session_state: 2

(Sometimes the wake_lock_size isn’t always one like when scrubbing through)

Since there are a lot of transient states mentioned above I’ve changed my config to this.

media_player:
  - platform: androidtv
    name: Shield
    device_class: androidtv    
    host: 10.0.0.10
    adb_server_ip: 10.0.0.9
    apps:
      com.plexapp.android: "Plex"
    state_detection_rules:
      'com.plexapp.android':
        - 'playing':
            'media_session_state': 3
        - 'paused':
            'media_session_state': 2 
        - 'standby'
1 Like

It’s not working properly for me. When something is running, media_session_state seems to stay at 3 but wake_lock_size moves between 3, 4 and 5. Pausing Plex (just pause not going “away” from the movie) leaves media_session_state at 3 and sets wake_lock_size down to 2 (but up again randomly, for a few seconds at a time). So there is no absolute way to differentiate, I think.

The following works to have playing always correct. But pause/standby randomly gets set to playing for an instant and then back. For simplicity I removed “paused” altogether.

state_detection_rules:
      "com.plexapp.android":
        - "playing":
            "media_session_state": 3
            "wake_lock_size": 3
        - "playing":
            "media_session_state": 3
            "wake_lock_size": 4
        - "playing":
            "media_session_state": 3
            "wake_lock_size": 5
        - "standby"

Is there anyway to set a range, so I don’t have to repeat all those lines?

I think I’ve change some things around since an update to the Plex app shifted the states around again (when they rolled out the new UI). I do remember experiencing the random paused -> play state trigger. But I can’t recall the last time it happened. This is what my config is now.

media_player:
  - platform: androidtv
    name: Shield
    device_class: androidtv    
    host: X.X.X.X
    adb_server_ip: X.X.X.X
    apps:
      com.plexapp.android: "Plex"
    state_detection_rules:
      'com.plexapp.android':
        - 'playing':
            'media_session_state': 3
        - 'paused':
            'media_session_state': 2 
        - 'standby'
1 Like

I know this was posted like 3 years ago, but thank you for this! I couldn’t figure out what to do about Hulu. Found this, worked instantly. THANK YOU.

Hi @Pronown

Did you maintain these state detection rules through the UI or configuration file? I have setup the integration using the UI and it has generated a UI, however depending on the app, I’m getting inaccurate states - hence I would like to lean on the work done in this thread.

My only issue, there is no documentation on how to maintain these in the UI despite the feature being available. If you could provide some guidance, that would be awesome!

Thanks

1 Like