Button for scene wich is active when scene is active

Hi i have on my dashboard some buttons which are triggering a scene on click.
This works very well.
But now it would be grate to see which scene is active.
Is it possible to check if a scene is active and then that the button is highlighted?

Thanks for help.

Bildschirmfoto 2021-07-11 um 21.06.39

type: grid
cards:
  - type: grid
    columns: 2
    cards:
      - type: button
        tap_action:
          action: call-service
          service: scene.turn_on
          service_data:
            entity_id: scene.helles_licht
        entity: scene.helles_licht
        show_name: false
        show_state: false
      - type: button
        tap_action:
          action: call-service
          service: scene.turn_on
          service_data:
            entity_id: scene.abendstimmung
        entity: scene.abendstimmung
        show_state: false
        show_name: false
        show_icon: true

You can create an automation on the trigger event.call_service.scene.turn_on to write the scene name of the latest applied scene to an input_text.

  - id: home_scene_change
    alias: home_scene_change
    mode: queued
    trigger:
    - event_data:
        domain: scene
        service: turn_on
      event_type: call_service
      platform: event
    action:
    - service: input_text.set_value
      data_template:
        entity_id: input_text.home_state_scenes
        value: "{{trigger.event.data.service_data.entity_id}}"

2 Likes

@seanomat ,
thanks for sharing the idea.
A change from button action: call-service to a action: toggle is with a scene not possible or?

There is no such thing as turning off a scene. After all, what should the state of the entities be, when turning off a scene?
If you want them to be, what they were before you activated the scene (which could be different every time) you would have to create a “before” scene on the fly before activating a scene. Then you could go back to the “before” scene.

By the way: For unknown reasons, the event-data in my previous example passes the name of the scene in different formats, depending on how it is called.
So you would be better off using this line:

          value: "{{trigger.event.as_dict()['data']['service_data']['entity_id']|replace('[\\'','')|replace ('\\']','') }}"

instead of this line:

      value: "{{trigger.event.data.service_data.entity_id}}"

Ok solved in now in another way with a workaround which works very nice for me

I created for every scene an input_boolean in the config.yaml
Then in the scene itself i set the several inputs to on or off
Afterwards if a scene is executed i got the state of all scences

In my dashboard i can use the input_boolean as an entity for my button. So that the correct activated scene shows on or off:

type: button
tap_action:
  action: call-service
  service: scene.turn_on
  service_data: {}
  target:
    entity_id: scene.abendstimmung
entity: input_boolean.scene_essen
show_state: true

Hey sagined

I’m trying to do the same thing but I’m not sure exactly what you have done here - would you be able to show me an example of what you put n the config.yaml file?

Cheers

Hi Tim,
i solved now in a more less different way. Probably not nice but working for me i think there are easier ways :slightly_smiling_face:

What i did:

  1. Creating switches as helpers
  2. Creating a script do deactivate all switches
  3. Creating automation for the action of the “Button”
  4. In Dashboard creating cards which trigger an automation

To 1. Creating switches for every scene/button on "Settings - Devices & - Helpers"

To 2. Then i have written a script to deactivate all inputs

alias: input booleans off
sequence:
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id:
        - input_boolean.fernsehen
        - input_boolean.essen
        - input_boolean.gute_nacht
        - input_boolean.guten_morgen
        - input_boolean.haus_verlassen
        - input_boolean.kochen
        - input_boolean.licht_an_dunkel
        - input_boolean.licht_an_hell
        - input_boolean.romantik
mode: single
icon: mdi:order-bool-descending-variant

To 3: automation:
In the automation i will first call the deactivate script and afterwards activate the current switch

To 4: In my Dashboard i have created some cards for each “Switch” which is triggering an automation:

square: true
columns: 2
type: grid
cards:
  - show_name: false
    show_icon: true
    type: button
    tap_action:
      action: call-service
      service: automation.trigger
      data: {}
      target:
        entity_id: automation.scene_licht_hell
    entity: input_boolean.licht_an_hell
    show_state: false
    icon: ''
    hold_action:
      action: none

Thanks for posting all that - I think my requirement was slightly less complicated than your and ended up achieving it using templates in the config to simply modify the specific device class icons.

can you explain how you achieved?

Appreciate this thread has been around for while, but following reading this and a bit of experimentation thought I’d share my take on achieving this:

  • each room has a series of scenes (scene’s are set independently and at different times so the room distinction is important for me)
  • all lights that belong to scene in a room also belong to a light group
  • lights are only enabled by scenes (e.g. a manual button press still triggers a scene not an individual light)
  • therefore, if a light group is on, then a scene is active – if the group is off no scene is active

I created my required scenes and following a common format:

  • Name: [Room] – [Description] e.g. “Office – Bright” or “Office – Working”
  • Entity_id: scene.[room]_[description]

For each room I created a template sensor that checks the state timestamp of the scenes for that room to establish the most recently activated scene. I do this by checking for the [room] name in the entity_id (in this case “office”):

- name: Current Scene Office
  state: >
    {%- set latest = namespace(time = 0) %}
    {%- set selected = namespace(item='') %}
    {%- if is_state('light.office_light_group', 'on') %}
      {%- for item in states.scene if 'office' in item.entity_id %}
        {% if latest.time < as_timestamp(item.state) %}
          {% set selected.item = item.attributes.friendly_name %}
          {% set latest.time = as_timestamp(item.state) %}
        {% endif %}
      {%- endfor %} 
      {{ selected.item.split('- ')[1] }} 
    {%- endif %}

The sensor then stores the name of the latest scene (this was because at one stage I was texturally outputting it on my dashboard (i.e. “The current office scene is Working”). If the light group is off the sensor will return null.

I then have a button for each scene (by room) using custom button. The tap action actives the scene the button represents and for visual display, I check the status of the template sensor above, and if its state equals the scene the button represents I turn the button “on”.

image
or
image

type: custom:button-card
icon: mdi:lightbulb-on-90
size: 30%
styles:
  name:
    - color: '#8c8c8c'
  icon:
    - color: |
        [[[
          if (states['sensor.current_scene_office'].state == 'Bright')
            return "#fbd84e";
          return "#8c8c8c";
        ]]]
  card:
    - background-color: |
        [[[
          if (states['sensor.current_scene_office'].state == 'Bright')
            return "#ffffff";
          return "#f6f6f6";
        ]]]
    - height: 45px
tap_action:
  action: call-service
  service: scene.turn_on
  service_data:
    entity_id: scene.office_bright
1 Like

I have been searching for this sometime now, and finally!

I changed it just a bit, but it works just fine:

sensor:
  - platform: template
    sensors:
      current_scene_kitchen:
        friendly_name: Current scene kitchen
        value_template: >-
            {%- set latest = namespace(time = 0) %}
            {%- set selected = namespace(item='') %}
              {%- for item in states.scene if 'Kitchen' in item.attributes.friendly_name %}
                {% if latest.time < as_timestamp(item.state) %}
                  {% set selected.item = item.attributes.friendly_name %}
                  {% set latest.time = as_timestamp(item.state) %}
                {% endif %}
              {%- endfor %} 
              {{ selected.item.split('- ')[1] }}

I removed the if-statement to check if group was on, then I was able to use “no lights” scene as well.

Thanks for sharing!

Sharing a little bit more refinement.

As I had a template sensor for about 10 rooms there was a lot of repeating logic just changing the name of the room each time. To make things “nicer” I moved to using macros (2023.04 release).

This meant I could compress each room current_scene sensor to the following:

      - name: Current Scene Lounge
        state: >
          {% from 'current_scene.jinja' import current_scene %}
          {{ current_scene('light.lounge_light_group', 'lounge') }}

      - name: Current Scene Hall
        state: >
          {% from 'current_scene.jinja' import current_scene %}
          {{ current_scene('light.hall_light_group', 'hall') }} 

      ... etc ...

With each of these calling the following macro:

{% macro current_scene(light_group, room_name) %}
{%- set selected = namespace(name=none,time=0) %}
{%- if is_state (light_group, 'on') %}
{%- for item in states.scene if room_name in item.entity_id %}
    {% if selected.time < as_timestamp(item.state) %}
    {% set selected.name = item.attributes.friendly_name %}
    {% set selected.time = as_timestamp(item.state) %}
    {% endif %}
{%- endfor %}
{{ selected.name.split('- ')[1] }}
{%- else %}
Off
{%- endif %}  
{% endmacro %}

Necessary, No - interesting to do, Yes - maintainable and scalable for future, Yes. As with everything Home Assistant related its never really done, I’m sure at some point in the next 6 months I’ll rip this out and revise with something different!

1 Like