I had been using a basic timer to turn on the lights in my house in the evening using my Raspberry Pi and the x10 firecracker python script I wrote about earlier. It’s easy enough to make a cron job (sudo crontab -e), for example:

00 20 * * * /home/pi/x10/firecracker.py A 2 ON

turns on Unit 2 of House A at 8:00 pm every night.

This worked for a while, until the summer started coming on and the daylight got much longer. I was constantly adjusting the timing to wait later to turn on the lights. What we need is a way to determine the sunset time on a given day, and turn on the lights at or around the official sunset time.

A little program called sunwait can be installed from here. You have to unzip the source download and run “make”. Sunwait does just what it sounds like: it waits until sunset before exiting. Now we can do something in the crontab like this:

00 17 * * * sunwait sun down 40.424948N, 86.914387W; /home/pi/x10/firecracker.py A 2 ON

Now at 5:00 pm every day, the sunwait program will run. It will sit there until sun down at the given coordinates before continuing on to the next command which turns on the lights!

Of course, then I got annoyed that it worked fine on clear sunny days, but when it was cloudy, I wanted the lights earlier. Maybe I’m too picky. I guess I could install a light sensor of some kind, but who wants to mess with more hardware when we’re already connected to the internet? We need to check the weather conditions and use that to decide when to turn on the lights.

#!/bin/bash

# Coordinates (Purdue University)
lat="40.424948N"
lon="86.914387W"

echo "Waiting to check weather 45 minutes before sunset" > /home/pi/x10/status.txt
sunwait sun down -0:45:00 $lat $lon

# REPLACE THE "KLAF" BELOW WITH THE AIRPORT CODE NEAREST YOU
curl -s http://tgftp.nws.noaa.gov/data/observations/metar/decoded/KLAF.TXT > /home/pi/x10/current.txt
sky=`awk -F': ' '/Sky conditions/ {print $2}' /home/pi/x10/current.txt`
if [ "$sky" == "overcast" ]; then
   delay=-20
elif [ "$sky" == "mostly cloudy" ]; then
   delay=-15
elif [ "$sky" == "partly cloudy" ]; then
   delay=-5
else
   delay=0
fi
echo "Waiting for sunset -$delay" > /home/pi/x10/status.txt

# Email the status to yourself. REPLACE EMAIL ADDRESS
echo "Conditions $sky. Lights scheduled at sunset $delay minutes" | mail -s "Pi Lights" YOUR@EMAIL_HERE.COM

# Do the actual waiting!
sunwait sun down $delay $lat $lon
/home/pi/x10/firecracker.py A 2 ON pi
echo "Lights ON at sunset $delay" > /home/pi/x10/status.txt

Now, save this script as “lights.sh” and give it executable permissions. The crontab can simply run lights.sh, which will wait until the corrected time to turn on the lights.

00 17 * * * /home/pi/x10/lights.sh

The script will wait until 45 minutes before the sunset time, then download the current weather conditions from NOAA recorded at your nearest airport, in this case KLAF. It pulls out the “Sky Conditions” which is a text string something like “clear” or “overcast”. Based on this value, it will add a negative delay time to the sunset, turning on the lights earlier if the sky is cloudy. I also have it sending me an email to notify me of the delay, so that I know it’s still working. The actual delay times for each case may still need a bit of tweaking; it hasn’t been cloudy much around here lately. For debugging, it also prints the current status of the script to the “status.txt” file.

Of course, don’t forget to turn the lights back off!

30 23 * * * /home/pi/x10/firecracker.py A 2 OFF

With this in the crontab, they’ll always turn off at 11:30 pm.

[EDIT 1/8/2016] Updated the URL for retrieving weather conditions.