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

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'

1 Like

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

Well, I’m no expert, but I did manage using this and the official documentation to get Hulu showing “playing” and “paused” via the below method. I couldn’t get “standby” nor “idle” but I’m using it for an automation that turns off my OLED to avoid burn in. If it notices the interactive sensor on my phone isn’t being used at certain times (30 min intervals) it will pause the firetv, then it will wait 5 minutes, then check to see if the firetv has been paused for 4.5 minutes, if so, it shuts down the whole bedroom and flips my switch made in helpers to track what time I fell asleep.

Anywho:
Add the device via IP in the Android TV integration, IDK if it matters, but I chose firetv specifically instead of auto to try to ensure it would work properly.
After it is added choose configure.


At the bottom, choose New Rule then Submit.

Then add

com.hulu.plus

&&

[{"playing": {"media_session_state": 3}}, {"paused": {"media_session_state": 2}}]


Press submit.
Enjoy!

Let me know if you figure out the other states, I don’t really need them, but if I can make something better, then I like to. That and who knows, maybe I’ll find a use in them one day? I originally had it in my config, and removed it on accident. Lost the state detection and couldnt figure out why. I actually switched to Chromecast for 2 weeks before returning them because their functions were pointless. If I asked for a show to play on Hulu, I was still required to press the enter button on the remote to make it play, so I switched back. Finally found this post and decided to try state detection, problems solved.

1 Like

Thanks, this has helped - I wasn’t clear on the format for the List of State Rules field. Appreciate the guidance!

1 Like