Data_template in a scene : if syntax around attribute

At the beginning of an automation, I’m trying to create a scene around a light to keep its state, including its color (inspired by this article)
The problem is that when a light is off, it does not have a xy_color attribute so I want to only store this attribute if it’s available obviously (the article doesn’t mention that situation)

But my syntax is not accepted and I get a Message malformed : extra keys not allowed @ data['action'][0]['xy_color'] when I save :slightly_frowning_face:
Do you see what’s wrong with it ?
(I know the “if” line is correct because it works in the Developer Tools)

service: scene.create
data_template:
  scene_id: lounge_light_state
  entities:
    light.lounge:
      state: '{{ states("light.lounge") }}'
      {% if state_attr('light.lounge', 'xy_color') != None %}      
      xy_color:
        - '{{ states.light.lounge.attributes.xy_color[0]|float }}'
        - '{{ states.light.lounge.attributes.xy_color[1]|float }}'
      {% endif %}

NB : if I remove the {% if... %} and {% endif %} lines, the syntax is accepted BUT the automation crashes if the light is off when executed so it’s not safe

You cannot template YAML statements.

Home Assistant processes YAML first and then processes Jinja2. Your example attempts to selectively include/exclude YAML using Jinja2 and that can never work due to the order of processing.

I suggest you use choose so that it can execute two different blocks of scene.create depending on if light.lounge is on or off.

1 Like

Why wouldn’t you use the snapshot feature which was specifically designed to dynamically save the state of any lights you want, so that you can recall them again? It doesn’t matter if the lights are on or off, it essentially grabs all the attributes and saves them.

I use this all the time, for things like - if I open the camera on my phone and I am in the living room, I want the RGB strips to go to full brightness and white, but then return to their previous state (including off) when I close the camera.

1 Like

The Snapshot approach is what I had and it was almost working ! (hence my attempt to find another solution)
But let’s try to crack that snapshot version - Please find the automation yaml code below.

What it does essentially is :

  • when I click a button, my Google speaker announces the next buses and turn a LIFX wifi bulb on either green or red (depending on how soon the next bus is) for 5 seconds => all this works like a charm
  • at the end of the automation, the bulb does turn off (its previous state, good) BUT it keeps the green color in “memory” so that if I turn it on back again immediately (through the LIFX app that shows green as a “pending” status or vocally through Alexa), it’ll be green again and not warm white like it was before the automation :crying_cat_face:

Would it be because I change the color of the bulb within the automation which “breaks” the scene created at the beginning ?..
I must be missing one tiny piece of the puzzle to make it work :grin:

alias: 'Bus : announce next bus on button click with snapshot'
description: ''
trigger:
  - device_id: e89302a904a3c40c4a456307c2dca5d9
    domain: deconz
    platform: device
    type: remote_button_short_press
    subtype: ''
condition: []
action:
  - service: scene.create
    data:
      snapshot_entities:
        - light.lounge
      scene_id: lounge_light_before_status
  - service: media_player.volume_set
    data_template:
      entity_id: media_player.salon
      volume_level: 0.5
  - service: tts.google_say
    data:
      message: >
        {% if states('sensor.ratp_bry_next') == "A l'appro" or
        states('sensor.ratp_bry_next') == "A l'ar" %}
          Next bus in {{ states('sensor.ratp_bry_following') }} minutes
        {% else %}    
          Next buses in {{ states('sensor.ratp_bry_next') }} and {{ states('sensor.ratp_bry_following') }} minutes
        {% endif %}
      entity_id: media_player.salon
  - service: light.turn_on
    data:
      color_name: |
        {% if states('sensor.ratp_bry_next') | int >= 3 %}
          green
        {% else %}
          red
        {% endif %}
      brightness_pct: 100
    target:
      entity_id: light.lounge
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: scene.turn_on
    target:
      entity_id: scene.lounge_light_before_status
mode: single

No it’s not because you change the colour of the bulb in the automation. This is something I come across a lot too. It seems to be down to the way that the White Mode and the Colour mode of RGB bulbs / strip are treated like 2 completely different modes. I typically get round this problem by setting the light back to the white mode before recalling the snapshot scene that we saved at the start. I have sometimes also had better luck by turning on the saved snapshot scene twice before ending the automation. Though for me that is probably because I have automations set up so that if I ask for lights to be turned on, when the light is on it is automatically set to the correct white level based on time of day and brightness based on an outdoor lux sensor. And if I try and turn on a scene that sets the light blue for example - I have to turn it on twice, because the first time the light will turn on, and then immediately set itself to white mode.

I need to find out if there is a way of detecting if the light was turned on manually or from a scene…

@mobile.andrew.jones Thank you for the input.
It seems like your workarounds (that didn’t work for me) kinda defeat the purpose of the snapshot feature and that’s unfortunate :frowning:

So I went back to the other approach described in the article I mentioned in my 1st post and fixed my yaml following @123 's recommandations above.
I ended up with something that does the job even though the warm white color to which the bulb goes back at the end of the automation (when the bulb is on to start with) is slightly different from the original one :laughing:
(I need to do some debugging to find out what’s going on but it’ll do for now)

alias: 'Bus : announce next bus on button click'
description: ''
trigger:
  - device_id: e89302a904a3c40c4a456307c2dca5d9
    domain: deconz
    platform: device
    type: remote_button_short_press
    subtype: ''
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ state_attr(''light.lounge'', ''xy_color'') == none }}'
        sequence:
          - service: scene.create
            data_template:
              scene_id: lounge_light_state
              entities:
                light.lounge:
                  state: '{{ states("light.lounge") }}'
    default:
      - service: scene.create
        data_template:
          scene_id: lounge_light_state
          entities:
            light.lounge:
              state: '{{ states("light.lounge") }}'
              xy_color:
                - '{{ states.light.lounge.attributes.xy_color[0]|float }}'
                - '{{ states.light.lounge.attributes.xy_color[1]|float }}'
  - service: media_player.volume_set
    data_template:
      entity_id: media_player.salon
      volume_level: 0.5
  - service: tts.google_say
    data:
      message: >
        {% if states('sensor.ratp_bry_next') == "A l'appro" or
        states('sensor.ratp_bry_next') == "A l'ar" %}
          Next bus in {{ states('sensor.ratp_bry_following') }} minutes
        {% else %}    
          Next buses in {{ states('sensor.ratp_bry_next') }} and {{ states('sensor.ratp_bry_following') }} minutes
        {% endif %}
      entity_id: media_player.salon
  - service: light.turn_on
    data:
      color_name: |
        {% if states('sensor.ratp_bry_next') | int >= 3 %}
          green
        {% else %}
          red
        {% endif %}
      brightness_pct: 100
    target:
      entity_id: light.lounge
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: scene.turn_on
    entity_id: scene.lounge_light_state
mode: single

Regarding this:

  - choose:
      - conditions:
          - condition: template
            value_template: '{{ state_attr(''light.lounge'', ''xy_color'') == none }}'
        sequence:
          - service: scene.create
            data_template:
              scene_id: lounge_light_state
              entities:
                light.lounge:
                  state: '{{ states("light.lounge") }}'
    default:
      - service: scene.create
        data_template:
          scene_id: lounge_light_state
          entities:
            light.lounge:
              state: '{{ states("light.lounge") }}'
              xy_color:
                - '{{ states.light.lounge.attributes.xy_color[0]|float }}'
                - '{{ states.light.lounge.attributes.xy_color[1]|float }}'

Why are you using the states function to determine the light’s state? xy_color exists only when the light is on and not when it’s off so the light’s state value is already known in each of the two branches in choose.

  - variables:
    light: 'light.lounge'
  - choose:
      - conditions: "{{ is_state(light, 'off') }}"
        sequence:
          - service: scene.create
            data:
              scene_id: lounge_light_state
              entities:
                light.lounge:
                  state: 'off'
    default:
      - service: scene.create
        data:
          scene_id: lounge_light_state
          entities:
            light.lounge:
              state: 'on'
              xy_color: "{{ state_attr(light, 'xy_color') }}"     

NOTE
data_template was deprecated in favor of data several versions ago.

1 Like

Thank you for the corrections about on/off :+1:
Regarding the data_template, that is the problem with outdated threads that one can come across without knowing it :grinning_face_with_smiling_eyes: