From time to time, I get a crazy idea of changing something small in my automation setup. Usually, an idea like that drags me into a rabbit hole, I didn’t know it had existed. Whatever I do nowadays, I always look at it with an angle: “Would that make an interesting tutorial?” and that angle has turned a simple “Is it nighttime yet?” query, into a 200 line long coding challenge. I hope someone will appreciate the fact I made a tool to check which part of the world needs a flashlight.
The “bigtimer” node is great… until it isn’t
I have been using the “bigtimer” node for a long time. As my NodeRED flows grow, adding the same nodes each time around becomes a burden and a complication that you have to deal with. Having a global set of values that I can use is the best coding practice, then reconfiguring a “bigtimer” node each time you want to deal with a timer or reconfigure a group of the devices that are not connected to the same node.
I wanted to have a global variable, which would store information about the time of the day: day/night. On the surface, it’s a simple idea. When you actually approach the problem (and the fact that you would like to share the idea with other people in different parts of the world) things get a little bit harder.
If you are here to rip the fruit of my work, scroll down to the bottom and download the flow. You can also buy me a coffee while you at it.
Creating a time keeping alternative
To calculate the day|night I decided to convert the current time to seconds from 1970 (EPOCH time) and compare the numeric values against the sunset and sunrise values. To be able to do so, I need sunset and sunrise values. I can obtain this using a free sunrise-sunset.org/api. As the API delivers data in the UTC timezone, some calculations are needed to present it correctly to people around the world. But I’m getting ahead of myself. There is more to sunset/sunrise than you think.
Exploring the rabbit hole
I spare you the boring historical details. In nutshell, humans recognise three sunset/sunrise levels with different light intensity based on how deep below the horizon the sun currently is. With my NodeRED from you will be able to get all that information adjusted for your current geographical location. The flow will:
- tell you if it’s night or day
- tell you the sunrise and sunset time
- tell you the day length
- provide you with astronomical, nautical, civil dusk and dawn times
- use these values to create timers
- all that good stuff in your local time!
Getting sun data based on coordinates.
You can get the longitude and latitude from Google Maps. Point it at your location and read the URL, these values are encoded into it:
https://firstname.lastname@example.org,-1.123456,14z Latitude is in red, Longitude in green
If you wonder what’s the 14z stands for, it’s the current zoom level. Save these as you will need them in my NodeRED flow settings.
Geographical coordinates are used to determine the sunset/sunrise times. Instead of hardcoding the data, I added the timezone option so you can decide if you want UTC values or recalculated values to your local timezone. The coordinates will be also saved globally should you ever need these again in another project of yours (weather info perhaps?).
Raise and shine!
To get the JSON data from the API (you can learn more about JSON here) we have to make a REST request. I covered these in my NodeRED for beginners: Connectivity – in case you need a more robust guide.
The flow will get the coordinates from global variables (make sure they are set to survive reboots – see how to enable that) and will ask API to provide us with all information about the daylight in this location. As the information is valid for 24h, the request has to be made once a day.
There is plenty of data to store, and all of that will be used in other projects. It makes sense to save these as global values once again. To keep the variables organised I will structure them as JSON and format the time to ISO standard. This way it will be easy to convert it into an object-alike format:
var date = new Date("TimeInISOFormat");
and as such accessed again as a date object. In my settings flow, a timezone bool value defines how I’m going to save these. By default, they are saved with a timezone offset enabled.
Too many timezones to worry about
In my original article, I was using another API service to convert the coordinates into a specific timezone. Unless you want to change this value to reflect a remote location, the local time offset can be easily obtained by
If you want to change the default behaviour, just replace that value with your negative time zone offset in minutes. Why negative?
.getTimezoneOffset() gives you a difference between UTC and your local time (with daylight saving). This value isn’t the same as the time zone value that we are so used to. At the time of the writing, UK is running at GMT+1 – it means that we are 60 min ahead of UTC time.
.getTimezoneOffset() will report
-60 which tells you that your time needs to be adjusted by
-60 minutes to equal UTC.
To recalculate the time, I either have to convert the value to the opposite one (0-timezone_offset) or simply subtract the offset.
Is it a night time yet?
Wait, we have sunsets, sunrises even the length of the day. Where are the timers? The main objective of this project was to get some sort of information about the night and day to drive my automation.
Since we have the info about the daylight features we can create a very effective timer that always tells us if the time outside is considered day/night/twilight etc. As these values change every day it’s very useful for driving automation that relies on the day/night cycle.
To achieve this all we have to do is ask NodeRED to check if it’s nighttime yet! (Shreck reference anyone?). If we repeat the question every minute, you have a pretty reliable clock that tracks the daylight features.
The "bigtimer" will have its uses, and my method is not a replacement for that useful node. If you want to check the value of the time against the existing condition inside the function node, now you have the toolset to do so.
It's not always about the time, but almost always about the journey. I hope you have picked up a thing or two that will make your flows better. I decided to rewrite this article to improve the flow and get rid of one annoying bug. Easily done for in the article, but I think this topic deserves a better video. What am I going to do with this project? I will add a small switch to enable daylight tracking in my various window curtains and blinds controllers, starting with the latest Zigbee Roller Driver from Aqara. Join the discussion on Reddit about this post!
Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.