Nvidia shield (androidtv) play/paused status problem

Hi everybody,

I recently got an nvidia shield and now want to integrate it into Home Assistant. I do have an entity media_player.nvidia_shield. When I play a video in the youtube app, it will successfully change the state to playing, and when I pause it to paused (there is even an idle state when it is running but not playing anything).

However, when I play anything via plex app, it will remain its last status from outside plex no matter what I do. When I start playback, or when I pause/resume playback, the state will not change. All or most other apps (haven’t tried all yet but seems like it) work fine, by that I mean the update the status to its actual value - only the plex app does not.

We mainly use plex for media playback, and I want an automation like “when plex changes from playing to paused, turn on lights”; I do have this automation, and it does work for my fire tv (but onn the fire tv I use plex inside the kodi player, which creates an additional entity media_player.plex_on_kodi_localhost(or similar; I cannot see the entity at the moment)).

While I can work with that additional entity on the fire tv, I would prefer not to run plex inside of kodi on my shield but rather use the stand alone plex app for android tv.

Have any of you encountered this problem and know how to fix it? I could work around it by installing kodi, then the kodi plex app, on my shield, but if this is not necessary, I’d prefer not to.

This has been semi-buggy on the fire tv as well, but might be due to my automation; when I play something in plex (in kodi) there upon starting the device, it works fine; but once I had played something outside plex (youtube, for example), it will sometimes update the status correctly, and sometimes not. Weird!

Thanks for your ideas :slight_smile:

Are you using the default androidTV component ? Then what you are asking should be possible. I use it to start a Harmony HUB activity when a specific app starts. Below is an example for Netflix. The extra condition is for checking it the activity isn’t already started.

- alias: ATV_Netflix
  trigger:
  - platform: template
    value_template: '{{ states.media_player.nvidia_shield_tv.attributes.app_name == "Netflix" }}'
  condition:
  - condition: template  
    value_template: '{{ states.remote.woonkamer.attributes.current_activity != "Films kijken" }}'
  action:
    service: remote.turn_on
    data:    
      entity_id: remote.woonkamer
      activity: "Films Kijken"
1 Like

And ofcourse you can also use the Plex component in Home Assistant. Then Home Assistant can also show media info.

1 Like

Thank you!

I am using both; the media_player for android tv and the plex sensor. Here are both current states:

media_player.nvidia_shield 	paused 	
volume_level: 1
is_volume_muted: false
app_id: com.plexapp.android
app_name: Plex
source: hdmi
adb_response: null
friendly_name: nVIDIA Shield
supported_features: 21945
media_player.plex_shield_android_tv 	playing 	
is_volume_muted: false
media_content_id: 20290
media_content_type: movie
media_duration: 6114
media_position: 129
media_position_updated_at: 2019-11-15T11:55:02.129026+00:00
media_title: In the Tall Grass (2019)
app_name: Movies
media_content_rating: null
session_username: 
media_library_name: Movies
friendly_name: Plex (SHIELD Android TV)
entity_picture: /api/media_player_proxy/media_player.plex_shield_android_tv?token=
supported_features: 21301

When I toggle pause, the plex sensor will change its status to paused, however, the media_player will always stay on paused (and when I toggle again, it will not change to playing, either). The really big issue for me is this: let’s say I am watching something on plex and pause it; now I assume that my lights will go on. However, when I then watch something on youtube/netflix and pause it, the plex sensor will be paused or idle (as I am not currently using plex but another app), while the media_player entity will either be playing or paused. Now, I’d like my lights to toggle regardless what app I am watching on, as long as it’s state changes from playing to paused. But if I need two separate entities for the automation (or a condition), this will get kinda confusing.

In other words: I would expect the media_player.nvidia_shield entity to change its status to playing when something is playing on plex as this means it is also playing on the shield at the same time (because plex is running on that device).

Oke, if you wan’t to change the lights regardless of the app that is playing your best bet is to use the status of the AndroidTV component mediaplayer. Otherwise you have to get quite complex with conditions (like you already mentioned… :wink:). I don’t use plex myself but i also see that the status doesn’t work correct with specific apps.

Did you see the new “Custom State Detection” in the androidTV component ? I haven’t tried it myself but it seems that you can add rules for specific apps. Maybe that can solve your issue. I the example configuration there’s an entry for Plex.

I just looked at them, but don’t quite understand how to work with them (will have to read slowly once more :wink: )

Below are my updated automations; I would assume they’d work, but they don’t. Also, I had a condition like

condition:
  condition: state
  entity_id: media_player.plex_nvidia_shield_android_tv
  state: "unavailable"

in the rule for the shield itself (so that the plex sensor will not mess with the playing/paused status for anything but plex itself), but that doesn’t work at all. Also, the media_player.plex_nvidia_shield_android_tv entity does only then exist when it is running; once I close plex, the entity disappears until I start it again, making it very difficult (for me!) to work with that entity all together).

Therefore, I removed that condition. Now when I toggle play/pause, nothing happens with any of those lights. I noticed that sometimes!! the media_player.nvidia_shield entity will toggle the status after I toggled it; however, sometimes this takes over half a minute, sometimes even longer, sometimes it won’t change states at all.
((usually when watching a movie and pausing, it’s to grab some water or for a bathroom break, so I cannot wait about a minute for the lights to turn on :smiley: might as well be back by then))

automation:
  - id: 'light_plex_pause'
    alias: "[Licht] Plex Pause"
    trigger:
      - platform: state
        entity_id: media_player.plex_shield_android_tv
        from: "playing"
        to: "paused"
    action:
      - service: python_script.light_store
        data:
          store_name: sz_nachttisch
          entity_id: light.schlafzimmer_innr_light
      - service: python_script.light_store
        data:
          store_name: sz_bett
          entity_id: light.schlafzimmer_led_bett
      - service: python_script.light_store
        data:
          store_name: sz_leiste
          entity_id: light.sz_led_seite
      - service: light.turn_on
        data:
          entity_id: light.schlafzimmer_innr_light
          rgb_color: [255, 176, 67]
          brightness: 55
          transition: 5
          color_temp: 500
      - service: light.turn_on
        data:
          entity_id: light.schlafzimmer_led_bett
          rgb_color: [255, 255, 255]
          brightness: 50
          transition: 5
          effect: "None"
      - service: light.turn_on
        data:
          entity_id: light.sz_led_seite
          rgb_color: [255, 255, 255]
          brightness: 50
          transition: 5
          effect: "static"

  - id: 'light_plex_resume'
    alias: "[Licht] Plex Resume"
    trigger:
      - platform: state
        entity_id: media_player.plex_shield_android_tv
        from: "paused"
        to: "playing"
    action:
      - service: python_script.light_store
        data:
          store_name: sz_bett
          operation: restore
      - service: python_script.light_store
        data:
          store_name: sz_leiste
          operation: restore
      - service: python_script.light_store
        data:
          store_name: sz_nachttisch
          operation: restore

  - id: 'light_plex_off'
    alias: "[Licht] Plex Aus"
    trigger:
      - platform: state
        entity_id: media_player.plex_shield_android_tv
        to: "unavailable"
    action:
      - service: pythong_script.light_store
        data:
          store_name: sz_bett
          operation: restore
      - service: pythong_script.light_store
        data:
          store_name: sz_leiste
          operation: restore
      - service: pythong_script.light_store
        data:
          store_name: sz_nachttisch
          operation: restore

  - id: 'light_shield_pause'
    alias: "[Licht] Shield Pause"
    trigger:
      - platform: state
        entity_id: media_player.nvidia_shield
        from: "playing"
        to: "paused"
    action:
      - service: python_script.light_store
        data:
          store_name: sz_nachttisch
          entity_id: light.schlafzimmer_innr_light
      - service: python_script.light_store
        data:
          store_name: sz_bett
          entity_id: light.schlafzimmer_led_bett
      - service: python_script.light_store
        data:
          store_name: sz_leiste
          entity_id: light.sz_led_seite
      - service: light.turn_on
        data:
          entity_id: light.schlafzimmer_innr_light
          rgb_color: [255, 176, 67]
          brightness: 55
          transition: 5
          color_temp: 500
      - service: light.turn_on
        data:
          entity_id: light.schlafzimmer_led_bett
          rgb_color: [255, 255, 255]
          brightness: 50
          transition: 5
          effect: "None"
      - service: light.turn_on
        data:
          entity_id: light.sz_led_seite
          rgb_color: [255, 255, 255]
          brightness: 50
          transition: 5
          effect: "static"

  - id: 'light_nvidia_resume'
    alias: "[Licht] Nvidia Resume"
    trigger:
      - platform: state
        entity_id: media_player.nvidia_shield
        from: "paused"
        to: "playing"
    action:
      - service: python_script.light_store
        data:
          store_name: sz_bett
          operation: restore
      - service: python_script.light_store
        data:
          store_name: sz_leiste
          operation: restore
      - service: python_script.light_store
        data:
          store_name: sz_nachttisch
          operation: restore

Maybe @JeffLIrion can help ?

I don’t use Plex, but as @hvdheurik suggested, I think the answer is to use custom state detection. Try the example from the full configuration in the documentation. You can also use this python script to help you to determine what the rules should be.

Thank you everybody! I used the example from full configuration copying exactly what was listed for plex.

For some reason, it kinda works now, but not in a way that I can work with:

  • OK = start plex app (state: standby)
  • OK = start playback in plex (state: playing)
  • OK = pause playback in plex (state: paused)
  • OK = start playback again (state: playing)
  • ERROR = pause playback again (STILL state: playing)
  • OK = stop playback completely while still in plex (state: standby)

So I can once get a paused state via media_player.nvidia_shield, but after that, it will not pick up paused again until I stop playback, start playback, and then pause.

These transitions take about 10 seconds. While this is similar in other apps (netflix, for example), those other apps will report paused each time that I actually pause. Only plex will not do this.

Might this sluggish behaviour (about 10 seconds for state update) have to do with my WiFi? Or is this a normal time periode? Also, when I switch apps, their app_id (for example de.prosiebensat1digital.seventv) takes considerably less than 10 seconds to update; so changing apps is reported more frequently than play state???

This is my config atm

# Kommandos siehe auch hier
# https://github.com/JeffLIrion/python-androidtv/blob/bf1058a2f746535921b3f5247801469c4567e51a/androidtv/constants.py#L143-L186

# {{{ nVIDIA Shield TV
media_player:
  - platform: androidtv
    name: nVIDIA Shield
    host: !secret nvidia_host
    adb_server_ip: !secret adb_server_ip
    adb_server_port: !secret adb_server_port  
    get_sources: true
    device_class: auto

    apps:
      com.netflix.ninja: "Netflix"
      com.google.android.tvlauncher: "Homescreen"
      com.google.android.youtube.tv: "YouTube"
      com.zdf.android.mediathek: "ZDF"
      de.rtli.tvnow: "RTL Now"
      com.amazon.amazonvideo.livingroom: "Amazon Video"
      de.prosiebensat1digital.seventv: "Joyn"
    # turn_on_command: "input keyevent 3"
    # turn_off_command: "input keyevent 223"

    state_detection_rules:
      'com.netflix.ninja':
        - 'media_session_state'
      'com.plexapp.android':
        - 'paused':
            'media_session_state': 3  # this indentation is important!
            'wake_lock_size': 1       # this indentation is important!
        - 'playing':
            'media_session_state': 3  # this indentation is important!
        - 'standby'
      'com.amazon.avod':
        - 'playing':
            'wake_lock_size': 4  # this indentation is important!
        - 'playing':
            'wake_lock_size': 3  # this indentation is important!
        - 'paused':
            'wake_lock_size': 2  # this indentation is important!
        - 'paused':
            'wake_lock_size': 1  # this indentation is important!
        - 'standby'


The Android TV component polls for an update every 10 seconds.

You could try to fine tune your state detection rules, but I think a better approach is to use both entities as triggers for your automation. My syntax will probably be wrong, but something like:

automation:
  - id: 'light_plex_pause'
    alias: "[Licht] Plex Pause"
    trigger:
      - platform: state
        entity_id:
          - media_player.plex_shield_android_tv
          - media_player.plex
        from: "playing"
        to: "paused"
    condition:
      - condition: template
        value_template: >
          {% if is_state('media_player.plex', 'unavailable') %}
            true
          {% elif trigger.to_state.entity_id == 'media_player.plex' %}
            true
          {% else %}
            false
          {% endif %}
    action:
      ...

Hi there,

I’ve got the same problem since the upgrade to v0.101. It wasn’t working either in 0.99 and there was a discussion somewhere that I took part in where the issue was found and fixed in 0.100. If I use Plex and even other apps that provide video playback, the Android TV media player is stuck on paused. I had the automation that dims the lights working so well only when the Plex app was used and now it is not working any more.

I would prefer if owners of the Nvidia Shield or any Android TV device can chime in and confirm this? Perhaps we need to log an issue on Github, but the more that report the same behavior, makes the logging of the issue a bit more palatable.

1 Like

@JeffLIrion thank you. I will try this later. An issue that might occur again is that sometimes plexes state might be playing, while nvidia_shield is still at paused (even though it is actually playing, as plex is playing). So the automation might still not know what to do as both entities have opposite states…?

Also, I tried using your script, but could not figure out how to. When I run it from “developer tools” => “services”, I don’t get any output… However, since I am using the exact example from full configuration, shouldn’t it just work™ :wink: ? The states should be correct as they are taken directly from the example.

@ipodmusicman I think that is a good idea! I have not reported an issue on Home Assistant github yet, but perhaps you could do this and link to this post? I am willing to provide any logs that might help to figure this out.

I did notice this morning that while playing YouTube, the status displayed correctly while on Plex, it was not. I just need to check if other video playing apps are displaying the same behavior or if it is a Plex only situation.

The condition will use the state of the Plex media player and ignore state changes in the Android TV media player when Plex is running.

Did you provide service data to the script, as the corresponding documentation indicates? You could change logging.info to logging.critical.

There is no issue. The logic for determining the state can vary between devices, so if you want it to report the correct state then you have to determine the correct custom state detection rules for a given app on your device.

1 Like

@ JeffLIrion the thing is that this worked flawlessly in 0.100 and I didn’t need to put in special logic for special states at all.

I tested other apps on the Shield and they work just fine. YouTube, Spotify, Netflix and even DSTV Now (our local pay TV network’s streaming app). It is only when Plex is playing on the Shield, that the status shows as Paused which is rather odd. I know that Plex received an update on Android TV not too long ago, so not sure if this is either coincidence or not.

The state detection logic in the androidtv package differs for each app. The logic for Plex that’s in the current HA version hasn’t changed in a long time, although it will change in HA 0.104 to the logic captured by the state detection rules in the full configuration example. So it could be that the Plex app changed, or it could be that something else changed on your Android TV device.

Came looking since I have the same problem with states!
Bought a new Shield TV to replace my old rpi solution, for me it’s like this
Start plex and start playing = status playing
Pauses = status paused
Resumes playing = status paused
On the card in the frontend of hass It shows as paused, pressing the play button does start the playback and I can toggle it from home-assistant but the card never updates to playing nor the status.

I believe this is a problem in communication between shield and hass. I am currently playing video on the shield via amazon prime video app. It had been paused, but is playing now, still those lights (that are supposed to be during pause only on due to the automation I wrote) are still on.

Then again, plex seems to sometimes work correctly now. Toggling play and pause positively did toggle those lights most of the time, but not all the time.

We could still use this workaround and run play inside of kodi, because this seems to report the play / pause state immediately (quicker than any other app on the shield and / or firetv, though that might just be the personal impression I got), but just the fact that it ought to work without a workaround makes me not want to do this (besides , the key app on android tv is pretty decent and doesn’t require one to use kodi as a “middleman”).

Do all of you shield users get the “source” drop down menu in Home Assistant? On my firetv, I can, for example, start the YouTube app from Home Assistant via this drop down menu, yet it is entirely missing on the media_player.shield entity (regardless of the extra settings from the docs page I have tried).

This wasn’t explained as clearly as I thought in the documentation, so I submitted a pull request to update it.

The Android TV integration works by polling the Android TV / Fire TV device at a regular interval and collecting a handful of properties. Unfortunately, there is no standard API for determining the state of the device to which all apps adhere. Instead, the backend androidtv package uses three of the properties that it collects to determine the state: audio_state , media_session_state , and wake_lock_size . The correct logic for determining the state differs depending on the current app, and the backend androidtv package implements app-specific state detection logic for a handful of apps. Of course, it is not feasible to implement custom logic for each and every app in the androidtv package. Moreover, the correct state detection logic may differ across devices and device configurations.

The solution to this problem is the state_detection_rules configuration parameter, which allows you to provide your own rules for state detection.

…

Android TV documentation (preview)

Hi folks,

This was fixed in 0.103 of HA. All is good in the world now. :slight_smile: