Circadian light with Philips Hue, independent from world clocks ;-)

Hi Marius, I just came across your project and want to implement it in our dining and living room. Could you send me the Calc sheet so I can tweek the settings a bit?

Best,
Reinhard

I would also love a copy of your Excel work. I’m working on a native Node-RED pallet that duplicates this functionality and picking up from your work would be so incredibly helpful!

1 Like

@mastermarkush Would love to get a look into the file as well!

@mastermarkush, I would love to see your Excel file, as well. Could you maybe create a gist with the file and share the link?

You can download the mired calculation file in my github repository: https://github.com/mastermarkush/homeassistant

1 Like

Hi, thank you for sharing this!
I integrated your sensors in my config and will check the graphs in the following days to see if the constants need some adjusting.
Anyway, trying to avoid the errors on startup, I also modified the colortemp template as per recommendations and so far no errors popped up:

    colortemp:
      friendly_name: 'Circadian light - color temperature'
      unit_of_measurement: 'mired'
      value_template: >
          {% if is_state('sun.sun' , 'above_horizon') %}
            {{ ((states('sensor.length_of_day_factor') | round (5)) * ((state_attr('sun.sun','azimuth') )-180)**2 + 175) | int }}
          {% elif ((as_timestamp(state_attr('sun.sun','next_dusk'))) - (as_timestamp(state_attr('sun.sun','next_setting'))) < 0) or ((as_timestamp(state_attr('sun.sun','next_rising'))) - (as_timestamp(state_attr('sun.sun','next_dawn'))) < 0) %}
            390
          {% else %}
            500
          {% endif %}

Best,
R

Is it possible to have multiple zones of lights set this or do they called by the single instance? I have the switch loaded in my office, but was thinking it would be nice for this to work in my kitchen or bedroom as well.

Hi @atmasphere! I think I didn’t get your question right. What I understood is that you want to have multiple (independent) lights apply the mechanics of adaptive “circadian” light. If so, then simply apply the colortemp variable to the color_temp in the data_template for the specific light or group of lights that you turn on… Maybe you can reformulate your question?

think you understand but to be clear, I’d like to have a switch for multiple rooms.

Office lights are currently utlizing this (though it broke for some reason). I was thinking I’d like to turn it on for my kitchen and bedroom as well but want the ability to turn the toggle on and off by room.

broken switch in place but this is my office view -

Screenshot_10

Dear @mastermarkush,

could I use this to automate my window roller shutters with this component? If yes, would you give a short hint, how?

What I’d like have is a little fixed time delay, so not to close the shutters instantly as dawn kicks in, but like 30 mins later or so…

many thanks in advance

Hi John,
for this use case I’d suggest you to have a look at my other project which relates more to automations around day periods.

Cheers,
Markus

Hi @mastermarkush
Would it be possible for you to send me your mired calculation file? I looked at your github site, but looks like it’s no longer there.
Really cool work.
Thank you.
Mark

hm, thx Markus, looks interesting, I’ll dig into it :slight_smile:

Hi Mark, I re-uploaded the mired calculation file.
-Markus

Fantastic, thx Markus for all your efforts!!
Best Mark

that’s the least I can do, given the tremendous support that I get from this community…

1 Like

Are these magic numbers geographic location depending perhaps?
I’ve tried it now (for a Hungarian location), and it goes to -339 mired soon after sunset for a few minutes:
screenshot-8123-2021.02.09-20_15_03

It is because with this formula, length_of_day_factor becomes -0.1056 after being 0.0471 for most of the day.
Or perhaps sun.above_horizon isn’t in sync with sun.next_setting?

Me too, same location. :slight_smile:
I’m trying to use another method to achieve the same result.
I like very much the idea, thank you for that @mastermarkush!
Here is my solution:

- platform: template
  sensors:
    max_elevation:
      friendly_name: 'Maximum solar elevation angle'
      unit_of_measurement: '°'
      value_template: >
        {% set deg = pi / 180.0 %}
        {% set N = now().strftime("%j") | int %}
        {% set L = state_attr('zone.home','latitude') | float %}
        {% set D = (-1 * asin(0.39779 * cos(0.98565 * deg * (N + 10) + 1.914 * deg * sin(0.98565 * deg * (N - 2))))) / deg %}
        {{ (asin(sin(L * deg) * sin(D * deg) + cos(L * deg) * cos(D * deg)) / deg) | round(2) }}
    colortemp:
      friendly_name: 'Circadian light'
      unit_of_measurement: 'mired'
      value_template: >
        {% set mired_min = 200 %}
        {% set mired_max = 350 %}
        {% set elev_at_mired_max = -6 %}
        {% set mired_night = 390 %}
        {% if state_attr('sun.sun', 'elevation') > elev_at_mired_max %}
          {{ (mired_max - ((state_attr('sun.sun', 'elevation') | float) - elev_at_mired_max) * (mired_max - mired_min) / ((states('sensor.max_elevation') | float) - elev_at_mired_max) ) | int }}
        {% else %}
          {{ mired_night }}
        {% endif %}

This is under testing yet. You can easily change the limits of the light warmth with mired_min, mired_max and mired_night.
I stretched the diagram to civil twilight with elev_at_mired_max = - 6, but you can change it to 0 to set it to sunset/sunrise.

2 Likes

I’d love to understand what that max_elevation is doing but I think it’s beyond my maths skills. Summarising, it uses the current time and the installation’s latitude to produce our max angle (somehow). And then the new circadian value, rather than using Markus’s day length factor, does some magic with this angle and the sun’s current elevation?

I hadn’t even begun to get my head around what Markus was doing, I’m terrible at trigonometry so now I’m officially lost. That’s OK, it’s not unusual.

So, I don’t need to understand the how - as per usual, smarter people have my back. But, am I safe to assume that since we are now referencing the home latitude, that it’s globally mobile and will function wherever HA knows its GPS coords?

And finally, there was talk of the sun’s elevation value being questionable. How much would this come into play with the new approach?
Markus, thanks so much, what a fascinating rabbit hole you pushed me into. :smiley:

Thanks, John

Yes exactly!
The max_elevation calculation uses some Fourier series thing. It only needs the day of the year (N) and the latitude (L). The first thing determines the Sun’s angle to the Earth’s axis (depends of N) and it needs to be modified because of the local position’s latitude.
It was the hard part. :slight_smile:

Yeah, but that “magic” is just a linear transformation to stretch the Sun’s elevation angle to the predefined values of mired_min and mired_max. It’s really a very simple approximation, but I think it’s pretty close to the real values and it’s enough for me.

I think, yes. But I tested it only here in Hungary, so I can’t be sure. :slight_smile:
The second part doesn’t depend on your location and the first part you can easily check, because sun.sun shows the elevation too and at noon you can take a look to compare the values. It’s not exactly the same but I think it’s because of the Fourier series and the difference is really small.

To tell the truth I have no idea. :smiley:
I compared my method’s results to @mastermarkush’s project and it was so close that I can’t see the difference in the mireds with my eyes. This is a simple idea but maybe it works. I don’t know for sure because I may be the only one who tried this little template sensor of mine. :sweat_smile:

1 Like