Harmony Activities, Volume Slider, and Lovelace

Hello everyone, I’ve been getting quite a few messages about my harmony setup, so I decided to create this post to give it more visibility.

I attempted to create a ‘minimalist’ approach to an interface that works identical to the harmony remotes activities. That being, when one activity is turned on, all others are off. This functionality is built into the harmony remote and it can be quite difficult to replicate in the Home Assistant user interface.

The second thing to note here is that I also use a receiver. My harmony activities turn on my receiver, set the correct input, and adjust volume. That’s why my interface also shows my receiver. The interface consists of 2 Lovelace cards, both which are picture-glance cards. Each card has a row of toggles that have specific tasks. On the harmony card, the toggles represent each activity. On the receiver card, the toggles represent an on/off for each zone. The zones for the receiver are areas of my house in which the sound comes through. Zone 1 being the living room and zone 2 being the dining room. You’ll also notice 2 icons that represent google home. When these are turned on, google home transmits sound through my receiver. So lets take a look at the interface.

Powered Off

This is what the interface looks like when the system is powered off. Notice all the toggles on the bottom of each card is dark in color. This means they are off.

Xbox One is On

You’ll notice that a volume slider appears for the receiver and now a info box appears with the Xbox Activites that are detected.

Playstation is On and Zone 2 is On.

You’ll notice that the xbox information is gone and now I have 2 volume sliders, one for each zone. I suppose I should rename those zones to the actual names, like Living Room Volume and Dining Room Volume.

Ok, so now here is the configuration:

Harmony Setup

remote: 
  - platform: harmony
    name: living_room
    host: !secret remote_host

This is located inside configuration.yaml. I do not use discovery because I don’t like dealing with things changing on the fly.

The available harmony activities inside harmony_living_room.conf:

Activities
  26592473 - Switch
  -1 - PowerOff
  24089909 - PS4
  24103421 - Xbox One
  24090202 - Wii U
  24090353 - PC
  30947237 - TV

Reciever Setup

media_player:
  - platform: yamaha
    host: !secret yamaha_host
    source_ignore:
      - AV1
      - AV2
      - AV3
      - AV4
      - AV5
      - AV6
      - Pandora
      - Rhapsody
      - SiriusXM
      - Spotify
      - Tuner
      - USB
      - V-AUX
    source_names:
      HDMI1: "Xbox One"
      HDMI2: "Playstation 4"
      HDMI3: "Wii U"
      HDMI4: "PC"
      HDMI5: "Switch"
      AUDIO1: "Phone"
      AUDIO2: "Echo"

This is located inside configuration.yaml. Again I avoid discovery.

Template Switches (the toggles on the Lovelace picture-glance cards)

switch: !include switch.yaml

This is located inside configuration.yaml. The contents of the switch.yaml are:

  - platform: template
    switches:
        # ZONE 1 MEDIA SWITCH
        zone_1:
          value_template: "{{ is_state('media_player.yamaha_receiver', 'on') }}"
          turn_on:
            service: media_player.turn_on
            entity_id: media_player.yamaha_receiver
          turn_off:
            service: media_player.turn_off
            entity_id: media_player.yamaha_receiver
              
        # ZONE 2 MEDIA SWITCH
        zone_2:
          value_template: "{{ is_state('media_player.yamaha_receiver_zone_2', 'on') }}"
          turn_on:
            service: media_player.turn_on
            entity_id: media_player.yamaha_receiver_zone_2
          turn_off:
            service: media_player.turn_off
            entity_id: media_player.yamaha_receiver_zone_2
        
        # XBOX HARMONY ACTIVITY
        xbox_one:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'Xbox One') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'Xbox One'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # PLAYSTATION HARMONY ACTIVITY
        ps4:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'PS4') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PS4'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # WII U HARMONY ACTIVITY
        wii_u:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'Wii U') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'Wii U'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # PC HARMONY ACTIVITY
        pc:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'PC') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PC'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # SWITCH HARMONY ACTIVITY
        switch:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'Switch') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'Switch'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # TV HARMONY ACTIVITY
        tv:
          value_template: "{{ is_state_attr('remote.living_room', 'current_activity', 'TV') }}"
          turn_on:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'TV'
          turn_off:
            service: remote.turn_on
            data:
              entity_id: remote.living_room
              activity: 'PowerOff'
        
        # AUDIO 1, USED FOR ECHO AND MUSIC ZONE 1
        audio_1:
          value_template: "{{ is_state_attr('media_player.yamaha_receiver', 'source', 'Echo') and is_state('switch.floating_outlet_switch', 'on') }}"
          turn_on:
            - service: switch.turn_on
              entity_id: switch.floating_outlet_switch
            - service: media_player.turn_on
              entity_id: media_player.yamaha_receiver
            - service: media_player.select_source
              data:
                entity_id: media_player.yamaha_receiver
                source: Echo
            - service: media_player.volume_set
              data:
                entity_id: media_player.yamaha_receiver
                volume_level: 0.7
          turn_off:
            - service: switch.turn_off
              entity_id: switch.floating_outlet_switch
            - service: media_player.turn_off
              entity_id: media_player.yamaha_receiver

        # AUDIO 2, USED FOR ECHO AND MUSIC ZONE 2
        audio_2:
          value_template: "{{ is_state_attr('media_player.yamaha_receiver_zone_2', 'source', 'Echo') and is_state('switch.floating_outlet_switch', 'on') }}"
          turn_on:
            - service: switch.turn_on
              entity_id: switch.floating_outlet_switch
            - service: media_player.turn_on
              entity_id: media_player.yamaha_receiver_zone_2
            - service: media_player.select_source
              data:
                entity_id: media_player.yamaha_receiver_zone_2
                source: Echo
            - service: media_player.volume_set
              data:
                entity_id: media_player.yamaha_receiver_zone_2
                volume_level: 0.7
          turn_off:
            - service: switch.turn_off
              entity_id: switch.floating_outlet_switch
            - service: media_player.turn_off
              entity_id: media_player.yamaha_receiver_zone_2

Volume Sliders

Disclaimer: I use appdaemon for my automation. These automations are what I would use if I used normal volume configuration (these could contain typos):

input_number: !include input_number.yaml

This is located inside configuration.yaml. The contents of the input_number.yaml are:

  yamaha_receiver:
    name: Zone 1 Volume
    initial: -80
    min: -80
    max: 0
    step: 5
    unit_of_measurement: dB
    
  yamaha_receiver_zone_2:
    name: Zone 2 Volume
    initial: -80
    min: -80
    max: 0
    step: 5
    unit_of_measurement: dB

The units of dB are negative, that’s why this is such a weird setup. My receiver shows the volume as negative so I’m emulating that here. Media_players only accept volume levels between 0 and 1. So because of that, I need to convert decibels to a 0 to 1 representation. That is handled by these automations:

- alias: Zone 1 Volume (Media to Slider)
  trigger:
    - platform: state
      entity_id: media_player.yamaha_receiver
  condition:
    - condition: template
      value_template: >
        # convert to decibel.
        {% set converted = ( -1.0 + trigger.to_state.attributes.volume_level | float ) * 100.0 | round(0.0) %}
        # Removes feedback loop
        {{ converted != states('input_number.yamaha_receiver') | float }}
  action:
     service: input_number.set_value
     data_template:
       entity_id: input_number.yamaha_receiver
       value: >
          {{ ( ( -1.0 + trigger.to_state.attributes.volume_level | float ) * 100.0 ) | round(0.0) }}

- alias: Zone 1 Volume (Slider to Media)
  trigger:
    - platform: state
      entity_id: input_number.yamaha_receiver
  condition:
    - condition: template
      value_template: >
        # convert from decibel.
        {% set converted = (1.0 - trigger.to_state.state | float / 100.0) | round(2) %}
        # Removes feedback loop
        {{ converted != state_attr('media_player.yamaha_receiver','volume_level') | float }}
  action:
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >
          {{ (1.0 - trigger.to_state.state | float / 100.0) | round(2) }}

- alias: Zone 2 Volume (Media to Slider)
  trigger:
    - platform: state
      entity_id: media_player.yamaha_receiver_zone_2
  condition:
    - condition: template
      value_template: >
        # convert to decibel.
        {% set converted = ( -1.0 + trigger.to_state.attributes.volume_level | float ) * 100.0 | round(0.0) %}
        # Removes feedback loop
        {{ converted != states('input_number.yamaha_receiver_zone_2') | float }}
  action:
     service: input_number.set_value
     data_template:
       entity_id: input_number.yamaha_receiver_zone_2
       value: >
          {{ ( ( -1.0 + trigger.to_state.attributes.volume_level | float ) * 100.0 ) | round(0.0) }}

- alias: Zone 2 Volume (Slider to Media)
  trigger:
    - platform: state
      entity_id: input_number.yamaha_receiver_zone_2
  condition:
    - condition: template
      value_template: >
        # convert from decibel.
        {% set converted = (1.0 - trigger.to_state.state | float / 100.0) | round(2) %}
        # Removes feedback loop
        {{ converted != state_attr('media_player.yamaha_receiver_zone_2','volume_level') | float }}
  action:
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver_zone_2
        volume_level: >
          {{ (1.0 - trigger.to_state.state | float / 100.0) | round(2) }}

Template Sensor

This will help Lovelace properly change the image. This is needed because when your remote is off, the activity is blank. We need to have a sensor that always has information so lovelace doesn’t get screwed up!

sensor:
  - platform: template
    sensors:
      harmony_activity:
        value_template: >
          {% if is_state("remote.living_room", 'on') %}
            {{ states.remote.living_room.attributes.current_activity }}
          {% else %}
            PowerOff
          {% endif %}

Lovelace

This interface uses all cards that are provided by Lovelace, no custom cards are needed.

Here is ui-lovelace.yaml (stripped to just the items needed for this setup)

title: Petros Setup
views:
  - icon: mdi:television
    title: Entertainment
    id: entertainment
    cards:
      - type: vertical-stack
        cards:
          - type: picture-glance
            title: Harmony
            entities:
              - switch.xbox_one
              - switch.ps4
              - switch.wii_u
              - switch.pc
              - switch.switch
              - switch.tv
            state_image:
              "PowerOff": /local/images/power_off.png
              "Xbox One": /local/images/xbox_one_logo.png
              "PS4": /local/images/playstation_logo.png
              "Wii U": /local/images/wiiu_logo.png
              "PC": /local/images/windows_logo.png
              "Switch": /local/images/nintendo_switch_logo.png
              "TV": /local/images/sony_logo.png
            entity: sensor.harmony_activity
          - type: entity-filter
            entities:
              - sensor.xbox_live_name
              - sensor.xbox_current
            state_filter:
              - 'Online'
              - 'Home'
              - 'Netflix'
            show_empty: false
      - type: vertical-stack
        cards: 
          - type: picture-glance
            title: Yamaha Receiver
            entities:
              - switch.zone_1
              - switch.audio_1
              - switch.zone_2
              - switch.audio_2
            image: /local/images/rxv677.png
          - type: conditional
            conditions:
              - entity: switch.zone_1
                state: 'on'
              - entity: switch.zone_2
                state: 'on'
            card:
              type: entities
              entities:
                - entity: input_number.yamaha_receiver
                  name: Zone 1 Volume
                - entity: input_number.yamaha_receiver_zone_2
                  name: Zone 2 Volume
          - type: conditional
            conditions:
              - entity: switch.zone_1
                state: 'on'
              - entity: switch.zone_2
                state: 'off'
            card:
              type: entities
              entities:
                - entity: input_number.yamaha_receiver
                  name: Volume
          - type: conditional
            conditions:
              - entity: switch.zone_1
                state: 'off'
              - entity: switch.zone_2
                state: 'on'
            card:
              type: entities
              entities:
                - entity: input_number.yamaha_receiver_zone_2
                  name: Volume
40 Likes

Fantastic write up. I can’t use any of it but these types of write ups are so useful for the community.

Mind sharing the model of Yamaha receiver you are using, I will be shopping for a HA compatible receiver in the near future.

1 Like

It’s a relatively new receiver (circa 2015 maybe), it was just dumb luck that it was compatible with home assistant. It’s an RXV series that is discontinued. Here are the current models:

https://usa.yamaha.com/products/audio_visual/av_receivers_amps/index.html#d145654

I think it would be equivalent to the RXV685

also, i have an onkyo that is old, just get a harmony hub and most likely it is 99% compatible via IR

    entity: sensor.harmony_activity
  - type: entity-filter
    entities:
      - sensor.xbox_live_name
      - sensor.xbox_current
    state_filter:
      - 'Online'
      - 'Home'
      - 'Netflix'
    show_empty: false

In your lovelace config, can you explain this?

That displays a card that has my Xbox live name and what i’m doing on Xbox. It’s not important for what if you don’t have the xbox live sensor.

I have broadlink ir blaster that works well to integrate into HA, however, its not stateful. If I turn something on with HA and off with the remote, HA has no idea.

Or if I want to tell HA to turn off the media center I could be turning on something that is already off as the on and off IR commands for my receiver and TV are the same.

That happens with harmony but it’s pretty good at keeping the state correct. The remote itself has a quick ‘fix it’ button too so you can easily make the states match in seconds. I use the harmony to automate my xbox because it has no network api, so it uses an IR blaster to control it. I’d say 5 times a year it screws up and it’s usually my fault or the xbox crashed.

This is awesome, thank you for sharing your config, Petro! I do have one question about the Lovelace cards. I got the Picture-Glance card working great, but how did you get the custom state-icons along the bottom? I just have generic lightning bolts.

That was done in my configuration, seems like I forgot to add that bit.

In configuration.yaml:

homeassistant:
  customize: !include customize.yaml

in customize.yaml:

switch.zone_1:
  friendly_name: Zone One
  icon: mdi:numeric-1-box
switch.zone_2:
  friendly_name: Zone Two
  icon: mdi:numeric-2-box
switch.xbox_one:
  friendly_name: Xbox One
  icon: mdi:xbox
switch.ps4:
  friendly_name: Playstation
  icon: mdi:playstation
switch.wii_u:
  friendly_name: Wii U
  icon: mdi:wiiu
switch.pc:
  friendly_name: Computer
  icon: mdi:desktop-classic
switch.switch:
  friendly_name: Switch
  icon: mdi:nintendo-switch
switch.tv:
  friendly_name: TV
  icon: mdi:television
switch.audio_1:
  friendly_name: Audio One
  icon: mdi:google-home
switch.audio_2:
  friendly_name: Audio Two
  icon: mdi:google-home

You can add that directly to the customize section pretty much. You can also probably specify it on the lovelace card itself.

I haven’t fully separated my lovelace config from my normal frontend config. That will happen with my next overhaul when I fully remove frontend.

1 Like

Oh that makes sense. I was trying to add the icons to the configuration.yaml, not customize. Thanks!

Mind sharing how you configured the entity: sensor.harmony_activity sensor for lovelace? I have everything else working, but I’m not able to get the images to change as I’m not able to pull the current activity and I do not have this sensor.

This is close to my current configuration for the remote:

LOL, so i just realized i linked to this thread. My bad. I thought I covered that! I’ll add it to the post, but here it is…

sensor:
  - platform: template
    sensors:
      harmony_activity:
        value_template: >
          {% if is_state("remote.living_room", 'on') %}
            {{ states.remote.living_room.attributes.current_activity }}
          {% else %}
            PowerOff
          {% endif %}
2 Likes

This did it, Thank you so much!

@petro

Any chance your could share your png images?

Yes, I’ll get a link up when I get home.

I stole most of this and made it work with my harmony hub and it’s great! One question though. I am trying to make a new universal remote for my house using an old dedicated tablet and one thing I still need to do is make some kind of UI element for the directional/enter/back buttons on the harmony.

Has anyone done any custom UI stuff like that? I could easily add them as similar icons to the activities but I would much prefer a dedicated card with a nice looking D-bad style layout.

Look towards the remote.send_command service. I’m on my phone so I don’t have a link handy. Should be covered in the docs

Yeah the service call part isn’t a problem. I am more curious with how to make a nice UI element with a d-pad style layout.