Circadian Lighting: Possible fix to keep light groups off

Tags: #<Tag:0x00007f73964345c0>

Update: You might consider using @basnijholt’s new and improved Circadian Lighting fork named “Adaptive Lighting” instead. It has a lot more intelligence built in to avoid issues like this.

However, if you still have problems with Zigbee light groups not turning off every bulb, then look at this much simplified automation instead.


Circadian Lighting: Possible fix to make light groups stay turned off

Difficulty: Advanced

The problem

I have multiple light fixtures which have more than one Zigbee bulb. So I created Zigbee groups for each fixture. Unfortunately, with Circadian Lighting enabled for these light groups, the bulbs all turn back on within 2 seconds - 2 minutes. This is a known issue without a documented fix so far.

The problem occurs while the bulbs fade to black. The light group briefly itself off to Home Assistant, but then realizes bulbs in the group have a brightness > 0%, so it changes the state back to on. Well, Circadian Lighting now sees a light which has just turned on, so it dutifully starts adjusting the light colors/brightness appropriate for the current time of day. <sarcasm>How helpful!</sarcasm> :stuck_out_tongue_winking_eye:

Now that we know the problem, I managed to come up with a solution which took some extra work to pull off. In the end I think the effort is work it (so long as it ends up being as reliable as I hope it is).

Proposed solution

I have put together an automation which triggers when one of my light groups turn off. It relies on several of the features added in 0.113: mode: parallel, and an until loop!

Home Assistant group of lights

Unfortunately ZHA doesn’t provide a list of entity_id’s in the light group, so I created light fixture groups for all four of my fixtures. Here is one such example.

group:
  name: Family Room Floor Lamp Fixture
  entities:
    - light.family_room_floor_lamp1
    - light.family_room_floor_lamp2
    - light.family_room_floor_lamp3

Circadian Lighting switches

I broke my Circadian Lighting mode switches up. Here is are two examples.

switch:
  - platform: circadian_lighting
    name: Dining Room
    lights_ct:
      - light.dining_room

  - platform: circadian_lighting
    name: Family Room Floor Lamp
    lights_brightness:
      - light.family_room_floor_lamp

Light group turns off automation

Here I break down what happens when I turn my Family Room Floor Lamp off.

  1. This automation is triggered when the Floor Lamp’s state changes to off (ie. light.family_room_floor_lamp).
  2. Don’t bother preforming any actions if Circadian Lighting mode is disabled for the Floor Lamp (ie. switch.circadian_lighting_family_room_floor_lamp).
  3. Temporarily disables Circadian Lighting mode only for the Floor Lamp.
  4. Delay for 5 seconds.
  5. Tell Home Assistant to turn off the Floor Lamp’s “Home Assistant group of lights” (ie. group.family_room_floor_lamp_fixture).
  6. Are the lights actually off now? If not, return to step #4.
  7. Delay for 5 seconds.
  8. Enable Circadian Lighting mode for the Floor Lamp.
alias: "Circadian Lighting: Force Light Groups To Stay Off"
id: circadian_light_group_turn_off
initial_state: true
mode: parallel
trigger:
  - platform: state
    entity_id:
      - light.brian
      - light.dining_room
      - light.family_room_floor_lamp
      - light.play_room_floor_lamp
    to: "off"
condition:
  # Only when circadian lighting is enabled for this light group.
  - condition: template
    value_template: "{{ is_state(trigger.entity_id|replace('light.','switch.circadian_lighting_'), 'on') }}"
action:
  # Temporarily disable the circadian lighting mode for this fixture.
  - service: switch.turn_off
    data_template:
      entity_id: "{{ trigger.entity_id|replace('light.','switch.circadian_lighting_') }}"

  - alias: Turn the light group off repeatedly until it stays off.
    repeat:
      sequence:
        - delay:
            seconds: 5

        # Turn the light group off, again.
        - service: homeassistant.turn_off
          data_template:
            entity_id: "{{ trigger.entity_id|replace('light.','group.') + '_fixture' }}"
      until:
        - condition: template
          value_template: "{{ is_state(trigger.entity_id, 'off') }}"

  - delay:
      seconds: 5

  # Turn the circadian lighting mode back on.
  - service: switch.turn_on
    data_template:
      entity_id: "{{ trigger.entity_id|replace('light.','switch.circadian_lighting_') }}"

Conclusion

I have only has this solution in place for a couple of hours so I don’t know how reliable it will be in the long run. Thus far it is a massive improvement over the failure I was experiencing before this fix. :slight_smile:

Honestly this solution is complex. You could probably simplify the code a bit by avoiding the ZHA and Home Assistant Light Groups (ie. light.family_room_floor_lamp), and directly controlling the lights GROUP (ie. group.family_room_floor_lamp).

3 Likes

I am playing with something similar currently.
Would it also work maybe to:
Trigger on any light going off
Disable the circadian switch where this light belongs to
Wait 10 seconds
Turn on circadian switch?

Or is there something I am missing here?

Basically. However, I needed the Repeat turn the light off repeatedly until they are actually off. Leaving that out the lights would just turn right back on.

I am trying this right now (shorter delays like 5 sec. helped a lot already but where not 100% reliable):

- id: '1598208244342'
  alias: circadian lighting workaround vorzimmer
  description: ''
  trigger:
  - entity_id: light.vorzimmer_light, light.gang_light
    platform: state
    to: 'off'
  condition:
  - condition: state
    entity_id: switch.circadian_lighting_vorzimmer
    state: 'on'
  action:
  - data: {}
    entity_id: switch.circadian_lighting_vorzimmer
    service: switch.turn_off
  - delay: '130'
  - data: {}
    entity_id: switch.circadian_lighting_vorzimmer
    service: switch.turn_on
  mode: single
1 Like

Sweet. Simple code that does the same job done is always better.

1 Like

It would be nice if one could configure CL to only trigger when a light is on for x seconds. But the author stated on his page that he does not want to do that.
Maybe a fork or PR is on order :grinning:

I understand why that would be undesirable. It would cause the light to turn on full brightness, then it would suddenly change after the delay. I believe our work-around for individual troublesome light fixtures is the lesser of two evils so to speak. :slight_smile:

You could just turn on the lights to the right brightness and color already like kn CLs advanced use section described.

Or use Adaptive Lighting that supports light groups! :tada:

It will also make it to core at some point, however, that might take months still (see this PR).

2 Likes

I installed it recently, but I have Circadian Lighting so embedded in my setup that I need to really do my homework so I don’t mess my lighting up. I am reading through the PR comments now, and am looking forward to trying it soon.

Nice. Does this solve the issue that some types of lights get turned on my CL again after being turned off intentionally? Like z2m or that lights?

It should! For me with deCONZ + Hue it works 100% of the time.

2 Likes

I’m taking the plunge, and after reading the Pull Request discussion and the related documentation I’m excited!

Since there’s no official Adaptive Lighting message thread yet, and I’m unsure whether the PR is the correct place to ask.

  1. Does adaptive_lighting.set_manual_control accept multiple entities in the entity_id attribute? I ask because I am wondering if it necessary to create two separate service calls or not.
  2. Why lights not optional? It seems like omitting the lights parameter would simple apply the manual_control state to all lights in the entity_id’s list. I’m sure there will be instances where I want to set it for a single light, however it seems redundant otherwise.
  1. Does adaptive_lighting.set_manual_control accept multiple entities in the entity_id attribute? I ask because I am wondering if it necessary to create two separate service calls or not.

Yes, see the screenshot from the docs.

  1. Why lights not optional? It seems like omitting the lights parameter would simple apply the manual_control state to all lights in the entity_id’s list. I’m sure there will be instances where I want to set it for a single light, however it seems redundant otherwise.

That is a good suggestion! Would you mind opening an issue such that I won’t forget?

1 Like

I’ve been using adaptive lighting for a few weeks now and it is amazing. It works great (also deconz+hue here, but also works great on my WiFi lights!).

I would highly recommend this component (just be aware that it is not the final product and that there are many updates and it could break somewhere in between). This has not happened for me however in all those weeks!

Thanks @basnijholt

2 Likes

I’ve implemented your suggestion now :slight_smile:

Adaptive Lighting

Good news!
Adaptive Lighting does not interfere like Circadian Lighting did.

Bad news!
A work-around is still required for me to get my ZHA light bulb groups. But, the solution is a bit simplier!

Simplified automation

This solution still requires the creation of a group named the same as your light group. This group needs to contain every bulb in that fixture. Example: for light.dining_room I created group.dining_room_fixture with all 9 bulbs.

alias: "Light Group Turn Off - Force To Stay Off"
id: light_group_turn_off
initial_state: true
mode: single

trigger:
  - platform: state
    entity_id:
      - light.dining_room
      - light.play_room_floor_lamp
    from: "on"
    to: "off"

variables:
  light: '{{ trigger.entity_id }}'
  group: '{{ light | replace("light.","group.") + "_fixture" }}'
  bulbs: '{{ expand(group) | map(attribute="entity_id") | list }}'

action:
  - alias: Turn the light group off repeatedly until it stays off.
    repeat:
      sequence:
        - delay:
            seconds: 5

        # Turn off the individual bulbs one at a time.
        - repeat:
            count: "{{ bulbs|count }}"
            sequence:
              - service: light.turn_off
                data:
                  entity_id: '{{ bulbs[repeat.index-1] }}'

      until:
        - condition: template
          value_template: "{{ is_state(light, 'off') }}"

Just out of curiosity: Does HA provides service calls to change light attributes (color warmth, brightness etc) without turning the light on?

There are devices which are designed to accept such changes separately to on/off commands. But AFAIK HA’s light service provides TURN_ON/OFF/Toggle methods only.

If you adk why: I want to be sure that a light turns on with warmth and intensity already set to expected values.

If there is no such feature, I have to stick with proxying warmth changes to mqtt where mentioned devices can pick them from

@maxym You are correct. The only way to set the light attributes is at the same time as the light.turn_on command. However, my lights turn on to the correct setting every time, from the off position. I just experimented with calling light.turn_on to blue, after turning my bulb off after changing it red. The color was blue the second it started fading up from off.

Can you expose a sensor that shows the current color temp and brightness?
I’d need this because I control my light mostly from node red and I’d like to turn the bulbs on to the correct color and brightness straight away. That works fine with CL.