Dynamic Attributes

I’m trying to synchronize two light entities using automation. I’ve been able to get the lights to go from an ‘off’ state to an ‘on’ state together and I can synchronize the brightness as well. The issue is when the lights go from an ‘on’ state to an ‘off’ state. My data_template provides the ‘brightness’ attribute, but you can’t provide that attribute in a call to the light.turn_off service. The automation is below. How can I dynamically provide the brightness attribute when the service_template resolves to ‘light.turn_on’ and not provide the brightness attribute when the service_template resolves to ‘light.turn_off’?

- id: '1546388168273'
  alias: Mirror Bedroom Light Levels
  trigger:
  - entity_id: light.left_bedside_light
    platform: state
  - entity_id: light.right_bedside_light
    platform: state
  condition: []
  action:
  - service_template: >
      {%- if trigger.to_state.state == 'on' -%}
        light.turn_on
      {%- else -%}
        light.turn_off
      {%- endif %}
    data_template:
      brightness: '{{ trigger.to_state.state.attributes.brightness }}'
      entity_id: >
        {%- if trigger.entity_id == "light.left_bedside_light" -%}
          light.right_bedside_light
        {%- elif trigger.entity_id == "light.right_bedside_light" -%}
          light.left_bedside_light
        {%- endif -%}

make 2 automations, one for on, one for off. scripts accept any amount of variables.

if you want 1 automation, you’ll need to make 2 scripts that accept variables. But then, only 1 script can be ran at a time. So adding more lights will cause issues.

Personally, id go 2 automation route:

- alias: Mirror Bedroom Light On
  trigger:
  - platform: state
    entity_id: light.right_bedside_light, light.left_bedside_light
    from: 'off'
    to: 'on'
  action:
    service: light.turn_on
    data_template:
      brightness: '{{ trigger.to_state.state.attributes.brightness }}'
      entity_id: >
        {%- if trigger.entity_id == "light.left_bedside_light" -%}
          light.right_bedside_light
        {%- elif trigger.entity_id == "light.right_bedside_light" -%}
          light.left_bedside_light
        {%- endif -%}

- alias: Mirror Bedroom Light Off
  trigger:
  - platform: state
    entity_id: light.right_bedside_light, light.left_bedside_light
    from: 'on'
    to: 'off'
  action:
    service: light.turn_off
    data_template:
      entity_id: >
        {%- if trigger.entity_id == "light.left_bedside_light" -%}
          light.right_bedside_light
        {%- elif trigger.entity_id == "light.right_bedside_light" -%}
          light.left_bedside_light
        {%- endif -%}

You may want to add a condition to do nothing when the other light is on as well.

might be a silly solution, but I have the exact setup, as I suppose many of us have here… just throw the 2 lights in a group and turn_on/off that group. ?

Which of course only works if you’re alone ;=)
but, if you’re not, there’s no use using the automation in the first place I would think, or? Don’t want to mess with the other half’s light…

adding the |int to attribute brightness is a little trick (call it a hack) that would probably make this possible with 1 automation. If the triggering light is off, it has no brightness. Using the |int makes that 0, which is then used to switch off the other light ;-). I

- alias: Mirror Bedroom Lights
  trigger:
    platform: state
    entity_id: light.right_bedside_light, light.left_bedside_light
  condition:
    condition: template
    value_template: >
      {{ trigger.to_state.state in ['on','off']
  action:
    service_template: >
       light.turn_{{trigger.to_state.state}}
    data_template:
      brightness: >
        {{ trigger.to_state.state.attributes.brightness|int }}'
      entity_id: >
        {% if trigger.entity_id == 'light.left_bedside_light' %}
          light.right_bedside_light
        {% elif trigger.entity_id == 'light.right_bedside_light' %}
          light.left_bedside_light
        {% endif %}

or

  entity_id: >
    light.{('right_bedside_light' if trigger.entity_id == 'light.left_bedside_light' else 'left_bedside_light' }}

Thanks. Ultimately I ended up creating an on automation and an off automation as petro had suggested.

I’m not sure I understand the use of the |int that Mariusthvdb is suggesting. I get that it will default in a 0 if the triggering device does not have any brightness valued, but the issue with my original automation is that HA logs an error is you pass the brightness attribute at all in a call to the light.turn_off service and the automation fails.

I don’t think the int trick will work because the turn_off service does not accept any attributes in the data, which is the root cause of the issue. So while adding the int will work when trigger.to_state.state.attributes.brightness doesn’t exist, but it will not solve the end goal which is to “not include brightness to the data dictionary”.

ah yes, you’re probably right on that one.
Ive rechecked and see indeed that i use light_turn.on with brightness |int being 0. That will do I think?

action:
  service: light.turn_on
  data_template:
    entity_id: light.parking_light
    brightness: >
      {{state_attr('light.parking_light','brightness') |int }}

I use this to check if the light is available or not, If it is (has power) it will turn on with the current brightness. If it is not (has no power) brightness doesn’t exist, and turning it on with brightness|int will make that 0.

worth a try!