JeffLIrion / python-androidtv

Communicate with an Android TV or Fire TV device via ADB over a network.
MIT License
165 stars 57 forks source link

How to help with state detection! #12

Open JeffLIrion opened 5 years ago

JeffLIrion commented 5 years ago

State detection diagnostics

Assuming you're using the Home Assistant Android TV component, here's how you can help improve state detection.

This package determines the state in the AndroidTV.update / FireTV.update methods using a collection of properties and reports that state to Home Assistant. You can see what those properties are by using the HA service androidtv.adb_command with "GET_PROPERTIES" as the command argument -- they will be logged at the INFO level and they will be stored in the media player's adb_response attribute (HA 0.94+), which can easily be viewed on the States tab. You can read more about the androidtv.adb_command service at the bottom of the Android TV documentation.

The state detection logic will differ depending on the app. So open an app, send the "GET_PROPERTIES" command a few times while it's idle / on standby, playing, and paused, and try to figure out a better way to determine the state. Pull requests are welcome!

earth08 commented 5 years ago

Thi I get when I get properties on playing video on vlc custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 3, 'media_session_state': 3, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 4}

On paused

custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 1, 'media_session_state': 2, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 4}

What should be added or change in order to get proper player status

JeffLIrion commented 5 years ago

Thi I get when I get properties on playing video on vlc custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 3, 'media_session_state': 3, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 4}

On paused

custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 1, 'media_session_state': 2, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 4}

What should be added or change in order to get proper player status

It looks like the media_session_state property is what you want to use. See here: https://github.com/JeffLIrion/python-androidtv/blob/38ac4fc7346d092d423aa0ecdfcd9110097c2648/androidtv/firetv.py#L150-L155

It would be great if you could fork the repo, make some changes, test it yourself, have others test it, and submit a pull request!

JeffLIrion commented 5 years ago

@earth08 the "state-detection" branch should yield better results.

JeffLIrion commented 5 years ago

@earth08 is it working now? Is the state detection working for VLC?

earth08 commented 5 years ago

Sorry to reply it lately, It is working, But I found a new error, When device is on home or any app in normal position, it shows paused.

earth08 commented 5 years ago

this are the results from some few apps it does works perfectly on vlc, but on home it shows as paused, is there any comman wasys of getting the media state to verify and than link with current app?

here are output at screensaver idle

2019-03-16 08:01:53 INFO (SyncWorker_4) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': False, 'wake_lock_size': -1, 'media_session_state': None, 'current_app': None, 'audio_state': None, 'device': None, 'muted': None, 'volume_level': None}

outpt at homescreen

2019-03-16 08:03:40 INFO (SyncWorker_6) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 0, 'media_session_state': None, 'current_app': {'package': 'com.google.android.leanbacklauncher', 'activity': 'com.google.android.leanbacklauncher.MainActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 9}

home as puased

output on vlc it does shows as standby

2019-03-16 08:15:10 INFO (SyncWorker_9) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 0, 'media_session_state': None, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.tv.MainTvActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 9}

output when playing on vlc

2019-03-16 08:17:02 INFO (SyncWorker_11) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 3, 'media_session_state': 3, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 3}

output when vlc paused

2019-03-16 08:18:13 INFO (SyncWorker_12) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.minim8s2': {'screen_on': True, 'awake': True, 'wake_lock_size': 0, 'media_session_state': 2, 'current_app': {'package': 'org.videolan.vlc', 'activity': 'org.videolan.vlc.gui.video.VideoPlayerActivity'}, 'audio_state': 'idle', 'device': 'hdmi', 'muted': False, 'volume_level': 3}

JeffLIrion commented 5 years ago

I removed some posts that weren't directly related to state detection.

I'm leaving it up to you and the community as a whole to collect data (as you've done) and implement better state detection. It's not that hard to modify the code, and as long as you don't have any syntax or programming errors, nothing catastrophic will happen if your state detection logic is flawed.

earth08 commented 5 years ago

After some study on my output, I found that many apps don’t provide a media_session_state, The provide wake_lock_size, So I modify some line is homeassistant updates like below, Which is working good, The only thing, with this changes, I found that, when device is off, It does shows off, but activity is shown as standby. Another thing I found is when device is on screensaver wake_lock_size is -1, How to get Screen Saver displayed.

EDIT: please use code blocks!

        else:
            if wake_lock_size == 1: 
                state = constants.STATE_PAUSED 
            elif wake_lock_size == 2: 
                state = constants.STATE_PLAYING 
            else: 
                state = constants.STATE_STANDBY

#  ###      else:
#  ###          if wake_lock_size == 1:
#   ###             state = constants.STATE_PLAYING
#  ###          else:
# ###               state = constants.STATE_PAUSED
earth08 commented 5 years ago

state off is now working well when device is turned off it does shows off for few seconds and after after that it shows unavailable. Is it behavior correct? should it be shown as off

BnMcG commented 5 years ago

I've also found (with the Jellyfin app), that there are two wake locks when playing, and one when paused. Perhaps the default of "1 wake lock == paused" should be changed, or was that value chosen specifically?

This was on a Fire TV stick.

JeffLIrion commented 5 years ago

state off is now working well when device is turned off it does shows off for few seconds and after after that it shows unavailable. Is it behavior correct? should it be shown as off

'Unavailable' means that the ADB connection is not intact. Since HA can't turn the device on, I think unavailable is the appropriate state. But that has to do with the Home Assistant component, not this package.

JeffLIrion commented 5 years ago

I've also found (with the Jellyfin app), that there are two wake locks when playing, and one when paused. Perhaps the default of "1 wake lock == paused" should be changed, or was that value chosen specifically?

This was on a Fire TV stick.

That is the logic used in the firetv package so that's what I used.

I think the wake_lock_size behavior differs from app to app. I don't want to change the default behavior at this time, but you can submit a pull request with logic that is specific to the Jellyfin app. It's pretty simple to do:

  1. In constants.py, add an APP_JELLYFIN = <Jellyfin app ID> constant. Add its friendly name to the APPS dictionary (i.e., APP_JELLYFIN: 'Jellyfin'). For both of these, please follow alphabetical order.
  2. In firetv.py, in the update method, add in a block for your state detection.

    # Jellyfin
    elif current_app == constants.APP_JELLYFIN:
       ...
BnMcG commented 5 years ago

Great, I'll do that shortly

BnMcG commented 5 years ago

I've raised #17 to fix this for Jellyfin

Molodax commented 5 years ago

Hi,

Unfortunately, some changes in the state logic made it "playing" all the time instead of "pause" for my case (Philips TV). It was some version when it was correct playing/pause section, but I cannot find that vestion anymore. I run the component on hassio and am trying to contribute to the states detection, however, get this output:

2019-03-31 19:36:03 INFO (SyncWorker_7) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.android_tv': '/system/bin/sh: GET_PROPERTIES: not found\n'

Any idea what is wrong?

JeffLIrion commented 5 years ago

Hi,

Unfortunately, some changes in the state logic made it "playing" all the time instead of "pause" for my case (Philips TV). It was some version when it was correct playing/pause section, but I cannot find that vestion anymore. I run the component on hassio and am trying to contribute to the states detection, however, get this output:

2019-03-31 19:36:03 INFO (SyncWorker_7) [custom_components.androidtv.media_player] Output of command 'GET_PROPERTIES' from 'media_player.android_tv': '/system/bin/sh: GET_PROPERTIES: not found\n'

Any idea what is wrong?

You're not using the right component. Use the official component.

https://github.com/home-assistant/home-assistant/blob/50a0504e07c971874a1bedf99ebd17a5383c88b1/homeassistant/components/androidtv/media_player.py#L316-L317

lolouk44 commented 4 years ago

Just chirping in to confirm that

                 if media_session_state == 2: 
                     state = constants.STATE_PAUSED 
                 elif media_session_state == 3: 
                     state = constants.STATE_PLAYING 
                 else: 
                     state = constants.STATE_STANDBY 

Is the way to go for Amazon Video too on a Fire TV 4K I'll try and do a PR (never done before) and see how it goes

t0mmy44-h commented 3 years ago

Hi Jeff, I have a Kogan TV (I think it's a rebranded TCL, or similar... not really sure who manufactured it as Kogan uses a few OEMs) and currently the hdmi_input detection doesn't work for me.

The following adb command does work, if I patch it into the python on my instance:

dumpsys hdmi_control | grep -o "mActiveRoutingPath: 0x[1-9]" | grep -o '[1-9]'

How can I go about getting this into the package for TVs that it works on?

JeffLIrion commented 3 years ago

This issue needs to be done first: https://github.com/JeffLIrion/python-androidtv/issues/255

After that's done, it shouldn't be too hard to customize the command used the get the HDMI input and the code that processes the result.