Slave Lamp Brightness to Other Lamp

Okay, This is embarassing

I ‘used’ to have an automation that slaved two lamps together (Just on/off).
All my lights have set brightness’s for different parts of the day
I found the lamps are ‘sometimes’ not right if we watch TV in the evening so ‘extending’ the above old automation to ‘brightness’ seemed the way to go.

I’ve played with this for nearly 8 hours and I can’t see the wood for the trees.
my aim was to have two automations to cope with all circumstances (like I used to have)
I can’t get the syntax right - I’m blind to the problem
So each automation is a mirror of the other, here’s the first
Can anyone else see what’s wrong ?

automation:
  #name: Lamp01 Link
  - alias: au_light_lamp01_link
    trigger:
      - platform: state
        entity_id: light.fibdim2_lamp01_level
    condition:
      - condition: state
        entity_id: input_boolean.ib_light_lamp01and02_link
        state: 'on'
      - condition: template
        value_template: "{{ (now() - state_attr('automation.au_light_lamp02_link', 'last_triggered')).seconds > 3 }}"
    action:
      - service_template: input_boolean.turn_"{{ states('light.fibdim2_lamp02_level') }}"
        entity_id: input_boolean.ib_light_lamp_other_lamp_on
      - service_template: light.turn_{{ trigger_to.state.state }}
        entity_id: light.fibdim2_lamp02_level
      - condition: template
        value_template: "{{ trigger_to.state.state == 'on' }}"
      - delay: '00:00:01'
      - service: light.turn_on
        data_template:
          entity_id: light.fibdim2_lamp02_level
          brightness: "{{ state_attr('light.fibdim2_lamp01_level', 'brightness') | int }}"
      - service_template: >
          {% if trigger.from_state.state == 'off' or is_state('input_boolean.ib_light_lamp_other_lamp_on', 'off') %}
            script.sc_light_lamp0102_reset
          {% else %}
            homeassistant.update_entity
          {% endif %}

I know it’s gonna be something stupid
Thanks in advance
:beers:

Edit: Sorry. forgot the script : -

script:
  sc_light_lamp0102_reset:
    alias: Lamp 01 On 02 To On
    sequence:
      - service: script.turn_off
        entity_id: script.sc_light_lamp01_timer, script.sc_light_lamp02_timer
      - service: script.sc_light_lamp01_timer
      - service: script.sc_light_lamp02_timer

The referenced scripts are timers to turn the lamps off after set times, only needs resetting “IF” one of the lamps was ‘off’

Dumb question - is there a reason you’re not using light groups? Do you want to control them individually as well? :thinking: https://www.home-assistant.io/integrations/light.group/

1 Like

Yes, in normal use they are separate lamps, when the TV is on they are slaved together using the ‘input_boolean.ib_light_lamp01and02_link’
They are already in a much larger group and ‘most of the time’ that works flawlessly, so I don’t want to mess with that.

Hang On - This just passed config check.
Let me re Start and re Test

:crossed_fingers:

Nope it passes config check but no joy on functionality

You can add the bulbs to a light group without affecting the other group they’re in and without affecting individual control

These lights are in the lights ‘all_remaining’ group
ie they do not belong to the other groups created but to the rest (habitable).
Other groups are ‘kitchen’ ‘bathrooms’ ‘bedrooms’ ‘outside’ and ‘office’
And those groups are used to control the brightness (from a profile (different for each group)) within that group to the profile.
There are master values, which get fed into the groups for each time of day (tod) for each group (these directly affect the groups lights) but the ‘fed to’ values can also be adjusted to affect all lights in that group (but not fed back to the master).
Similarly the individual lights can be adjusted without affecting the group.
To change these for these two would require the creation of a new group just for use when the TV is on as otherwise they should behave ‘exactly’ the same as ‘all remaining’
I think this is even more complicated.

eg halfway though a film the ‘all remaining’ may go through a transition. But these lamps have their transition blocked. So a lot of editing to incorporate a new group with new transitions and blocks.

All Right,
I have a solution.
It’s not pretty, but I’ve learned a lot.
If you can possibly get away with using a light group as @fedot and @Tediore suggested above, go with that. It will save you a LOT of headaches.

The BIGGEST problem I had is not wanting to run the same automation again within a given period.
Easy you say :- “Just check that ‘last triggered’ was more than x seconds ago”.
Well, this is a new automation and has never been triggered so you then have to cope with either None or null depending how you accessed it (hint :- state_attr(‘automation.myautomation’,‘last_triggered’) gives you None)
Anyway assuming you want at least a 10 second gap, @petro posted a solution on : -

De-mangled it looks like this : -

{% set last_triggered = state_attr('automation.auto_whichexistsbuthasneverbeenrun','last_triggered') or (as_timestamp(now()) - 11) %}
{{ (as_timestamp(now()) - last_triggered) | int > 10 }}

Alternate version not using state_attr (it’s a bit longer ! and according to the docs, less robust)

{% set last_triggered = as_timestamp(states.automation.auto_whichexistsbuthasneverbeenrun.attributes.last_triggered) or (as_timestamp(now()) - 11) %}
{{ (as_timestamp(now()) - last_triggered) | int > 10 }}

See that 11 is > 10 etc.
This will also work if you set any of your automations with initial: true (generally a big mistake, as it resets this attribute)

Regardless, I was up against it and had promised the wife I’d get this working, I used a quick and dirty solution using an input boolean, and an automation containing a delay. (Will re-write when I have time).

Automation - Don’t run if boolean on, boolean on - start delay to switch it off (I said it was dirty)
I also need to know the status’s of each lamp when the automation came to them so I used another couple of boolean’s there too.

Long and the short, it works but if anyone can improve upon it. It will teach me even more
There are 3 automations :-

  1. First sync the lamps, IF one is ‘on’ and the other ‘off’ (if they are both on with different brightness - Tough !)
  2. The second checks when Lamp01 changes and syncs Lamp02 and …
  3. The third does as 2. but is the mirror version.
automation:
  - alias: au_light_lamp0102_lnk_on
    trigger:
      - platform: state
        entity_id: input_boolean.ib_light_lamp01and02_link
        to: 'on'
    condition:
      - condition: state
        entity_id: input_boolean.ib_light_lamp0102_timer
        state: 'off'
      - condition: template
        value_template: "{{ states('light.fibdim2_lamp01_level') != states('light.fibdim2_lamp02_level') }}"
    action:
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_light_lamp0102_timer
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_aalight_stop_adjust
      - service_template: input_boolean.turn_{{ states('light.fibdim2_lamp01_level') }}
        entity_id: input_boolean.ib_light_lamp01_on
      - delay: '00:00:01'
      - service: light.turn_on
        data_template:
          entity_id: >
            {% if is_state('input_boolean.ib_light_lamp01_on', 'on') %}
              light.fibdim2_lamp02_level
            {% else %}
              light.fibdim2_lamp01_level
            {% endif %}
          brightness_pct: >
            {% if is_state('input_boolean.ib_light_lamp01_on', 'on') %}
              {{ (state_attr('light.fibdim2_lamp01_level', 'brightness') | float / 255 * 100) | int }}
            {% else %}
              {{ (state_attr('light.fibdim2_lamp02_level', 'brightness') | float / 255 * 100) | int }}
            {% endif %}
          transition: "{{ states('input_number.in_aalight_normal_transition') | int }}"
      - delay: '00:00:09'
      - service_template: input_boolean.turn_off
        entity_id: input_boolean.ib_aalight_stop_adjust
      - service: script.sc_light_lamp0102_reset

  - alias: au_light_lamp01_lnk
    trigger:
      - platform: state
        entity_id: light.fibdim2_lamp01_level
    condition:
      - condition: state
        entity_id: input_boolean.ib_light_lamp0102_timer
        state: 'off'
      - condition: state
        entity_id: input_boolean.ib_light_lamp01and02_link
        state: 'on'
    action:
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_light_lamp0102_timer
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_aalight_stop_adjust
      - service_template: input_boolean.turn_{{ states('light.fibdim2_lamp01_level') }}
        entity_id: input_boolean.ib_light_lamp01_on
      - service_template: input_boolean.turn_{{ states('light.fibdim2_lamp02_level') }}
        entity_id: input_boolean.ib_light_lamp02_on
      - delay: '00:00:01'
      - service: light.turn_on
        data_template:
          entity_id: light.fibdim2_lamp02_level
          brightness_pct: >
            {{ 0 if trigger.to_state_state == 'off' else (state_attr('light.fibdim2_lamp01_level', 'brightness') | float / 255 * 100) | int }}
          transition: "{{ states('input_number.in_aalight_normal_transition') | int }}"
      - delay: '00:00:09'
      - service_template: input_boolean.turn_off
        entity_id: input_boolean.ib_aalight_stop_adjust
      - condition: template
        value_template: "{{ states('input_boolean.ib_light_lamp01_on') != states('input_boolean.ib_light_lamp02_on') }}"
      - service: script.sc_light_lamp0102_reset

  - alias: au_light_lamp02_lnk
    trigger:
      - platform: state
        entity_id: light.fibdim2_lamp02_level
    condition:
      - condition: state
        entity_id: input_boolean.ib_light_lamp0102_timer
        state: 'off'
      - condition: state
        entity_id: input_boolean.ib_light_lamp01and02_link
        state: 'on'
    action:
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_light_lamp0102_timer
      - service: input_boolean.turn_on
        entity_id: input_boolean.ib_aalight_stop_adjust
      - service_template: input_boolean.turn_{{ states('light.fibdim2_lamp01_level') }}
        entity_id: input_boolean.ib_light_lamp01_on
      - service_template: input_boolean.turn_{{ states('light.fibdim2_lamp02_level') }}
        entity_id: input_boolean.ib_light_lamp02_on
      - delay: '00:00:01'
      - service: light.turn_on
        data_template:
          entity_id: light.fibdim2_lamp01_level
          brightness_pct: >
            {{ 0 if trigger.to_state_state == 'off' else (state_attr('light.fibdim2_lamp02_level', 'brightness') | float / 255 * 100) | int }}
          transition: "{{ states('input_number.in_aalight_normal_transition') | int }}"
      - delay: '00:00:09'
      - service_template: input_boolean.turn_off
        entity_id: input_boolean.ib_aalight_stop_adjust
      - condition: template
        value_template: "{{ states('input_boolean.ib_light_lamp01_on') != states('input_boolean.ib_light_lamp02_on') }}"
      - service: script.sc_light_lamp0102_reset

Each Lamp has a script that runs when it goes from ‘off’ to ‘on’, containing a delay to turn it off again. The script.sc_light_lamp0102_reset script cancels both of those and restarts them.
Any Lamp going ‘off’ cancels it’s own script.