node-red-contrib-sunevents 3.1.1
A node for node-red that generates events based on the position of the Sun at the appropriate time of day
node-red-contrib-sunevents
A node that emits events based on the location of the Sun at the appropriate time of day. This node can be used to make something happen at particular period of the day, for example switching on your lights at home at dusk every day or taking a photo a the darkest time of night ("nadir").
On receiving a msg.payload
containing latitude and longitude coordinates (in decimal), this node waits and then outputs a series of Sun event objects at the appropriate time for each. A secondary "missed events" output provides an array of the Sun events that have passed before this node was triggered with an input (See Missed Events for more details).
Calculations are performed using the excellent SunCalc module and the resulting Sun events are output from this node at the appropriate time:
- sunrise: sunrise (top edge of the sun appears on the horizon)
- sunriseEnd: sunrise ends (bottom edge of the sun touches the horizon)
- goldenHourEnd: morning golden hour (soft light, best time for photography) ends
- solarNoon: solar noon (sun is in the highest position)
- goldenHour: evening golden hour starts
- sunsetStart: sunset starts (bottom edge of the sun touches the horizon)
- sunset: sunset (sun disappears below the horizon, evening civil twilight starts)
- dusk: dusk (evening nautical twilight starts)
- nauticalDusk: nautical dusk (evening astronomical twilight starts)
- night: night starts (dark enough for astronomical observations)
- nightEnd: night ends (morning astronomical twilight starts)
- nauticalDawn: nautical dawn (morning nautical twilight starts)
- dawn: dawn (morning nautical twilight ends, morning civil twilight starts)
- nadir: nadir (darkest moment of the night, sun is in the lowest position)
How To Say Thanks
If you find this node useful and you want to say thanks, feel free to buy me a coffee using the link below.
What's New - Missed Events
Whenever you invoke this node by passing an input there will be a series of Sun events that will have occurred already. These are known as "missed events". An array missed events is provided on the 2nd output immediately following receipt of an input. Missed events maybe useful if you are initialising system state at start up (e.g. lights off or on), before you receive the first emitted Sun event on output 1.
Upgrading from v2.x
Version v3.0 and later of this node works a little differently to previous versions and will require a change to your flow if you are upgrading from an earlier version.
Passing latitude and longitude into the node in the mss.payload/ is now the preferred option, but the latitude and longitude you previously defined in the node's configuration can still be used to calculate Sun events if no latitude and longitude coordinates are passed in the msg.payload. However, you must still inject a payload at regular intervals to recalculate the next 24 hour's events, but this payload can be any value.
Since this node now accepts an input payload, it's important that this node not overwrite or lose any values you have already set in the msg.payload. So for consistency the Sun event name is now output as msg.payload.sunevent (more information is also output in msg.sunevent, see Output section).
Usage
Each time this node receives a new msg.payload
to it's input, it calculates up to 2 days worth of Sun events (depending on what time of day it is invoked). To have the node output events reliably every day, you should inject a latitude and longitude payload into the node at least once every 24 hours. The easiest way to do this is with the node-red Inject node.
Input
This node requires a latitude and longitude in decimal form to be passed to it in the msg.payload
, either :
msg.payload.latitude = <latitude in decimal format>
msg.payload.longitude = <longitude in decimal format>
or
msg.payload.lat = <latitude in decimal format>
msg.payload.lng = <longitude in decimal format>
Calculations are performed using the Latitude and Longitude that are passed in via the payload. If you have a frequently changing GPS position it will update the Sun event calculations every time it receives a new latitude and longitude in the payload.
Outputs
Output 1 - Upcoming Sun Events
This node waits for the appropriate time and then outputs the appropriate sun event.
The Sun event name is output in msg.payload.sunevent
, preserving any other payload values set earlier in the flow. It also outputs the event name and date & time of the event in msg.sunevent
object if you need a more complete set of Sun event data. The msg.topic
can also be set in the node's configuration.
Output 2 - Missed Sun Events
An array of Sun events that have occured before this node was invoked. The array is ordered so that the most recent missed event is at the start of the array (position 0). Which missed event is the most recent is entirely dependant on the time at which the node is invoked. Each array element is an object containing the event name (event_name) and the date & time (datetime) at which the event occurred.
Config
Name: Override the default name of this node in the flow
Topic: Set the topic used in the flow from this point onwards
Options:
- Verbose: When enabled this setting outputs additional logging messages to the debug console
- Make Hours seem like minutes (test mode): Reduces the time you have to wait for an event to fire, 1 hour becomes 1 minute. Obviously the Sun events won't fire at their correct times but if you are testing your flow it means you won't have to wait for hours to see that things are working.
Example Flows
Unlike previous versions of this node, this node DOES NOT perform it's own daily scheduling. In keeping with the general guidance for node-red nodes you must now use some other node to invoke the sun-events node at a time and frequency appropriate for your use case. The Inject node supplied with node-red is a good candidate for this and is demonstrated in the supplied example flow. Please note, I show the use of 2 inject nodes, one to invoke the flow on deployment and the other to invoke the flow at a fixed time each day.
There are two example flows provided, one for a fixed GPS positioned injected daily and one for a stream of GPS coordinates that continually updates with your position.
Example 1: Fixed GPS position Download
Example 2: Stream of GPS positions Download
Background
I used the original version of this node in my own set up to turn on house lights at dusk. The whole system ran on a Raspberry Pi we have hanging on the wall. The lights were controlled by a RFXCom RFXTRX433 USB device. Sitting between the Sunevents node and the RFX node is an MQTT persistent topic to hold system state, so if the Raspberry Pi is rebooted at any point during the day the system knows exactly what state it was in before the reboot. This set up ran with very little manual intervention for over 7 years in two different homes. At Christmas time it gets extended to switch on our outdoor Christmas lights too. I have recently switched to Sonoff wifi switches and Alexa is now doing the scheduling, so I have to confess this node is kind of redundant for me. I am maintaining it in case it is helpful to others!
Change History
Version | Date | Description |
---|---|---|
3.1.0 | 2023-01-14 | Added new output for missed events and updated dependencies |
3.0.3 | 2021-03-19 | Fixed issue with msg.payload |
3.0.2 | 2021-03-14 | Fixed issue when preserving existing msg.payload value |
3.0.1 | 2021-03-14 | Updates to examples and documentation |
3.0.0 | 2021-02-14 | Major redesign to improve flexibility and the reliability of output. Drastically improved unit testing |
2.0.3 | 2020-03-03 | Updated Readme and docs |
2.0.2 | 2020-02-28 | More debugging and closer attention to anywhere where timezones could cause an issue |
2.0.1 | 2020-02-27 | Improved unit testing, example flow |
2.0.0 | 2020-02-24 | Updated to run on node-red 1.0.3 and node.js 12.11 |
0.5 | 2015-03-02 | Original released version |
License
Licensed under the Apache License, Version 2.0 (the "License"); http://www.apache.org/licenses/LICENSE-2.0