Raspberry Pi - Sunrise/Sunset Timer for Christmas Lights


15 posts
by savageautomate » Wed Dec 05, 2012 6:42 am
Just in time for the holidays ..

A very simple Raspberry Pi project to control your (exterior) Christmas lights based on the calculated sunrise/sunset times for your location.
http://www.savagehomeautomation.com/projects/raspberry-pi-sunrise-sunset-timer-for-christmas-lights.html

Image

Merry Christmas!
Robert Savage | Follow me @savageautomate
http://www.pi4j.com | http://www.pislices.com
http://www.savagehomeautomation.com
User avatar
Posts: 184
Joined: Thu Aug 16, 2012 3:20 pm
Location: USA
by ski522 » Wed Dec 05, 2012 11:48 am
Cool...On my NSLU2(http://www.nslu2-linux.org/), which has been hacked to run Linux, I do a similar thing using X10 modules, X10 firecracker and controlling the one/off times of those modules with a PHP program that determines sunset times. Been thinking about porting that over to my PI, but heard that there are some issues with USB/serial adapters on the PI.
Posts: 389
Joined: Sun Sep 30, 2012 2:22 pm
by scruss » Wed Dec 05, 2012 12:44 pm
Nice use of a PowerSwitch Tail there. Looks like the sort of thing that MisterHouse is built for, but if your Java solution works ...

I have Heyu + x10 working here, though I don't know for how long. I'll probably just dedicate a Pi to house control and apply the USB fullspeed hack to add some stability.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.
User avatar
Posts: 284
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
by Dweeber » Wed Dec 05, 2012 1:16 pm
I actually thought of using a Raspberry Pi as a Synchronized Xmas light controller....

In a waterproof box....

o AC power in
o Raspberry Pi
o WiFi Adapter
o Controller board that controls a number of AC switches.
o Plug lights into the various switches
o Connect Audio out to FM Transmitter

Have the Raspberry Play music over the FM Transmitter and have a program time when to turn the AC switches on and off.

Using the WiFi adapter, use the Raspberry Pi as a hotspot so you could go outside and control it from say a tablet.
Dweeber A.K.A. Kevin...
My RPI Info Pages including Current Setup - http://rpi.tnet.com
User avatar
Posts: 606
Joined: Fri Aug 17, 2012 3:35 am
Location: Mesa, AZ
by tedhale » Wed Dec 05, 2012 2:18 pm
I have a home automation/alarm system running now on the Pi.
It uses the serial port on the GPIO pins. I have had a lot of problems with USB to Serial adapters on normal Linux systems, so I didn't want to go that route on the Pi.
I haven't written up my blog post on the X10 interface yet, but you can see the other progress I have made on my blog.
http://raspberrypihobbyist.blogspot.com/
- Ted B. Hale
http://raspberrypihobbyist.blogspot.com
User avatar
Posts: 105
Joined: Thu Sep 20, 2012 4:52 pm
Location: Williamsburg, VA, USA
by savageautomate » Wed Dec 05, 2012 3:33 pm
tedhale wrote:I have a home automation/alarm system running now on the Pi.
It uses the serial port on the GPIO pins. I have had a lot of problems with USB to Serial adapters on normal Linux systems, so I didn't want to go that route on the Pi.
I haven't written up my blog post on the X10 interface yet, but you can see the other progress I have made on my blog.
http://raspberrypihobbyist.blogspot.com/

That's a pretty impressive undertaking :-)

I will definitely be interested in the X10 interface.
Robert Savage | Follow me @savageautomate
http://www.pi4j.com | http://www.pislices.com
http://www.savagehomeautomation.com
User avatar
Posts: 184
Joined: Thu Aug 16, 2012 3:20 pm
Location: USA
by fatcinco » Sat Dec 08, 2012 11:52 am
I did the same thing with open zwave. Love it the range.

http://thomasloughlin.com/z-wave-christmas-lights/
Posts: 26
Joined: Tue May 15, 2012 4:50 am
by scruss » Mon Dec 10, 2012 12:42 pm
Incidentally, if anyone's looking for a simple sunset/sunrise/dawn/dusk timer, Sunwait is designed to run from cron. It's a very small C program.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.
User avatar
Posts: 284
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
by tomhannen » Sun Jan 06, 2013 6:27 pm
Hi. I'm attempting to install Sunwait, as scruss mentioned - it sounds like the perfect complement to my raspberry-strogonanoff project. I'm pretty new to Linux, and I'm attempting to install it.

  • I've downloaded the .tar.gz file from here, and expanded it into a folder (containing 7 files) on my mac.
  • I've sftp'd the expanded files into a new folder called sunwait in the home folder of my pi.
When I try to make the files, it gives this error:
Code: Select all
pi@raspberrypi ~/sunwait $ sudo make
cc -g    -c -o main.o main.c
main.c: In function ‘main’:
main.c:155:14: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
main.c:162:11: warning: incompatible implicit declaration of built-in function ‘strstr’ [enabled by default]
cc -g    -c -o print.o print.c
cc -g    -c -o sunriset.o sunriset.c
cc -o sunwait -g  main.o print.o sunriset.o  -lm
pi@raspberrypi ~/sunwait $ sudo make install
make: *** No rule to make target `install'.  Stop.

Any ideas much appreciated...
Posts: 12
Joined: Sun Jul 31, 2011 9:27 am
by carrotjuice » Mon Jan 07, 2013 2:06 am
tomhannen wrote:Hi. I'm attempting to install Sunwait, as scruss mentioned - it sounds like the perfect complement to my raspberry-strogonanoff project. I'm pretty new to Linux, and I'm attempting to install it.

  • I've downloaded the .tar.gz file from here, and expanded it into a folder (containing 7 files) on my mac.
  • I've sftp'd the expanded files into a new folder called sunwait in the home folder of my pi.
When I try to make the files, it gives this error:
Code: Select all
pi@raspberrypi ~/sunwait $ sudo make
cc -g    -c -o main.o main.c
main.c: In function ‘main’:
main.c:155:14: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
main.c:162:11: warning: incompatible implicit declaration of built-in function ‘strstr’ [enabled by default]
cc -g    -c -o print.o print.c
cc -g    -c -o sunriset.o sunriset.c
cc -o sunwait -g  main.o print.o sunriset.o  -lm
pi@raspberrypi ~/sunwait $ sudo make install
make: *** No rule to make target `install'.  Stop.

Any ideas much appreciated...


The sunwait makefile is short and sweet--it only builds the project, and leaves you to install it yourself. You can either run it in place, or copy it to e.g. /usr/local/bin. Don't forget to make sure the binary has execute permissions as well. Lastly, if sunwait isn't in the $PATH and you're adding it to your crontab, be sure to use the full pathname or cron won't be able to find it. HTH.
Posts: 1
Joined: Mon Jan 07, 2013 1:39 am
by scruss » Mon Jan 07, 2013 3:45 am
  • those compilation errors are okay. Best not to use 'sudo make'; I just call make on its own.
  • there is no install script or rule; all I did was 'sudo cp sunwait /usr/local/bin'.

The only disadvantage of calling sunwait from cron is that if your machine gets rebooted while sunwait is waiting, the job won't trigger.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.
User avatar
Posts: 284
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
by tedhale » Mon Jan 07, 2013 1:37 pm
I solved the sunrise/sunset problem in my home automation code by using CURL and pulling today's times for sunrise and sunset for my location from the US Naval Observatory site.
This is called every time the program starts and when a new day is detected (i.e. it passed midnight)

Here is the code I use.

Code: Select all
// Get today's sunrise and sunset times from USNO

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <malloc.h>
#include <curl/curl.h>

// US Naval Observatory
char PostURL[] = "http://aa.usno.navy.mil/cgi-bin/aa_pap.pl";

/* put YYYY  MM  DD into this */
char PostDataFmt[] =   
"FFX=1&ID=AA&xxy=%04d&xxm=%02d&xxd=%02d&st=VA&place=Williamsburg&ZZZ=END";

struct MemoryStruct {
  char *memory;
  size_t size;
};

/****************************************************************************/
static size_t
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)data;

  if (mem->memory)
   mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  else
   mem->memory = malloc(realsize + 1);
  if (mem->memory) {
    memcpy(&(mem->memory[mem->size]), ptr, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;
  }
  return realsize;
}

/****************************************************************************/

int GetSunRise(time_t *sunrise, time_t *sunset)
{
   CURL      *curl;
   CURLcode   res;
   char      postdata[100];
   time_t      now;
   struct tm   *today;
   struct tm   tmx;
   char      temp[20];
   char      *p;
   struct MemoryStruct chunk;

   chunk.memory=NULL;
   chunk.size = 0;   

   // init cURL
   curl = curl_easy_init();
   if(!curl) {
      Log("GetSunRise: curl_easy_init failed");
      return 1;
   }
   curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

   // who ya gonna call
   curl_easy_setopt(curl, CURLOPT_URL, PostURL);

   // fill in the post buffer with today's date
   time(&now);
   today=localtime(&now);
   snprintf(postdata,sizeof(postdata),PostDataFmt,
            today->tm_year+1900,today->tm_mon+1,today->tm_mday);
   postdata[sizeof(postdata)-1]=0;
   ///Log("GetSunRise: posting %s",postdata);
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);

   // set the write callback
   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
   curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

   // do the dirty work
   res = curl_easy_perform(curl);

   // cleanup
   curl_easy_cleanup(curl);

   // dump what we got
   ///Log("GetSunRise got back:\n%s",chunk.memory);

   // find sunrise
   p = strstr(chunk.memory,"Sunrise   ");
   if (p) {
      strncpy(temp,p+26,10);
      temp[10]=0;
      Log("SUNRISE IS %s",temp);
      // convert to time_t
      p=strchr(temp,':');
      *p=0;
      today->tm_hour=atoi(temp);
      today->tm_min=atoi(++p);
      today->tm_sec=0;
      *sunrise = mktime(today);
   }

   // find sunset
   p = strstr(chunk.memory,"Sunset    ");
   if (p) {
      strncpy(temp,p+26,10);
      temp[10]=0;
      Log("SUNSET IS %s",temp);
      // convert to time_t
      p=strchr(temp,':');
      *p=0;
      today->tm_hour=atoi(temp)+12;
      today->tm_min=atoi(++p);
      today->tm_sec=0;
      *sunset = mktime(today);
   }

   free(chunk.memory);
   return 0;
}


Of course, you have to modify the posted data for your location.
- Ted B. Hale
http://raspberrypihobbyist.blogspot.com
User avatar
Posts: 105
Joined: Thu Sep 20, 2012 4:52 pm
Location: Williamsburg, VA, USA
by tomhannen » Wed Jan 09, 2013 11:01 pm
Thanks all - I didn't realise the sunwait executable had been created. When I saw the errors, I assumed it had crashed out, but sure enough, it's there and it works!
Posts: 12
Joined: Sun Jul 31, 2011 9:27 am
by STPi » Thu Apr 04, 2013 2:32 pm
There is a very good standard Linux command "remind" that can trigger events based on sunrise/sunset times (once GEO location is provided) and many other fancy things:

http://linux.die.net/man/1/remind
Posts: 1
Joined: Thu Apr 04, 2013 2:27 pm
by Gadjetnut » Fri Apr 05, 2013 11:09 pm
If you are building an alarm system, please check out this website:

http://www.projects.privateeyepi.com/home

They have full instructions on how to create an alarm system with email alerts, web based dashboard to view and control you alarm. No fees.

http://www.privateeyepi.com/image/dashboard.jpg
Posts: 15
Joined: Fri Apr 05, 2013 9:13 pm