hey, it’s the sun … heyu and sunwait and cron on the Raspberry Pi

Yep, springtime’s coming, and today’s the first day I know it, despite the -5.8°C outside. I know spring is coming because my sunrise-adjusted lights came on before my alarm today. I’m controlling them with a Raspberry Pi, cron, and X10.

I’d described how to build and use heyu previously, so I won’t go into it further. I use sunwait to control the timing relative to local sunrise and sunset. Sunwait is a simple C program which builds quickly, and you can put the executable somewhere in your path.

(NB: newer versions of sunwait use a completely incompatible command line format. Everything here refers to the 2004 version I linked to above, which does exactly what I need in the way it’s described here.)

You need to know your latitude and longitude to use sunwait. To check its setting for the day, you can call it with the -p option:

$ sunwait -p 43.729N 79.292W
Using location:             43.729000N, 79.292000W
Date:                        6 Feb 2013 
Local time:                  7:44 
Day length:                 10:13 hours
With civil twilight         11:10 hours
With nautical twilight      12:18 hours
With astronomical twilight  13:25 hours
Length of twilight:  civil   0:28 hours
                  nautical   1:02 hours
              astronomical   1:35 hours
Current specified time zone: EST (-5 from UTC) 
Sun transits meridian 1231 EST
                   Sun rises 0726 EST, sets 1736 EST
       Civil twilight starts 0656 EST, ends 1806 EST
    Nautical twilight starts 0622 EST, ends 1840 EST
Astronomical twilight starts 0548 EST, ends 1913 EST

So for me, today’s sunrise is at 0726, and sunset is at 1736. All sunwait does is wait until a specific solar time is reached, and then exit. Whatever command you call after sunwait, therefore, is what gets run at the right time. So if I wanted X10 device H1 to come on an hour before sunrise, I’d run:

sunwait sun up -1:00:00 43.729N 79.292W; heyu on h1

Remembering to run this every day before sunrise would be a pain, so this is where cron helps. cron uses a slightly odd config file that is edited using the crontab -e command. Here’s the relevant bit of my crontab, showing the light control times:

# m h  dom mon dow   command
 01 00   *   *   *   /usr/local/bin/sunwait sun up -1:00:00 43.729N 79.292W; /usr/local/bin/heyu on h1
 02 00   *   *   *   /usr/local/bin/sunwait sun up +1:00:00 43.729N 79.292W; /usr/local/bin/heyu off h1
 03 00   *   *   *   /usr/local/bin/sunwait sun down -1:00:00 43.729N 79.292W; /usr/local/bin/heyu on h1
 45 22   *   *   *   /usr/local/bin/heyu off h1

(you can view your crontab with crontab -l)

The columns in crontab are:

  • minute
  • hour
  • day of month
  • month
  • day of week
  • command

So the four crontab lines mean:

  1. Every day at 00:01, wait until an hour before sunrise and turn light H1 on
  2. Every day at 00:02, wait until an hour after sunrise and turn light H1 off
  3. Every day at 00:03, wait until an hour before sunset and turn light H1 on
  4. At 22:45, turn light H1 off.

So for quite a bit of the day, there are a couple of sunwait tasks just quietly waiting until sunrise or sunset to do their thing. cron, incidentally, is picky about executable paths; that’s why I specified full paths to both sunwait and heyu.

What I’d really like to do is have time on this machine update without a network connection, because it’s running from a particularly messy router set up in a spare bedroom. I should investigate a real-time clock, with GPS time updates from an I²C GPS, talking through a bluetooth console. In my copious free time, of course.


  1. Perfect – this got my cron and sunwait up and running – I use a telstick to switch on my lights via some homeeasy sockets but exactly the same principle.

  2. Hello and thanks for this info but…. I am in northern calif and when I use the the lat/long I get from google maps 38.974645, -121.012310 its wrong.. using location changes and even though it says UTC-7 and the local time is correct it says Sun rises 1514 PDT, sets 0206 PDT which is way off. What am I doing wrong?

    pi@raspberrypi:~/Downloads/sunwait-20041208 $ ./sunwait -p 38.974645, -121.012310
    Using location: 38.974645N, 121.012310E
    Date: 23 Oct 2018
    Local time: 20:51
    Day length: 10:54 hours
    With civil twilight 11:46 hours
    With nautical twilight 12:48 hours
    With astronomical twilight 13:50 hours
    Length of twilight: civil 0:25 hours
    nautical 0:56 hours
    astronomical 1:27 hours
    Current specified time zone: PDT (-7 from UTC)
    Sun transits meridian 2040 PDT
    Sun rises 1514 PDT, sets 0206 PDT
    Civil twilight starts 1447 PDT, ends 0233 PDT
    Nautical twilight starts 1416 PDT, ends 0304 PDT
    Astronomical twilight starts 1345 PDT, ends 0335 PDT

  3. You forgot the N and W on your coordinates. Also, that comma doesn’t belong there:
    sunwait -p 38.974645N 121.012310W
    When I run that (with TZ=’America/Los_Angeles’ to match yours) I get:

    Using location:             38.974645N, 121.012310W
    Date:                       24 Oct 2018 
    Local time:                  4:49 
    Day length:                 10:50 hours
    With civil twilight         11:42 hours
    With nautical twilight      12:44 hours
    With astronomical twilight  13:46 hours
    Length of twilight:  civil   0:25 hours
                      nautical   0:57 hours
                  astronomical   1:28 hours
    Current specified time zone: PDT (-7 from UTC) 
    Sun transits meridian 1248 PDT
                       Sun rises 0724 PDT, sets 1812 PDT
           Civil twilight starts 0656 PDT, ends 1839 PDT
        Nautical twilight starts 0625 PDT, ends 1910 PDT
    Astronomical twilight starts 0554 PDT, ends 1941 PDT

    Which is much more like the thing.

  4. Yep it was the comma, I had tried to run it with and without the N/W but never tried without the comma… TY works like a charm…

  5. scruss,

    Thanks for this page – on sunwait – and the other on heyu. I have successfully implemented this on a Raspberry Pi 3. It’s been several years since you wrote these pages and when I did my implementation, so I thought I would point out to you – and any other people who wish to get this same configuration working – that there are some small changes needed.

    The changes are primarily due to changes that the author of ‘sunwait’ has made in the command line arguments. In your example, you used ‘sunwait -p …’ to check the settings for the day (in your location). In the current implementation of sunwait, the command line option is ‘report’.

    For the actual command line options as you showed them in the crontab example, you used ‘sunwait sun up -1:00:00 [latitude] [longitude]’ for a sunrise command. The new command line options need to be ‘sunwait wait rise offset -1:00:00 [lat] [long]’ for a sunrise command and ‘sunwait wait set offset -1:00:00 [lat] [long]’ for a sunset command. Once I made these adjustments to the command line arguments, things started working better.

    I also made some changes to how I put the commands in the crontab. For my implementation I had a porch light I wanted turned on in the evening (just prior to sunset) and off just after sunrise. So it spanned a change from one day to the next. If I fired off each of the sunwait commands just after midnight – as you did in your example – I got inconsistent results. Not exactly sure why this happened, but I found that if I fired of any sunwait commands related to events for sunrise at 4 AM instead of just after midnight, and any sunwait commands related to events for sunset at 3 PM everything worked perfectly.

    While debugging the implementation I decided to have crontab call a script the included the heyu and sunwait commands. This gave me the opportunity to simplify the command string in crontab and at the same time allow me to add some logging by adding
    echo “Porch light turned on at: ” `date` >> ~logs/Heyu_log.txt
    So the command called out in crontab is ‘~scripts/Porch_On.sh’. Any changes or adjustments can be made to the script without modifying crontab.

    Again, thanks for the ideas and pointers to heyu and sunwait. Everything seems to be working fine now.

  6. Thanks, Rick. I stick with the original version of the code because it does all I need in the syntax I understand. I’m not going to update the article as the code is still available.

Leave a comment

Your email address will not be published. Required fields are marked *