Lovelace-card-mod and StudioDisplay/IDJC indicators

So we’re doing (Internet) Radio Broadcasts using the Internet DJ Console (IDJC) and my StudioDisplay system.

I already had a Lovelace glance card showing the four most interesting studio indicators (Studio Ready, Streaming, Microphone hot, Caller on the request line) but since these indicators can not only have the state ‘off’ and ‘on’, but also ‘blink’ and ‘flash’ (as used on the studio signal tower), I wanted more.

So I installed Tom’s lovelace-card-mod as a module:

Awesome! This is how my Lovelace glance card now works: Screencast, MP4

I use these MQTT sensors:

sensor:

  # Studio/IDJC
  - platform: mqtt
    name: 'Studio Green'
    state_topic: 'studio/1/status/green'
  - platform: mqtt
    name: 'Studio Yellow'
    state_topic: 'studio/1/status/yellow'
  - platform: mqtt
    name: 'Studio Red'
    state_topic: 'studio/1/status/red'
  - platform: mqtt
    name: 'Studio Blue'
    state_topic: 'studio/1/status/blue'

And this is how my glance card looks like (use the code editor in case you use the UI):

title: Studio Krumbach
type: glance
entities:
  - entity: sensor.studio_green
    name: Bereit
    style: |
      :host {
        --paper-item-icon-color:
        {% if states(config.entity) in ['on', 'blink', 'flash'] %}
          var(--paper-item-icon-active-color)
        {% endif %}
        ;
      }
      state-badge {
        --on-color: hsla(120, 90%, 50%, 0.9); /* green */
        --off-color: hsla(120, 25%, 50%, 0.5);
        background-color: var(--off-color);
      }
      @keyframes blink {
        0%   { background-color: var(--off-color); }
        50%  { background-color: var(--on-color); }
        100% { background-color: var(--off-color); }
      }

      @keyframes flash {
        0%   { background-color: var(--off-color); }
        15%  { background-color: var(--on-color); }
        30%  { background-color: var(--off-color); }
        45%  { background-color: var(--on-color); }
        60%  { background-color: var(--off-color); }
      }
      {% if states(config.entity) == 'on' %}
        state-badge {
          background-color: var(--on-color);
        }
      {% elif states(config.entity) == 'blink' %}
        state-badge {
          animation: blink 2s infinite;
        }
      {% elif states(config.entity) == 'flash' %}
        state-badge {
          animation: flash 2s infinite;
        }
      {% else %}
        state-badge {
          background-color: var(--off-color);
        }
      {% endif %}
  - entity: sensor.studio_yellow
    name: Auf Sendung
    style: |
      :host {
        --paper-item-icon-color:
        {% if states(config.entity) in ['on', 'blink', 'flash'] %}
          var(--paper-item-icon-active-color)
        {% endif %}
        ;
      }
      state-badge {
        --on-color: hsla(60, 90%, 50%, 0.9); /* yellow */
        --off-color: hsla(60, 25%, 50%, 0.5);
        background-color: var(--off-color);
      }
      @keyframes blink {
        0%   { background-color: var(--off-color); }
        50%  { background-color: var(--on-color); }
        100% { background-color: var(--off-color); }
      }

      @keyframes flash {
        0%   { background-color: var(--off-color); }
        15%  { background-color: var(--on-color); }
        30%  { background-color: var(--off-color); }
        45%  { background-color: var(--on-color); }
        60%  { background-color: var(--off-color); }
      }
      {% if states(config.entity) == 'on' %}
        state-badge {
          background-color: var(--on-color);
        }
      {% elif states(config.entity) == 'blink' %}
        state-badge {
          animation: blink 2s infinite;
        }
      {% elif states(config.entity) == 'flash' %}
        state-badge {
          animation: flash 2s infinite;
        }
      {% else %}
        state-badge {
          background-color: var(--off-color);
        }
      {% endif %}
  - entity: sensor.studio_red
    name: Am Mikrofon
    style: |
      :host {
        --paper-item-icon-color:
        {% if states(config.entity) in ['on', 'blink', 'flash'] %}
          var(--paper-item-icon-active-color)
        {% endif %}
        ;
      }
      state-badge {
        --on-color: hsla(0, 90%, 50%, 0.9); /* red */
        --off-color: hsla(0, 25%, 50%, 0.5);
        background-color: var(--off-color);
      }
      @keyframes blink {
        0%   { background-color: var(--off-color); }
        50%  { background-color: var(--on-color); }
        100% { background-color: var(--off-color); }
      }

      @keyframes flash {
        0%   { background-color: var(--off-color); }
        15%  { background-color: var(--on-color); }
        30%  { background-color: var(--off-color); }
        45%  { background-color: var(--on-color); }
        60%  { background-color: var(--off-color); }
      }
      {% if states(config.entity) == 'on' %}
        state-badge {
          background-color: var(--on-color);
        }
      {% elif states(config.entity) == 'blink' %}
        state-badge {
          animation: blink 2s infinite;
        }
      {% elif states(config.entity) == 'flash' %}
        state-badge {
          animation: flash 2s infinite;
        }
      {% else %}
        state-badge {
          background-color: var(--off-color);
        }
      {% endif %}
  - entity: sensor.studio_blue
    name: Anrufer
    style: |
      :host {
        --paper-item-icon-color:
        {% if states(config.entity) in ['on', 'blink', 'flash'] %}
          var(--paper-item-icon-active-color)
        {% endif %}
        ;
      }
      state-badge {
        --on-color: hsla(240, 90%, 50%, 0.9); /* red */
        --off-color: hsla(240, 25%, 50%, 0.5);
        background-color: var(--off-color);
      }
      @keyframes blink {
        0%   { background-color: var(--off-color); }
        50%  { background-color: var(--on-color); }
        100% { background-color: var(--off-color); }
      }

      @keyframes flash {
        0%   { background-color: var(--off-color); }
        15%  { background-color: var(--on-color); }
        30%  { background-color: var(--off-color); }
        45%  { background-color: var(--on-color); }
        60%  { background-color: var(--off-color); }
      }
      {% if states(config.entity) == 'on' %}
        state-badge {
          background-color: var(--on-color);
        }
      {% elif states(config.entity) == 'blink' %}
        state-badge {
          animation: blink 2s infinite;
        }
      {% elif states(config.entity) == 'flash' %}
        state-badge {
          animation: flash 2s infinite;
        }
      {% else %}
        state-badge {
          background-color: var(--off-color);
        }
      {% endif %}

It uses quite a bit of CSS, which could possibly be optimized, though.

But hey, it works! And I can now finally see the blink and flash states. I’m happy.

Thanks for the great work, Thomas!

Good day! Can you tell me if you can make a blinking icon only at a temperature of 40 degrees? I made this method change the color of the icon, but how to do that would blink not all the time, but only when the value reaches 40 or more!?

      - cards:
          - cards:
              - entity: sensor.temperature
                style: |
                  ha-card {
                    background: {% if states('sensor.temperature')|int >= 40 %}
                            red
                          {% elif states('sensor.temperature_ul_1')|int >= 35 %}  
                            orange
                          {% elif states('sensor.temperature_ul_1')|int <= 29 %}  
                            green
                          {% else %}
                            green
                          {% endif %}
                  }
                graph: none
                name: temp_out
                show_icon: false
                show_name: false
                show_state: false
                type: sensor