pyatv
pyatv copied to clipboard
Device and power state are not aligned
Describe the bug
Device and power states are managed independently by pyatv. Unfortunately, the power state is a bit unreliable and it sometimes happens that it reports Off
even though something is playing. One such case is when using the Apple TV as an AirPlay receiver, only to receive and play audio but not use any screen as output. The power state more or less mirrors if there is a monitor on or not (which is not totally true either because turn_on
with Companion will cause the power state to be reported on On
even if no screen is on). So it's a pickle...
My suggestion is to at least change power state to on when something is playing as that makes more sense. It will potentially trigger lots of changes between on and off whenever media plays or not, so that's the flipside of this.
Error log
No response
How to reproduce the bug?
Stream audio to an Apple TV without having the TV turned on: pyatv shall report Off
as power_state
but still provide a playing state.
What is expected behavior?
Power state should be reported as On
.
Operating System
Any
Python
Other
pyatv
any
Device
Apple TV 4 and later
Additional context
Reported here: https://github.com/postlund/pyatv/issues/1333#issuecomment-961279579
I think you narrowed it down pretty well, and it should be a nice solution for my use case. 😄 You're also right on the flip sides. But I think most scenarios shouldn't be hampered too much as any playback automatically stops, as far as I know, when you actually "turn off" the Apple TV. Or when you turn off the CEC connected receiver or TV.
Great! Yeah, I think this is "as good as it gets" based on how things work. I'm gonna work on a few backlogged features for the component that has been down prioritized for way too long and possibly try to fix this after that. My backlog is way to long!
Don't sweat about it, I'm assuming this is still mostly a hobby, so it's better to make sure it stays fun by not spending too much time on it. 🙂
It's a hobby, but I like spending time on it so I try to improve it whenever I can 😄
I'm getting closer to the target but it is pretty tricky as it requires some intricate changes to the internal state handling. There is a big overlap with #1301 here so it will be a good change as a preparation for that feature in the future (I hope that I can implement that soon). Hopefully I can have something ready to test within a few days as I have some addition bugs to address.
Sure thing, if there's anything you want me to test, let me know! I have CEC and non-CEC setups here.
I've found a work-around in the meantime. Because everything's working correctly for me right after a HA restart. As long as I don't touch the power controls in HA or turn on the connected TV (which I rarely do luckily), it assume power is on, and doesn't shift away from it, haha.
So, I have pushed my changes now to #1519. It would be great if you could help me out and test it a bit. Simplest I would say is to use atvscript
as it will print both play and power state. So basically:
- Install the PR in a venv
- Get some AirPlay credentials unless you already have it (
atvremote -s <ip> --protocol airplay
) - Start atvscript:
atvscript -a <ip> --airplay-credentials <credentials from above>
Observe reported power state. You should never get duplicates, e.g. multiple "on" in a row. If "off" is reported it shall change to "on" if you start to play something and then (usually) return back to "off" again, unless the device decides to change power state. Some apps change play state multiple times when switching media, so you could potentially see some switching back and forth when this happens (please report if you notice this). I intend to add a small filter here to report "off" a second or so after that the state changed to filter out these kinds of situations.
I'll try and let you know my results this week ASAP!
I merged the PR yesterday as I need the changes for another issue, so you can run directly from master
and report any issues from there.
Some initial findings, I used the push_updates
command as that seemed the most relevant.
When starting the command the TV and receiver were on, and nothing was playing.
{"result": "success", "datetime": "2021-12-13T16:12:06.751520+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:12:06.753888+01:00", "hash": "gnNF4NFEw\u22064pkgSH8p6", "media_type": "music", "device_state": "paused", "title": "Dangerous (feat. Akon) [feat. Akon]", "artist": "Kardinal Offishall", "album": "Not 4 Sale", "genre": "Hiphop/Rap", "total_time": 246, "position": 112, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Then I unpaused the music using the remote on my iPhone and skipped a song:
{"result": "success", "datetime": "2021-12-13T16:12:28.424415+01:00", "hash": "gnNF4NFEw\u22064pkgSH8p6", "media_type": "music", "device_state": "playing", "title": "Dangerous (feat. Akon) [feat. Akon]", "artist": "Kardinal Offishall", "album": "Not 4 Sale", "genre": "Hiphop/Rap", "total_time": 246, "position": 113, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:12:38.472958+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": null, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:12:39.836518+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "playing", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": null, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Then I turned off the TV. The receiver was still on, as per the disabled CEC functionality. But the Apple TV stopped playing anyway, so I'm guessing the ATV is still receiving those signals, but check the power state events:
{"result": "success", "datetime": "2021-12-13T16:13:28.344620+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 22, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:13:28.437542+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 41, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:13:28.477203+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:13:30.033642+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:13:35.278083+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:13:36.164317+01:00", "power_state": "on"}
It toggled a coupled of times between off and on, but it ended with on. 😅 (Which I'm not 100% sure is correct at this point.) So then I turned off the receiver:
{"result": "success", "datetime": "2021-12-13T16:14:09.839683+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:14:10.742242+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:14:28.427660+01:00", "power_state": "off"}
Another quick power_state toggle in quick succession, but an off state 18 seconds later 🤔
So then I started some music on my iPhone again with the "Control other speakers and TV's" button.
{"result": "success", "datetime": "2021-12-13T16:21:55.728893+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "playing", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 41, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:22:01.310172+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 46, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:22:01.500750+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:22:05.341217+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "playing", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 46, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Here my HA automations come in action, if it sees the ATV change to playing state, it turns on my receiver and switches to the right source. When this happens, the ATV pauses itself again. So I start playing 3 seconds later automatically.
So at least for me it doesn't break things, and it seems I end up with the correct power_state as well, eventually. Because automatically starting playing after 3 seconds didn't work before if the power_state
from HA's point of view switched to off, because it wouldn't allow playing in that state. Now the power_state is on
so I would assume that would allow HA to start playing again. It does all feel a bit fragile though. 😬 (Not caused by pyatv necessarily I think.)
These are some interesting findings. It's a bit tricky to know what is actually happening here since we are aggregating two sources to derive one final state. If we take this behavior for instance:
{"result": "success", "datetime": "2021-12-13T16:13:28.344620+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 22, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:13:28.437542+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 41, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:13:28.477203+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:13:30.033642+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:13:35.278083+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:13:36.164317+01:00", "power_state": "on"}
Why is it toggling like that? IMHO it shouldn't, but it might as well be a side-effect of some HDMI negotiation. The same goes for this one:
{"result": "success", "datetime": "2021-12-13T16:14:09.839683+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-13T16:14:10.742242+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-13T16:14:28.427660+01:00", "power_state": "off"}
Why would this happen? Not sure. We could look at the logs but I believe they will be rather huge, so I'll prepare a small change that adds debug prints for what is happening under the hood. Maybe we can see some patterns from there. I want it to feel stable without too much jitter (I can't guard for everything obviously, but as much as possible).
I experimented a bit with my setup... Let's say that my Apple TV is off as well as the receiver it is connected to. If I run atvscript push_updates
, it will tell me that power state is "off". Fine. Then, from another shell i turn the Apple TV off via atvremote -s <...> --companion-credentials <...> turn_off
- what happens? The Apple TV turns on, of course. There's nothing from MRP that I can use to deduce any other state, so I guess this will be somewhat unstable... I will try to explore other alternatives.
Turning the receiver on whilst the Apple TV is off does not trigger any state change in my case. Not until I do something else, like send the menu key.
what happens? The Apple TV turns on, of course.
Haha yeah it makes sense in a way 😅 Would it be possible to make power_state optional for the next release at least? So that people who have CEC can use it and see if it's working for them? And to have an option to disable it completely because it totally breaks all my automations when it's "turned off" all the time in HA and I cannot get it to turn on anymore. Because I do have a hard time thinking what would specify it being turned on if nothing's playing, and you don't have a CEC receiver or TV for it to determine their state as well.
It all feels a bit limited by tvOS 15 as wel.. In the Living Room I have a 2nd gen 4K ATV hooked up to a Denon AVR-X1600H with an LG B9 OLED, so all relatively new stuff. But if I turn on the ATV with the included remote, it does turn on the TV and receiver, but it doesn't switch my receiver to the correct input most of the time. I have to press a button again to have it actually switch sources, almost the same as you described your situation. It's all so wonky. (CEC has always been wonky unfortunately...)
I would have preferred an optional flag for power management (or to not implement it at all actually), but I got run over on that because people are too keen on that feature unfortunately. It makes the code in the integration a bit...ugly... So I'll have to think about this a bit.
But things should work rather OK as long as power state is updated correctly according to play state. So I think some additional work is needed to fix that. I didn't think too much about it before, but this situation should never happen:
{"result": "success", "datetime": "2021-12-13T16:13:28.437542+01:00", "hash": "gnNF4NFEw\u2206n6gH8F48n", "media_type": "music", "device_state": "paused", "title": "UN DIA (ONE DAY)", "artist": "J Balvin, Dua Lipa, Bad Bunny & Tainy", "album": "UN DIA (ONE DAY) - Single", "genre": "Latin urban", "total_time": 231, "position": 41, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-13T16:13:28.477203+01:00", "power_state": "off"}
As long as device_state
is not idle, the power state must be totally ignored and it doesn't seem to be. So I guess I need to go bug hunting here.
And yes, CEC is a total buggy sack of... yeah. It is a standard that has not been very well treated, mainly by manufacturers I guess.
I get why people ask for it, but you're still limited by what the hardware and software that runs on it can supply you with. 😉 You could even turn on the flag by default. If it's then problematic you can turn it off. But I feel it's totally acceptable to do it the other way around for such experimental functionality. That way people who really want to use and try it can at least enable it. Just do whatever you feel is right of course. 🙂
Good luck with hunting bugs! Is the device_state
actually switched to idle automatically when receiving a CEC power off? It doesn't really happen quickly without CEC anyway. (I don't see it happening in my events without CEC.) Which is fine/correct of course 👍
I know, that's the problem. Trying to bend the universe here... As the feature is in there now, I would prefer to just keep it there and try to improve the situation as much as I can and people will have to live with a few oddities. Maybe it can be further improved over time as well. I'll use that as my goal, but might have to change direction later on.
I think I know the issue, just need to come up with a test for it. The device_state
solely depends on what the media player framework in the Apple TV says is currently playing. There are situations where the Music app remains active and paused, like a "default state". So even you aren't actively choosing what to play, something else might keep it looking like it is playing.
I found a subtle bug that pretty much disabled everything I implemented... Fixed it in the branch below, can you try it out and see how it behaves?
https://github.com/postlund/pyatv/tree/power_state_mrp
Kind of interesting how it behaves now 🙂
This is with the TV and receiver turned off. Also, the light on the front is off.
{"result": "success", "datetime": "2021-12-14T18:26:44.059411+01:00", "power_state": "off"}
{"result": "success", "datetime": "2021-12-14T18:26:44.059623+01:00", "power_state": "on"}
{"result": "success", "datetime": "2021-12-14T18:26:44.059825+01:00", "hash": "gnNF4NFEw\u22064NgwkHklX", "media_type": "music", "device_state": "paused", "title": "Dakiti", "artist": "Bad Bunny & Jhay Cortez", "album": "Dakiti - Single", "genre": "Latin", "total_time": 205, "position": 161, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
The result is power_state
on
which I find surprising, but I guess it's because the device isn't idle. (When does it normally go idle?)
I start playing a song using the companion remote (ATV light turns on):
{"result": "success", "datetime": "2021-12-14T18:29:23.345935+01:00", "hash": "gnNF4NFEw\u22064NgwkHklX", "media_type": "music", "device_state": "stopped", "title": "Dakiti", "artist": "Bad Bunny & Jhay Cortez", "album": "Dakiti - Single", "genre": "Latin", "total_time": 205, "position": 161, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:29:23.377370+01:00", "hash": "XN6FnlkHp\u2206_PLACEHOLDER_TAIL_", "media_type": "unknown", "device_state": "stopped", "title": "Laden\u2026", "artist": "Radio", "album": null, "genre": null, "total_time": null, "position": null, "shuffle": "songs", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:29:23.381035+01:00", "hash": "XN6FnlkHp\u2206_PLACEHOLDER_TAIL_", "media_type": "unknown", "device_state": "stopped", "title": "Laden\u2026", "artist": "Radio", "album": null, "genre": null, "total_time": null, "position": null, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:29:24.373955+01:00", "hash": "XN6FnlkHp\u2206_PLACEHOLDER_TAIL_", "media_type": "unknown", "device_state": "paused", "title": "Laden\u2026", "artist": "Radio", "album": null, "genre": null, "total_time": null, "position": null, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:29:24.388588+01:00", "hash": "XN6FnlkHp\u2206SSe68NlgN", "media_type": "music", "device_state": "paused", "title": "GOT IT GOOD (feat. Craig David)", "artist": "KAYTRANADA", "album": "99.9%", "genre": "Electronic", "total_time": 228, "position": null, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:29:25.203978+01:00", "hash": "XN6FnlkHp\u2206SSe68NlgN", "media_type": "music", "device_state": "playing", "title": "GOT IT GOOD (feat. Craig David)", "artist": "KAYTRANADA", "album": "99.9%", "genre": "Electronic", "total_time": 228, "position": 4, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Interesting how the states change.
Unfortunately my HA automation didn't trigger here. Sometimes this happens, so I try again by pausing:
{"result": "success", "datetime": "2021-12-14T18:31:29.241796+01:00", "hash": "XN6FnlkHp\u2206SSe68NlgN", "media_type": "music", "device_state": "paused", "title": "GOT IT GOOD (feat. Craig David)", "artist": "KAYTRANADA", "album": "99.9%", "genre": "Electronic", "total_time": 228, "position": null, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:31:29.330800+01:00", "hash": "XN6FnlkHp\u2206SSe68NlgN", "media_type": "music", "device_state": "paused", "title": "GOT IT GOOD (feat. Craig David)", "artist": "KAYTRANADA", "album": "99.9%", "genre": "Electronic", "total_time": 228, "position": 123, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
And then playing again (switches to a new song at 18:33:42):
{"result": "success", "datetime": "2021-12-14T18:31:58.357148+01:00", "hash": "XN6FnlkHp\u2206SSe68NlgN", "media_type": "music", "device_state": "playing", "title": "GOT IT GOOD (feat. Craig David)", "artist": "KAYTRANADA", "album": "99.9%", "genre": "Electronic", "total_time": 228, "position": 128, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:33:42.557411+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "paused", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": null, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:33:42.640822+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "playing", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 4, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Strange, my HA automation doesn't trigger... And then I see that HA thinks it's turned off for some reason, so I turn on my receiver manually 😅 (At least it demonstrates my current issues.)
This only puts the music to pause again:
{"result": "success", "datetime": "2021-12-14T18:36:14.704292+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "paused", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 23, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:36:14.810083+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "paused", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 34, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
And I can now start playing it again:
{"result": "success", "datetime": "2021-12-14T18:40:44.274499+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "playing", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 38, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:40:50.651418+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "playing", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 42, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
I pause the music:
{"result": "success", "datetime": "2021-12-14T18:41:28.646567+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "paused", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 40, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
{"result": "success", "datetime": "2021-12-14T18:41:28.756568+01:00", "hash": "XN6FnlkHp\u2206HeHk86g8N", "media_type": "music", "device_state": "paused", "title": "No Worries", "artist": "Disciples & David Guetta", "album": "No Worries - Single", "genre": "Dance", "total_time": 208, "position": 78, "shuffle": "off", "repeat": "off", "series_name": null, "season_number": null, "episode_number": null, "content_identifier": null, "app": "Muziek", "app_id": "com.apple.TVMusic"}
Switch off the receiver:
*crickets*
The light on the ATV actually represents kind of the state I would expect it to be in, isn't that represented in some way?
So no power_state
switches anymore. It's on during the whole cycle of push_updates
, except for the first message.
Ok, so, based on the logs you have above I think the power_state
behavior is as expected: as long as some app is considered active, thus not changing device_state
to idle, the power state remains on. We have multiple elephants in the the room here, that I will not deny. So my observations and theories:
- For some reason an app can get "stuck" as active more or less indefinitely (until a reboot or until you start playing something else). Usually this is the Music app for some reason. I have seen this happen from time to time since like...forever. Whenever this happen,
power_state
is more or useless as it will just be on all the time. - External events, like turning off the TV or receiver, will not always change
power_state
to off according to previous experiments. It works sometimes but not always (and especially not if 1) has happened). - Regarding the "light", I would guess that it represents some kind of low-power or deep-sleep state (depending on what is possible). If the device is in deep-sleep we can't have a connection to it because it's turned off, so all reasoning here is pointless. If it's in low-power mode, it's likely running but has most things turned off. It means that it's still software running, so an app can technically be active. Externally we cannot know if we are in this state, but I guess we sort of try to guess it when we look at
logicalDeviceCount
. - For some reason the state for what is playing can switch back and forth several times before playback start. In theory it's of course possible to filter out some of it, but it's hard to do correct. Not sure how much I can do about it I'm afraid.
I'm not really sure how to treat this to be honest. It seems to do what it's programmed to do, the Apple TV is (at least in my opinion) just acting bonkers. Best would be to find another source of power state information.
I agree with what you're saying here, and in all honesty I'm curious how this will behave in HA. I think it might even work as expected, and at least shouldn't be worse for my use-case. So I'm happy to try it like it is right now moving forward 👍 Great job so far on all the work you've put in, again. 🙂
Should installing this inside my HA container be compatible API wise? Because then I might try that later this week.
Yeah, I think it will work fine in HA but I guess testing it out is the only fair way to know.
There's no breaking change here, so it should be safe to install and run it. I hope...otherwise it's a bug (which might very well be the case because I've fiddled with many core things 😉). I intend to release 0.9.8 very soon, possibly tomorrow. So probably easier to just wait for it. Let's try it in production and see what happens!
I will close this again as I think we are in a better state now. Let the bug reports pour when this hits the masses! 🌧
I just wanted to let you know that it's sometimes still not working for me. I haven't been able to put my finger on it, but I'm using the beta integration in HA with pyATV 0.9.8. And when I start playing music through the companion remote, the state in HA sometimes is still stuck on standby.
Currently, the companion is playing something, and the progress slider is moving along, but looking at the device state in HA shows this:
source_list:
[...]
media_content_type: music
media_duration: 359
media_position: 0
media_title: A Glimmer of Hope
media_artist: Chris Stussy
media_album_name: A Glimmer of Hope - EP
app_id: com.apple.TVMusic
app_name: Muziek
entity_picture: >-
/api/media_player_proxy/media_player.apple_tv_mancave?token=91a317c836213296e2cc92ecec7fc886ea2122b3ce5a8be605b1976c111689bf&cache=https://is2-ssl.mzstatic.com/image/thumb/Music115/v4/78/68/fc/7868fcd9-1b18-98e4-f3de-978433bf085a/cover.jpg/{w}x{h}{c}.{f}
friendly_name: Apple TV Mancave
supported_features: 450487
With state standby
.
When I then manually turn on my receiver, the state immediately changes to playing
and media_position
is updated again.
Hmm, that's interesting. Can you try to fetch some logs (especially for pyatv) so I can troubleshoot from there? Something must be missing.
Hi, I was going to open a new issue, until I saw this. Here is what happened to me (I figured this out the hard way though, did not see this issue)
@postlund note sure if you have seen this before, I can get you logs if that helps?
After several hours of troubleshooting where I couldn't figure out why my remote command (- menu) was no longer working (to turn my TV on via HDMI-CEC). I noticed that the media player in home assistant (HA) has music on it, if clicked play my TV turned on, but the remote command would not work. So I knew I had to clear this, I restarted the Apple TV, and bang everything works again. So basically when there is music paused on the ATV (even it I put the ATV to sleep it has the same state), HA gets the "paused" state, if no music and it's gets put to sleep the state is "standby".
Not sure if this is just doco needed or something else...
Running HA Release 2023.5.4 - May 23 ATV Model A2169 TVOS 16.4.1