Circadian Lighting [Custom Component]

My config:

circadian_lighting:
  min_colortemp: 2200
  max_colortemp: 4000
  interval: 600
  transition: 30

switch:
  - platform: circadian_lighting
    name: Yeelight
    lights_ct:
      - light.yeelight_color2_...
      - light.yeelight_color2_...
    max_brightness: 20
  - platform: circadian_lighting
    name: Tradfri_E27
    lights_ct:
      - light.a
      - light.b
      - light.c
    max_brightness: 40
  - platform: circadian_lighting
    name: Tradfri_E14
    lights_brightness:
      - light.d
      - light.e
      - light.f
    max_brightness: 30

The settings for min and max colortemp are not needed when you only have Yee lights. The default settings worked for me. I have added them because I have a mix of IKEA and Yee lights.
The settings for interval and transistion are not needed too. Again, the defaults worked for me. I have them for the IKEA E14 lights; their brightness does not transition with the default settings.

An easy way to test whether it work is to add the max_colortemp to your config, set a high value, restart HA, the lights will turn bright/white after a minute or 2 after the restart. Then, set a low value, restart HA, the lights should change to a warm light-color after some time after the 2nd restart.

Hope this helps you.

Thank you very much.

My config works, I may revert to default to try.
I think that the problem might be a ratio between interval/transition. I have 300/2, you have 600/30.

I had problems with 60/60.

I will try defaults, I think it’s 900/900. It’s not a big deal, as with 300/2 the eye cannot see the updates and it’s working.

I still have no updates of sleep brightness BTW. I see you don’t use it.

[Edit 01-01-2019] With defaults, I have no more disconnections. I’ve even tried the config that leads to disconnection: no more problems. I hate this because I don’t know what the root cause was. Maybe a problem with timeout from Yeelight server side? Not a big deal, now that’s working, thanks @claytonjn @bouwew for your help!

Happy new year Circadian Enlighted people :slight_smile: !

3 Likes

Hello claytonjn,

Would it be possible to add a sort of wake up light? I have now my own script that sets my lamps to bright cold white in the morning and switches to warm light in the afternoon.
I am thinking of adding a few items to the switch.

switch:
  - platform: circadian_lighting
    name kitchen
    lights:
      - light.kitchen1
      - light.kitchen2    
    wake_up:
      transition: False
      start: 6:30 
      stop: 8:00 
      colortemp: 5000
      brightness: 100

This will set the kitchen lights to max brightness between 6:30 and 8:00 hours at 5000 Kelvin.

For the bedroom you could do something like this:

switch:
  - platform: circadian_lighting
    name kitchen
    lights:
      - light.masterbedroom1
      - light.masterbedroom2    
    wake_up:
      transition: 1800
      start: 6:00 
      stop: 7:00 
      colortemp: 5000
      brightness: 100

The 2 lamps in the master bedroom will start with the minimum value at 6:00 hours and transition to max brightness 1800 seconds = 30 minutes later and the color temp will change to 5000K as well. By then you should be awake… At 7AM the light will switch to the normal schedule again.

Would this be possible and of interest to other as well?

Circadian Lighting already allows you to disable it with a switch. Instead of building in a non core element, I think you’d be better off using the built in function to disable CL, run your wake up light script, and then enable CL again when your script is finished. Remember, you can have multiple CL switches for different groups of lights.

Thanks, yes that would be possible. I did not think about that.

However I think it is less clean doing that way. To me it would make more sense to set all the color temperatures in one component. I really do not like to have one part of a component set up in one location and another part somewhere else.

@claytonjn Can there be a check added for the light’s color temperature range? I’m seeing errors with negative values for colortemp.

example: Circadian color temperature range is 2000-4000K. This works fine for lights which go as low as 2000 and high as 4000. But if a light only goes to 2100, the switch still attempts to set 2000 and gets an error and doesnt change the temperature.

ERROR (MainThread) [homeassistant.core] Error executing service <S erviceCall light.turn_on (c:85e6c83e18674ab1a85bb6233cf85d6d): entity_id=[‘light.bedro om_wall_lamps’], color_temp=588, brightness=161, transition=0.0>
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.6/site-packages/homeassistant/components/light/ xiaomi_miio.py”, line 286, in _try_command
partial(func, *args, **kwargs))
File “/usr/local/lib/python3.6/concurrent/futures/thread.py”, line 56, in run
result = self.fn(*self.args, **self.kwargs)
File “/srv/homeassistant/lib/python3.6/site-packages/miio/philips_bulb.py”, line 139 , in set_brightness_and_color_temperature
raise PhilipsBulbException(“Invalid color temperature: %s” % cct)
miio.philips_bulb.PhilipsBulbException: Invalid color temperature: -158

I have another use case for different sensors (color) settings, as discussed above, there, and there

In the same room, I have same light bulbs in different appliances and different “light projections”
As I like my wall lights going from min to max colortemp because wall color is greyish/whiteish, I like to have a cutoff on the lunch table, to avoid an uncomfortable effect (already had complaint from wife or guests “we feel like in an hospital”).

I fix it with an high cut filter in my automation

automation
- alias: 'Lampes Table couleur'
  initial_state: 'on'
  trigger:
  - entity_id: light.yeelight_ct2_7c49ebb7d46a
platform: state
to: 'on'
  - entity_id: sensor.circadian_values
platform: state
  condition:
  - condition: state
entity_id: light.yeelight_ct2_7c49ebb7d46a
state: 'on'
  action:
  - service: light.turn_on
data_template: 
    entity_id: light.yeelight_ct2_7c49ebb7d46a # Table salon
    # transition: >
    #     {%- if as_timestamp(now()) - as_timestamp(states.automation.lampes_table_couleur.attributes.last_triggered) > 10 -%}
    #         {{ states.sensor.circadian_values.attributes.transition | int }}
    #     {%- else -%}
    #         2
    #     {%- endif -%}
    kelvin: >
        {%- if states.sensor.circadian_values.attributes.colortemp <= 3921 -%}
            {{ states.sensor.circadian_values.attributes.colortemp | int }}
        {%- else -%}
            3921
        {%- endif -%}

(I have yet to make the transisition part working)

I could do this because it seems that all lights report max_mireds and min_mireds (at least mine do - Hue and Lightify), however it would require querying the light attributes for every selected light, and doing some logic to figure out the min and max of all lights selected, every single time the code runs (every interval). That also assumes that the min_mireds and max_mireds values are correct. I think it would be much better for the user to just figure it out once during the initial setup and have the code me more efficient…

I appreciate your input, but again, this goes against the core intention of this component. Honestly, if you’re allowing any lights to bypass the circadian values you’re throwing off your biological rhythm so there’s really no point in having this component at all - if they think it’s like a hospital that’s probably because hospitals are designed to make patients comfortable. There are other components/methods you can use to allow varying color temperature throughout the day, Circadian Lighting specifically is focusing on keeping everything in sync to maximize the biological benefits. At this time I have no plans on programming in any way to allow color temperature to be out of sync between groups of lights, the in-place overrides are intended for one-off temporary overrides. The only real argument I’ve considered for taking color temperature at the switch level is when different model lights appear different when set to the same CT but even that is something I want to avoid compensating for because it should be fixed at the device level.

Hi Clayton,

I am in this case:

The only real argument I’ve considered for taking color temperature at the switch level is when different model lights appear different(not different lights but different reflective material.

Overall, all my lights are in sync in all my appartment. I listen and respect your arguments. Lights are different in hospital/restaurant/lounge bar for a purpose I think. (I’m not going that far). Because off the direct light exposition and white reflector on this specific light, I guess it appears agressive compared to the wall paint that may “absorb” some part of the light spectra.

BTW I will think about keeping or not my “low pass filter”, or set the whole lights the same.

Overall, CL improved our life, many thanks Clayton !

Thanks for the component, I’m currently testing it to replace flux in my setup :slight_smile:

Do you have plans to get this mainlined at some point?

Btw, with embedded platforms it is now possible to contain the code inside a single directory (which would allow it to be easily pulled from a git repository), here’s the structure under ~/.homeassistant:

custom_components/circadian_lighting/
custom_components/circadian_lighting/__init__.py
custom_components/circadian_lighting/switch.py
custom_components/circadian_lighting/sensor.py

1 Like

hi all,
i may have a stupid question, can anyone tell me when the lights should be brightest?
it’s pitch dark outside here (around 10 pm) and the lights are at around 30% (which is just a little bit above my min_brightness
Is my assumption correct that it will go darker the later it is in the day?

Sure, I’d love to, at some point.

Thanks, I do plan on making this change as soon as I have time.

1 Like

Yes, they start at max_brightness at sunset, dim down to min_brightness (half way between sunset and sunrise) then brighten back to max_brightness at sunrise.

@claytonjn

Can you make this plugin compatible with this plugin?

Or it is already compatible?

See his response to my comment above, from the page you linked

@claytonjn, others

I had an idea: during evening, I want my kitchen lights to be on low brightness when nobody is in the kitchen.And turn to a higher brightness when somebody enters the kitchen.
I made something that works, kind off. My config for this, looks like this:

circadian_lighting:
  interval: '20'
  transition: '20'

switch:
  - platform: circadian_lighting
    name: Tradfri_GU10
    lights_ct:
      - light.tradfri_bulb_10
      - light.tradfri_bulb_11
      - light.tradfri_bulb_12
      - light.tradfri_bulb_8
      - light.tradfri_bulb_9
    min_brightness: 31
    max_brightness: 70
    disable_entity: 'binary_sensor.motion_sensor_xyz'
    disable_state: 'off'
  - platform: circadian_lighting
    name: Tradfri_GU10_dimmed
    lights_ct:
      - light.tradfri_bulb_10
      - light.tradfri_bulb_11
      - light.tradfri_bulb_12
      - light.tradfri_bulb_8
      - light.tradfri_bulb_9
    max_brightness: 40
    disable_entity: 'binary_sensor.motion_sensor_xyz'
    disable_state: 'on'

in the HA log I see 10 errors after a restart (all the same as shown below), they must be linked to the above configuration.

Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/switch/circadian_lighting.py", line 332, in light_state_changed
    self.adjust_lights([entity_id], 1)
  File "/config/custom_components/switch/circadian_lighting.py", line 266, in adjust_lights
    if self.should_adjust():
  File "/config/custom_components/switch/circadian_lighting.py", line 259, in should_adjust
    elif self._attributes['disable_entity'] is not None and self.hass.states.get(self._attributes['disable_entity']).state == self._attributes['disable_state']:
AttributeError: 'NoneType' object has no attribute 'state'

So I must be doing something that’s not correct.

Can maybe someone provide some help? Is there a better way to implement this?

Basically what’s happening is that the Circadian Lighting switches are being initialized before your motion_sensor_xyz, so when CL tries to check the state there’s nothing there.

I think there’s a way with async to have CL wait until the disable_entity exists before trying to query the state…I’ve been wanting to implement async but I have no experience with it and haven’t had the time to learn.

In the mean time I should probably have it check if the entity exists yet before checking its state, but for now you should be able to just ignore the error.

OK, thank you for the explanation.I will ignore the errors :slight_smile:

Can I ask you about advice regarding my implementation?
Right now, the switch from low brightness to high brightness is not instantaneous. It takes at least 20 seconds.
I can decrease the numbers even more, but I wonder, is there another way to implement this?
I tried something with the “circadian_lighting.values_update” service, but that did no do anything.