RM Example: Circadian Color Temperature

see this post for the newest rules:

original post

I created a rule to slowly adjust the color temp of my lights from 6500K down to 2200-2700K (depending on the light) throughout the day. I'm not trying to recreate a circadian pattern so much as I am trying to actively hack it by suppressing melatonin the morning and then having nice warm light in the evening to encourage melatonin production. The rule sets the color temp to 6500K right before my 5am alarm and then starts a downward march at sunrise and lands on nice warm lighting by sunset. for my sengled color bulbs I take them all the way down to 2200 over the hour after sunset.

In addition to all that, there are also two global variables %colorTemp% and %colorTemp2700% that I then call from the specific lighting rules for each individual lamp (this has greatly simplified my lighting rules as I was previously changing the color temperature of lights based on modes).

my feature request is for @bravenel and is as follows:
It would be nice to able to call the system sunrise and sunset variables without having to recreate them as I do here in order to do math based on those times. The problem is that if my hub gets flaky at sunset the night before, my rule flies off the rails the next day. Between hub updates or hubconnect or some network issue, if I miss that 1 minute window at sunrise or sunset my lights get all weird and I have to use an online unix timestamp conversion tool to manually repair things. If I could use the system variables, then I think it would make things much more reliable.

Just and idea here: instead of doing everything in one rule, break it up.

Make one that tiggers at sunrise and sets a global variable “sunrise”
Make another one that triggers at sunset that sets a global variable “sunset”
Change the rule above to trigger when the global variables sunrise or sunset changed

This way you can discount the “flaky” situations as you don’t need that IF at the beginning

hmm, I don’t think that will fix my problem. The rule itself is quite stable - i’ve been using it for about 3 months now. The problem occurs when the entire hub gets bogged down such as during a hub update or if the network is down or if it just isn’t working well. After that all the math breaks down.

the rule really requires the reliability of hubitat (and the fact that this rule works as well as it does speaks to that reliability) as it is continuously calculating these values based on the ones that came before. in the past 3 months I’ve only had to manually correct it a handful of times. having access to system variables would mitigate that even more.

This is really the province of a small custom app, not Rule Machine. Time is messy. But even so, I don't follow how having access to those variables would help. You still would have the problem of knowing that those values need to be updated. If you have GVs for sunrise and sunset (in epoch time seconds), what more do you really need?

I would certainly agree with @dan.t that those should be separate little triggers, one for each, that just set those GVs. Then you'd always have them available.

Are you using Change Color Temperature Over Time? What update interval do you need? With a longer update interval, one that spans a hub update, you could set that once each morning and it would just keep on going. Even with a shorter interval it would keep on going. Perhaps you could have a special "fix-up" rule that makes it run from now until sunset in the event the hub went down, to get it back on track -- that you could manually fire when needed. I don't see why you need to trigger this every 10 minutes. Let Change Color Temperature do that work for you.

So, if you have those rules that grab sunrise and sunset times, this would do it:

Trigger Event:  Sunrise
   Set timespan to (sunset - sunrise)
   Set timespan to timespan + 3600
   Change CT Over Time: target 2200, time %timespan% seconds, interval 10 seconds

Use a separate rule for whatever you want at 4:52, could be Simple Lighting.


I guess I figured that the system had a way of setting sunrise and sunset that was not predicated on it being active at exactly the time corresponding to sunrise and sunset. Therefore the math of the rule would be updated as long as the system had a connection to the internet and the correct time and location. as it is now, it has to be working at exactly sunrise and sunset everyday to capture those times into a variable.

I am not using Change Color Temp Over Time as that was not an option when I wrote this rule. I’ve been thinking about that and how to possibly integrate it since you posted the update. My use case would involve having it change over the course of the entire day, which seems somewhat fragile. If the hub is rebooted or interrupted somehow it would kill this automation. I suppose that is why you mentioned a “fix-up” rule.

The reason it updates every 10 minutes is b/c that seemed like a small enough step to march down the color temp in an unnoticed way. The math of my rule divides the color temp range into an even number of steps to step down every 10 minutes. Then my lighting rules that take advantage of this variable re-evaluate when the variable changes. That way my great room lights (which are often on for much of the day) will slowly change with time.

I would worry about using Change CT Over Time causing my rules to fire continuously this setup, so I’ll have to rethink my triggers.

Doesn't need a connection to the internet for this. Sunrise and sunset are from built-in astronomical clock.

I have rules that run every day at sunrise and sunset, and have for years. They have never missed a day.

You choose the interval. It fires on that interval. It doesn't fire "continuously". Even if you fire it every 10 seconds it's not much load on the hub. You're firing every 600 seconds, a miniscule load.

this has been some interesting food for thought. as always, thanks for your input. My original rule was doing a lot of math that is now built in with CT Over Time. I’ve rewritten my rule as follows:

ignore my variable values - those are just placeholders as I’m writing this before dawn.

I think this rule will handle self correction if it has to be rerun at a time other than sunrise. It just subtracts the the number of seconds of daylight that have passed from the timespan it is going to run over.

also, Change CT Over Time requires minutes, so I had to divide everything by 60. It also asks for the interval in seconds and gives a “1...60” example. It accepted 300, so I assume that is ok?

I put a conditional in there just keep me from borking all the numbers by running it at the wrong time, but that shouldn’t really be necessary.

I also created two other rules - one to set sunrise/sunset global variables and one to set the color temp to 6500 at 4:52 AM (i had to use RM for this as simple lighting doesn’t seem to allow for setting color temperature).

I’ll test this for a while before I change my lighting rules to use it.

final plea: my sunset value is really the night before, so I have to subtract the difference from 24 hours in order to get daylight hours. It would be nice to be able to access the upcoming sunset value and not just the one from the night before. It would be more accurate and I would not have to make sure to not do a hub update around sunset (which seems to be a common time for me to mess with hubitat).

I don't know if this will help, but I created a similar circadian rule in a much messier fashion that goes up and down, in contrast to your unidirectional rule. It has 3 opportunities to correct itself and get back on the rails, with a little buffer on either end. It's not exact and it's not a fine gradient, but it works. For your situation maybe you can set a few checkpoints along the way.

My original rule worked similarly and had programmed check points at 4:52 am, sunset and sunset + 60 min to set the colortemp to a constant. Different than yours my original rule took sunrise and sunset into account for the transitions. I now just set a constant at 4:52, the rest of it is calculated.

the new CT Over Time option has simplified things and honestly this new rule I posted above seems to working pretty well as long as I leave it alone. If things get off for some external reason hitting update rule and run actions will re-initiate it at the correct point in the transition.

I see two weak points - one is stacking pending events. I just hit run action several times while testing the rule and I had a bunch of pending events, which really shouldn’t have too much of an impact on the actual CT values, it should just cause it to be calculated more often that every 5 min. as long as I leave it alone, it seems to run fine.

the other is the aforementioned requirement of catching the sunrise and sunset times. the rule has to be running for at least one sunset and then one subsequent sunrise to have the correct numbers, otherwise those variables have to be manually adjusted to the correct epoch times. It works, but I’d love to just have access to what hubitat already knows without having to recapture it. then the rule would be essentially bulletproof.

1 Like

sort of as a proof of concept I rewrote the rule for those that like the CT to rise from warm light in the morning to cool light by noon. its not perfect as it is expecting noon to be exactly halfway between sunrise and sunset, which it obviously isn’t. it raises the color temp until noon, then after noon it starts lowering it. at noon it may be off the target by a few hundred CT.

if this were to run on its own it would take the lights from ~6500 at noon, down to 2200 or 2700 (both variables are included) at sunset, then starting at sunrise the next day it would start raising them to a goal of 6500 by noon again.

I haven’t fully tested this, but it makes sense in my head! :stuck_out_tongue_winking_eye:

The advantage to this over a dedicated app is just that it is lightweight and runs on the built in tools available, so it should hopefully be both reliable and low impact.

edit: If you wanted you could try to capture noon from the day before into a global variable and then just add 86400 to it (24 hours) to get an approximation of noon the following day. then do the math based on that.

edit2: here you go. two rules:
capture the times into global variables:

then calculate:

edit3: you have to add a second trigger to the calculation rule at 1200 in order for it to restart the fade.

@bravenel is the man!

with the new time variables and with the "change color temp over time" RM action, setting color temperature has never been easier. here are my new example rules:

Global variables:
noon_variable -- time variable
sunset_variable -- time variable
colorTemp -- number variable -- also has a color bulb connector

Rule #1
this rule sets these variables every day 1 minute after midnight (I also have a sunrise_variable, although it is not required for these rules):

Rule #2
this rule changes the color temperature of the variable %colorTemp% up to 5000K by noon, and then back down to 2200K by sunset.

it requires two local variables:
start_time -- time variable
timespan -- number variable

The nice thing about this rule is that it will calculate the time between the time the rule is run and either noon or sunset, and adjust the rate of color temperature change accordingly. That way if the you have to change the rule or the hub is reset you can just hit "run actions" to restart the countdown.

Then all you have to do is use the variable %colorTemp% in your automations and it change the color temperature according to your circadian rhythm.

I'll present an example of my great room lighting automation. It is fairly complex b/c the lights are often on in this room when we are home. With these rules they adjust so slowly that it isn't noticeable even if we are sitting in the room reading a book. it requires 3 rules:
on/off and set color temp:

adjust color temp even if the lights are on:

adjust level to start dimming at sunset:

Of course it could be much simpler, especially in a high traffic area where the light turns on and off often. In that case a single rule that just adjusts color temperature to the variable will likely suffice.

1 Like

Nice work. Just a thought....rather than have a set of rules like your last 3 here here above for each room, would it be more easy to set up a single rule that checks all groups (for me mostly rooms) and if each set/group is on, change their brightness/temperature to the appropriate circadian values? Then run that on a repeat to fire every 10 mins. I'm gonna try that I think. And of course set an override switch to allow other manual settings of lights to take precedence when desired (for specific scenes to be set etc).

Definitely. Here is an example of another rule that controls the CT of multiple lights.

I’d just have the trigger be the variable or CT change though, as that is already going to be running at whatever predefined interval you’ve setup. I’ve found that sometimes I have to manually adjust or change the CT, and if changing the variable is the trigger, then it will immediately change the lights as opposed to having to wait 10 min.

Yes! Schweeeeet!

I've just completed an interesting wake up routine for our Master Bedroom (so not a general routine, but a specific one). It allows wake up time to be set from a dashboard for weekdays and weekends independently, along with a snooze time and number of snoozes. Then 30 minutes before the wake up it starts to bring the lights up (temp and level) until quite bright and daylight temp. Then an announcement from the Google Nest hub is made at the wake up time. If snooze is on then after that time a selection of sarcastic messages are broadcast :rofl: pandering to my slightly obtuse British sense of humour. When we both get out of bed, the whole thing is cancelled (we have Withings sleep pads), lights go off after a while (allowing time to open the curtains) and the AC turns off. It's really cool. I'm very pleased with it. One day I will automate the curtains too ha ha ha. Will probably post it sometime soon to give others inspiration :smile:

What are you using to allow a wake up time to be set via dashboard?

I'm using "connectors". They allow you to enter values on a dashboard linked to global variables. Extremely cool. Here's the section of my dashboard for the wake-up/Alarm settings...

You have to fiddle around with the variables a bit so I have some simple rules to manipulate them into the required seconds, time etc (egm to start the circadian routine 30 mins prior to when wake-up is desired). It's been fun to set up. Not quite bullet proof yet but when I'm done with it I will post it all.

1 Like

Ha ha I just noticed my Snooze Time is set to 1 minute, that's because I'm testing it. Should be set to say 10 mins once I'm finished with it.

I really like this idea. I want to be able to set these variables via alexa however, which I don't think will be straightforward at all.

I can't figure out why the "current time" doesn't change from 12pm. Is there something wrong with rule machine?

your %start_time% variable should be set to noon, midnight, and sunrise +1 minute, depending on when the rule is triggered.

or any time you manually trigger the rule.