Merging media player statuses

I have two primary media players – Kodi and Roku – and I want to merge their statuses to know what the current state of my theater is.

Specifically, there is a natural hierarchy of “activity” with media players – Playing is more active than Paused which is more than Idle which is more than Off (or any other random state). I want the grouped/merged status of both media players to be whichever is the most active state.

A “Media Player Group” seems like a logical solution except that it’s merge logic is too simple to be useful – any differences in play state is just “On”. I can’t do anything with that.

A “Universal Media Player” is primarily for controlling multiple media players, so the opposite of what I’m looking for on the surface. However, it does have the ‘attributes.state’ setting which maybe could work? It’s not obvious, if so.

A full custom “Template” surely could work, with the right programming. A super accurate case might be to query my Denon AVR to determine the current ‘source’ and then query the current state of whatever media player is dedicated to that source channel.

But I’m not looking to reinvent the wheel here. If anybody has done something like this already or has a brilliant idea on how to implement it, let me know!

(If this is an esoteric problem, then I’ll eventually come up with my own solution and post here)

I figured this out and it would have been much faster except that my Denon AVR kept gaslighting me. Denon, you make a fine AVR, but seriously – be far more deterministic when returning the current ‘source’! It’s not useful when it keeps changing!

Okay, first off, a custom “Template” will apparently not work since there is no Media Player Template type (other than an unsupported HACS example).

What works is the “Universal Media Player”. I’ll give two examples and discuss their pros and cons.

First “con” is for the Universal Media Player itself – there is no way to configure it via the UI. And unfortunately, sometimes just reloading the YAML doesn’t reload the player and thus requires rebooting HA itself. No idea why.

Simple Example

- media_player:
  - platform: universal
    name: Merged Media Players
    children:
      - media_player.kodi
      - media_player.roku
    device_class: tv
    unique_id: merged_media_players

This is super simple and gets me 90% of the way. Ostensibly, this will automatically switch to whatever media player is currently active and not only have the current state, but also a set of controls and attributes that are specific to the currently active player. Very slick!

Alas, Roku mucks up the waters a bit since it arbitrarily changes its state based on a timeout, not on what you do. For example, if you are watching something on the Roku, then the universal player will be all focused on it. You stop watching something and the Roku moves to the “On” state. You then switch to Kodi, which is in “Idle” state until you actively start playing something. That means that the above universal player will still be focused on Roku while you are trying to browse Kodi. It won’t switch to Kodi until you either start actively playing or Roku times out and it switches to “Idle”.

Honestly, this simple case would likely be fine if my streaming player was anything but a Roku, but since it is a Roku, I needed something a bit more direct.

Guaranteed Example

- media_player:
  - platform: universal
    name: Theater Media Players
    children:
      - media_player.kodi
      - media_player.roku
    device_class: tv
    unique_id: theater_media_players
    active_child_template: >
      {% if is_state_attr('media_player.harmony', 'source', 'Watch Roku') %}
        media_player.roku
      {% elif is_state_attr('media_player.harmony', 'source', 'Watch Kodi') %}
        media_player.kodi
      {% else %}
        media_player.denon_avr_x6200w
      {% endif %}

This one works for me 100% of the time since it forces the actually active media player to the forefront based on which player currently has control of the screen. I could even have a Roku actively playing a video while switching to Kodi and this will (properly) start serving up the Kodi state and controls.

This does require having a central control of what is playing. I originally wanted this control to be my Denon AVR, but it’s ‘source’ attribute was never the same each time I tried so sometimes it would work and sometimes it would just be “unknown”. The Harmony source is at least consistent every time.

Why I’m Doing This

For anybody making it this far… I never said why I wanted the merged or active state. It’s for an automation where I turn on my theater lights to 10% when the current video is paused. Just using the state change as a trigger wasn’t enough, since the Roku would change state a few minutes later and trigger the light to go on. Thus, I needed to check the current state as a condition and not turn on the light if anything is currently playing. The above “Guaranteed Example” does exactly what I need.