Sunset-Sunrise time period detection

I currently have a process that has a random event that turns on a lamp, but I want that lamp only to turn on between sunset & sunrise.

Ideally I would prefer a node that would pass an input to the output between sunrise & sunset, but have not found a single node that has that capability,
I have found the following nodes; cronplus & suncalc.

cronplus seems overly complicated for what I need. Two additional issues, even though I specified my time-zone, at the bottom of the node it displays a time that's not related to anything, and I don't know what the node input does (an inject node does not produce any output).

suncalc appears to function; as it can produce a 0 or 1 output every minute depending on sunrise/sunset, which I could use to set a global var, but I tried accessing it directly from a function-node with the following code:

var suncalc = global.get('suncalc');
var location = { latitude: 40.392, longitude: -74.1843 };
var times = suncalc.getTimes(new Date(), location.latitude, location.longitude);
var sunrise = times.sunrise.getTime();
var sunset = times.sunset.getTime();
var now = new Date().getTime();

The code returned this error:

function : (error)
"TypeError: Cannot read properties of undefined (reading 'getTimes')";

and node.error(suncalc) returned "" empty for var suncalc.

Any suggestions would be appreciated,

This example should work for you, the module is install using functionExternalModule

[{"id":"aa4c8a427a7ebd4f","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":800,"wires":[["b14f07a1326ae9bf"]]},{"id":"b14f07a1326ae9bf","type":"function","z":"d1395164b4eec73e","name":"function 144","func":"\n\nvar location = { latitude: 40.392, longitude: -74.1843 };\nvar times = suncalc.getTimes(new Date(), location.latitude, location.longitude);\nmsg = {\n    sunrise: times.sunrise.getTime(),\n    sunset: times.sunset.getTime(),\n    now: new Date().getTime()\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"suncalc","module":"suncalc"}],"x":390,"y":780,"wires":[["d995a939c332ca86"]]},{"id":"d995a939c332ca86","type":"debug","z":"d1395164b4eec73e","name":"debug 2452","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":550,"y":780,"wires":[]}]

Thanks E1cid,

I copied your code into a new flow, and it functions. This implies that suncalc is inherently global; is that true?


UPDATE: I just saw that you specified the module in the setup -got it.

You would need to add suncalc in the function setup tab of each function node you wish to use it in.

Got it; thanks looks like it will do the job.

BTW: The issues I referred to regarding cronplus; do you have any familiarity with that node?

  • what is the input for?
  • even with the correct time-zone specified, why does it display some unrelated time below the node?

Not familiar with the node. Start a new topic as there are many here that are familiar with it. Best to keep topics and answer separate, as future readers can then search topic with more ease.


You could make the function node do it for you.

Ok, thanks again :smiley:

I use suncalc and I have a simple flow that is triggered every 1 minute:

That outputs data to MQTT so that updates can be used in other flows.

The first node actually outputs a bunch of stuff:


I used to use: node-red-contrib-today-time-range-switch

A simple Node-RED node that routes messages depending on the time. If the current time falls within the range specified in the node configuration, the message is routed to output 1. Otherwise the message is routed to output 2.

Thanks for the good suggestions guys; but E1cid's Function-Node import of suncalc works the best for my application.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.