cool project. A newb question, will this work only during daylight?
Hi Claudio,
the current setup is meant to be for a natural daylight simulation, and my definition of “day” is as soon as the sun goes up (sunrise around 80 degrees azimuth) until the sun goes down (sunset around 280 degrees azimuth). The mired update continues working automatically, even beyond sunset. It will then depend on your use case, how you’re going to change the algorithm to your needs…
Cheers,
Markus
I had a look at Flux 'cause it has some similarities with my project. What Flux could not do for me was to be a bi-directional (increase/decrease) solution, since Flux is unidirectional (from start_colortemp to stop_colortemp).
If I understand correctly, this follows the actual position of the sun, as it changes around the year. I live in Sweden, so I would really prefer not to have an emulated indoor sunset at 15:30 mid-winter… Is there any way one could define an ideal day, or sunset & sunrise times and have that repeat all year round? The Swedish Brainlit uses April 16th (if I recall correctly) for the “ideal” workday as office lighting schedule.
That’s an interesting thought, so let me try to elaborate on how I understand your request. If you opt for a “static” approach, you might want to have a look at this example:
In this way, you would be able to set static color_temp
as per the hour of the day and likewise simulate the “ideal day” that you’re looking for. As my wife spent some time in Sweden during studies, I learnt the hard way, how frustrating short daylight-periods can be during the winter, so totally understand why you’re looking for this approach
HI
Trying your approach, please let me ask first if here you point to the sensor.farbtemp? there’s no sensor.colortemp in your post so I hope im not mistaken…
Checking the states of my Hue-Lights, I cant find the color temp any longer… are we sure this still works as you describe, od do we need th adapt further, along the changes in the Hue/Hassio setup lately:
I have tried with the light.Hue_go_1:
customize to show in the frontend:
light.hue_go_1:
icon: mdi:transfer
extra_data_template: >
if (attributes.hs_color || attributes.rgb_color)
return 'Hs: ' + attributes.hs_color
+ ' | ' + 'Rgb: ' + attributes.rgb_color;
return null;
state_card_mode: break-slider
stretch_slider: true
hide_control: false
show_last_changed: true
confirm_controls: true
slider_theme:
min: 0
max: 255
pin: true
off_when_min: true
report_when_not_changed: true
extra_badge:
- attribute: brightness
unit: Br
- attribute: color_temp
unit: Co
and the states:
As you can see, no more color temp…
checking the Hue Api for this light, there is ct
, but this isnt supported on the Hassio instance?:
10":{"state":{"on":true,"bri":136,"hue":7676,"sat":199,"effect":"none","xy":[0.5016,0.4151],"ct":443,"alert":"none","colormode":"xy","mode":"homeautomation","reachable":true},"swupdate":{"state":"noupdates","lastinstall":"2018-02-19T13:27:28"},"type":"Extended color light","name":"Hue go 1","modelid":"LLC020","manufacturername":"Philips","productname":"Hue go","capabilities":{"certified":true,"control":{"mindimlevel":40,"maxlumen":300,"colorgamuttype":"C","colorgamut":[[0.6915,0.3083],[0.1700,0.7000],[0.1532,0.0475]],**"ct":{"min":153,"max":500}**},"streaming":{"renderer":true,"proxy":true}},"config":{"archetype":"huego","function":"decorative","direction":"omnidirectional"},"uniqueid":"unique idxxxxx","swversion":"5.105.0.21169"}
since your circadian sensor calculates the ct to be this:
something must be wrong
still, I see the light change but right now it keeps turning down, instead of turning to the regular evening setting…
What should I check?
update:
setting it manually in the dev tools works!, and also reveals the color_temp attribute in the state machine:
see the frontend:
I am somewhat puzzled…
btw any thoughts on the brightness to go with the color_temp? Is there a circadian setting for that too?
thx!
Marius
My apologies: yes, I mean sensor.farbtemp. Sorry for that.
I have this config up and running in version 0.60.1 as per today. No idea if there have been any “breaking changes” to the HUE API in the meantime. Can anybody else find out?
Your setup is working fine for me. I had to wiggle a few things to support the new automations.yaml formatting that was introduced some time ago, and I caught the sensor.farbtemp issue too, but aside from that, this is working great for me on 0.72.1.
working right now, just have to figure out why the light switches off , or on with rgb/hs settings, in which case the color_temp is not available of course. (believed the circadian automation to do that, but now believe something else is doing it, since the circadian sensor is correct, and now also showing on the light in the frontend)
the thing that might confuse the light is, that this is a color lamp, and color_temp is mutually exclusive for hs_color, or any other color setting. So when any Hue scene is set on this light that actually uses a real color setting this circadian sensor and setting is lost…
why would you only calculate the length of day when the sun is up? if the sun is down, the sensor has no value… For the other sensor, and the automation depending on it, it doesn’t make any difference if the length of day sensor is simply as follows doesn’t it? Since you’re calling the condition of the sun being up/above horizon there also?:
length_of_day_factor:
friendly_name: 'Length of day' # factor for circadian light calculation'
value_template: >
{% set daylength = ((as_timestamp(states.sun.sun.attributes.next_setting) -
as_timestamp(states.sun.sun.attributes.next_rising)) /
3600) + 24 %}
{{ ((daylength*-0.0063616)+0.11131)|round(5) }}
just don’t like empty sensors…
Correct, as this is true for any other value which can get overridden as soon as a new automation kicks in. That’s why my automation re-calculates the circadian light every time this automation gets triggered.
This is true. In reality, the “length of day factor” does calculate the length of the NEXT day because I did not find a way to calculate the day-length for the current day. Therefore, as soon as the sun sets (= it’s getting night), the states.sun.sun.attributes.next_setting
switches to a point in time which will happen the day after, so the result of the equation gets inverted (negative) and the sensor becomes useless. I would recommend using this sensor only in helper mode, without even being displayed in the GUI.
This is the sensor.farbtemp
you’re referring to, and be aware that my mechanism aims at a) displaying circadian light as long as the sun is above horizon, b) then switching to a predefined value during dusk/dawn
and c) goes to a predefined value as soon as it’s neither day, nor dusk, nor dawn.
You can find more information on my personal dusk/dawn calculation here, however it’s not perfect yet: Automations with dusk, dawn, night and day period
So in fact, it goes a little further than what you suggested above and that’s whay I would still need to build in a condition to check whether the sun is above horizon.
thank you! very useful and nice tool. learning both about Hue and mired here. Which is why I started with the Hue light system in the first place, so, again thanks!
for the icons you might be able to use this template I use in another sensor, ive adapted it quickly to your period_of_day:
icon_template: >-
{% if (as_timestamp(states.sun.sun.attributes.next_dusk)) - (as_timestamp(states.sun.sun.attributes.next_setting)) < 0 %}
mdi:weather-sunset-down
{% elif (as_timestamp(states.sun.sun.attributes.next_rising)) - (as_timestamp(states.sun.sun.attributes.next_dawn)) < 0 %}
mdi:weather-sunset-up
{% elif (states.sun.sun.attributes.elevation) < 0 %}
mdi:weather-night
{% else %}
mdi:weather-sunny
{% endif %}
Hi @mastermarkush,
Thank you for your excellent formula, it works spledidly at my home. Could you please provide your calculation sheet also? My wife finds the light too “cold” during noon, so I would like to reduce the peak from 175 mireds to something around 200…
As an idea for all adopters of circadian lights: I defined a Hue scene for each room called “Circadian Light”. I update this scene via REST service to the Hue API every 10 minutes so that it always includes the current color_temp from the sensor. My Hue dimmer switches all use the “Circadian” scenes, so the lights are immediately set to their correct color_temp as soon as I switch them on. In HA, I defined templates switches for the lights (turn_on action activates the “Circadian” scene") so I can facilitate the same logic from HA too.
In addition to that, I also established an automation that updates the color_temp of active lights every 10 minutes. This automation compares the color_temp the light has at the moment with the sensor value. If they do not differ too much (i. e. <15 mired, will probably be adjusted over the next months…), the light is updated. That way I avoid that if I manually activate another scene, it gets overwritten after 10 minutes by the circadian light.
HI @cicero222, thanks for your suggestions and ideas!
would you share your code please, so we could easily adopt and implement into our own settings?
Ive been testing the circadian sensor with several of my lights, and indeed enjoy the results, your bigger setting might be very useful.
thanks,
Marius
REST service to update the HUE scenes:
rest_command:
set_dynamic_hue_scene:
url: "http://192.168.1.33/api/<YOUR_API_CODE_HERE>/scenes/{{scene_id}}/lightstates/{{light_id}}"
method: "put"
content_type: "application/json"
payload: '{"on":true,"bri":{{states.sensor.circadian_brightness.state}},"ct":{{states.sensor.circadian_color_temp.state}}'
The service updates both color_temp and brightness for which I have another sensor defined. Unfortunately you have to update each single light within a scene and cannot update the whole scene with one call…
Reference: https://developers.meethue.com/documentation/scenes-api#43_modify_scene
This automation kicks in every 10 minutes and sets the color_temp to the up-to-date value:
automation:
- alias: "Update Hue Circadian Scenes"
trigger:
- platform: time
minutes: "/10"
seconds: 05
action:
- service: rest_command.set_dynamic_hue_scene
data_template:
scene_id: "mkaM4wCS0zTytUr"
light_id: 1
- service: rest_command.set_dynamic_hue_scene
data_template:
scene_id: "mkaM4wCS0zTytUr"
light_id: 2
This automation updates all active lights every 10 minutes with the current color_temp value:
automation:
- alias: "Update Circadian Lights"
trigger:
- platform: time
minutes: "/10"
seconds: 00
action:
- service: light.turn_on
data_template:
entity_id: >-
{% for lamp in states.light if lamp.state == 'on' -%}
{% if lamp.attributes.color_temp %}
{% set currentvalue = lamp.attributes.color_temp %}
{% elif lamp.attributes.xy_color %}
{% set currentvalue = (-449*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858))**3)+(3525*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858))**2)-(6823.3*((lamp.attributes.xy_color[0]-0.332)/(lamp.attributes.xy_color[1]-0.1858)))+(5520.33) %}
{% set currentvalue = (1 / currentvalue) * 1000000 %}
{% else %}
{% set currentvalue = 0 %}
{% endif %}
{% if (currentvalue - states.sensor.circadian_color_temp.state|float)|abs < 15 %}
{{lamp.entity_id}},
{% endif %}
{% endfor -%}
light.dummy
color_temp: "{{ states.sensor.circadian_color_temp.state }}"
transition: 3
As also other users have noticed, Hue lights may have either a color_temp attribute in HA or an xy color attribute, depending on the last action performed on them. So I have to check which one is defined. If it is xy, I have to convert it to Kelvin and then to mired. I found one formula here (although there seem to be also others): https://developers.meethue.com/comment/3046#comment-3046
Combining all lamps whose current values do not differ too much from the sensor value into one list is just beyond my programming skills, so I compose a list that always contains one dummy light. I would really appreciate if someone could show me a cleaner way to handle this (and also cater with the case that no light at all shall be updated)!
That’s easy. In this case, the just modify the value 175 to 200 in the sensor.colortemp
at the end of the formula (see above).
No, it’s not. That way the entire parabola would move up and would not deliver 350 mireds at the beginning/end of the day cycle but 375. I would need to change the u-factor in your formula. But anyway, for the moment it’s fine…
[Edit]: Just saw your PM, thanks a lot for the file!
You’re right. I forgot about the dependencies. You’ll see the calculation file and understand how to set it up correctly.
would you recognize this error:
2018-07-20 09:50:24 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.circadian_light fails
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 196, in async_update_ha_state
yield from self.async_device_update()
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 317, in async_device_update
yield from self.async_update()
File "/usr/local/lib/python3.6/asyncio/coroutines.py", line 212, in coro
res = func(*args, **kw)
File "/usr/local/lib/python3.6/site-packages/homeassistant/components/sensor/template.py", line 183, in async_update
self._state = self._template.async_render()
File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/template.py", line 132, in async_render
return self._compiled.render(kwargs).strip()
File "/usr/local/lib/python3.6/site-packages/jinja2/asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/local/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "<template>", line 3, in top-level template code
TypeError: can't multiply sequence by non-int of type 'float'
which change would you suggest to mitigate the error in these 2 sensors:
- platform: template
sensors:
length_of_day_factor:
friendly_name: 'Length of day' # factor for circadian light calculation'
value_template: >
{% set daylength = ((as_timestamp(states.sun.sun.attributes.next_setting) -
as_timestamp(states.sun.sun.attributes.next_rising)) /
3600) + 24 %}
{{ ((daylength*-0.0063616)+0.11131)|round(5) }}
circadian_light:
friendly_name: 'Circadian light'
unit_of_measurement: 'mired'
value_template: >
{% if is_state('sun.sun' , 'above_horizon') %}
{{ ((states.sensor.length_of_day_factor.state | round (5)) *
((states.sun.sun.attributes.azimuth)-180)**2 + 175) | int }}
{% elif (as_timestamp(states.sun.sun.attributes.next_dusk)) -
(as_timestamp(states.sun.sun.attributes.next_setting)) < 0 or
(as_timestamp(states.sun.sun.attributes.next_rising)) -
(as_timestamp(states.sun.sun.attributes.next_dawn)) < 0 %}
350
{% else %}
390
{% endif %}
not sure if the error is caused by the HA startup sequence not having set the value correctly yet, or the template is not correct?
Thx for having another check,
Marius