Turning My Lights On At Sunset

Last week I bought & wrote about some wi-fi controlled lights. The Osram iOS app allows you to schedule a time when the lights will turn on & off. I don’t really want to mess around changing the time the lights will come on as the time of sunset changes throughout the year. I want the lights to come on at sunset, then go off at 11pm – currently something the iOS app does not support.

This weekend I started playing with some code to build this functionality. I plan on adding it to my Raspberry Pi based home automation system.

The solution I came up with is split into two main parts – the first one being to figure out what time the sun will set (on a day to day basis) then the second part is to turn the lights on at that time.

Figuring out what time the sun will set

I found a rather neat NPM module called SunCalc which can be used to calculate everything from sunset times & lunar phases, right through to planetary positions. It may be a little overkill for what I need, but it works. Another good feature is the ability to calculate based on coordinates so I can get the exact sunset time for my house.

// include module
const SunCalc = require('suncalc')
// get the sunset time based on coordinates (of Tower Bridge)
let times = SunCalc.getTimes(new Date(), 51.5055, 0.0754)
// extract the time (hours and minutes) 
let sunSet = `${times.sunset.getHours()}:${times.sunset.getMinutes()}`

The above code is pretty self-explanatory and will give me the sunet time.

Turn the lights on at sunset – cron

Now that I can figure out the time of sunset, I want to do it every day using a cron job. The initial cron will run at a set time every day. It will get the sunset time, then initiate another cron using that time to turn the lights on.

I chose a NPM module called node-cron which make creating cron jobs really easy.

// include modules
const SunCalc = require('suncalc')
const cron = require('node-cron')
// run at 12:15 every day
cron.schedule('15 12 * * *', () => {
      // get the sunset time
      let times = SunCalc.getTimes(new Date(), 51.5055, 0.0754)
      // format the minutes & hours for the cron job
      let sunSet = `${times.sunset.getMinutes()} ${times.sunset.getHours()}`
      // create a new cron job to run at the sunset time
      let sunsetLightsON = cron.schedule(`${sunSet} * * *`, () => {
        // turn the lights on here
        // only needs to run once a day so destroy after it has run once
      // start the cron job to turn the lights on

The code above is the basic structure which makes use of 2 cron jobs. One runs every day which creates another one which will turn the lights on then destroy itself ready for another to be created the next day. This process will just repeat over & over turning the lights on at sunset without me having to change a time manually.