Daylight controlled devices with PyEphem

I needed a camera to be turned off at night and a PIR sensor (controlling a light switch) to be turned on. A photoresistor would be an obvious choice here, but we can also accurately calculate twilight times with the PyEphem astronomy kit. Here’s how to control a Raspberry Pi camera with PyEphem running on Python 2.x (current versions should work with Python 3.x as well).

First, make sure your system is up to date:

sudo apt-get update
sudo apt-get upgrade

I have two small shell scripts to start and stop the camera’s video stream.

# kill what needs to be killed
sudo pkill -6 mjpg_streamer
sudo pkill -6 raspistill
sudo mkdir /tmp/stream
sudo raspistill -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 86000000 -th 0:0:0 -n &
LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i " -f /tmp/stream -n pic.jpg" -o " -p 9000 -w /opt/mjpg-streamer/www" &

sudo pkill -6 mjpg_streamer
sudo pkill -6 raspistill

Cron and anacron can be used to periodically schedule these scripts, but since we want to schedule dynamically (based on sunrise and sunset) the ‘at’ scheduler seems more useful.

sudo apt-get install at

This wil also install the Exim4 MTA as ‘at’ depends on it for sending its output.

Now we can create our schedule scripts.

at -M $1 today < /home/pi/

at -M $1 today < /home/pi/

The time argument passed over $1 takes four digits (e.g. 2030 for 20:30).

Next we need a Python script to calculate the twilight times (based on our location) and schedule the ‘at’ jobs. Install PyEphem:

sudo apt-get install python-setuptools
sudo easy_install pip
sudo apt-get install python-dev
sudo pip install pyephem

The script is extremely straightforward.

from subprocess import call
import ephem
nuetterden = ephem.Observer()
nuetterden.lon = '6.0592' = '51.7860'
nuetterden.elevation = 20
nuetterden.horizon = '-6'
start_date_time = ephem.localtime(nuetterden.next_rising(ephem.Sun(), use_center=True))
stop_date_time = ephem.localtime(nuetterden.next_setting(ephem.Sun(), use_center=True))
at_start_time = '%02d%02d' % (start_date_time.hour, start_date_time.minute)
at_stop_time = '%02d%02d' % (stop_date_time.hour, stop_date_time.minute)
call(['/home/pi/', at_start_time]) 
call(['/home/pi/', at_stop_time])

First we define an Observer object that represents our location, which in my case happens to be the village of Nütterden in Germany. The object takes the decimal co-ordinates and the elevation in meters. Twilight is defined as “civil twilight” here, which means that it starts and ends when the center of the sun is at six degrees beneath the horizon. We convert the computed times to the four digit arguments that ‘at’ wants to see.

The scheduler script wil be run nightly, e.g. at one o’clock. Edit the crontab:

crontab -e

Add the following line:

0 1 * * * /home/pi/