title


Raspberry Pi
[Integrated System]
system
 
[Block Diagram]
connect
Raspberry Pi2
USB power supplyKSY UB310-0520
Case
USB CameraC270
Solid State RelaySainSmart 2ch SSR
5A Fuse
USB Wireless LANWLI-UC-G301N
USB hubU2H-TZ420SBK
Passive infrared sensorHC-SR501
Jumper wirefemale-female 10cmx6


[Functions]
  • I had activated only the Weather Forecast Announcement System because of the limited number of the SD card write times but I have changed the storage to HDD. So, I have integrated the Monitoring Camera System and the Weather Forecast Announcement System.
  • ver.2 checks the change of the captured pixel by OpenCV and it records the JPEG picture only.
  • Pi detects a human by a passive infrared sensor.
  • If it is in the morning, the Weather Forecast Announcement System will run. If it is in the afternoon, the Monitoring Camera System will run.
  • The recorded pictures and movies are located in the DocumentRoot of web server.
[Main Program]
  • Source code ver.2
    #include <iostream>
    #include <string>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <time.h>
    #include <sys/time.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <syslog.h>
    
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <netdb.h>
     
    #define BCM2708_PERI_BASE        0x3F000000
    #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
    #define PAGE_SIZE (4*1024)
    #define BLOCK_SIZE (4*1024)
    #define MOVIEFPS 8
    #define MAXMOVIENUM 20
    #define MOVIETIME 600
    #define DETECTINT 600
    
    #define HOST "rss.weather.yahoo.co.jp"
    #define RSSSIZE 8096
    #define PAGE "rss/days/4410.xml"
    #define PORT 80
    #define USERAGENT "HTMLGET 1.0"
    
    using namespace std;
    using namespace cv;
    
    int  mem_fd;
    void *gpio_map;
    // I/O access
    volatile unsigned *gpio;
     
    // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
    #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
    #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
    #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
     
    #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
    #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
     
    #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
     
    #define GPIO_PULL *(gpio+37) // Pull up/pull down
    #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
    
    #define MOVIEDIR "/home/www/pi"
    #define SPEAKDIR "/home/pi/cpp/homepi"
     
    int movienumber;
    int timecount;
    int jpgcount;
    bool rec;
    
    void setup_io();
    
    int create_tcp_socket();
    int speakweather();
    char *get_ip(char *host);
    char *build_get_query(char *host, char *page);
    int get_weather(char *rssbuf, int *index, char *title);
    
    int main(int argc, char *argv[])
    {
            unsigned char b1,g1,r1,b2,g2,r2;
            char outfile[20];
            if (daemon(1,0) == -1) {
                    syslog(LOG_USER|LOG_INFO,"failed to launch daemon.\n");
                    return -1;
            }
    
            char outfile2[20];
            char workcommand[1000];
    
            struct timespec wt={0,100000000}; // sleep time of main loop 100mS.
    
            struct tm *s_time;
            time_t the_time;
    
            syslog(LOG_USER|LOG_INFO,"Start");
    
            setup_io();
            INP_GPIO(4);
            INP_GPIO(17);
            OUT_GPIO(17);
    
            movienumber = 0;
            timecount = 0;
            rec = false;
    
            VideoCapture inputVideo(0);
            if (!inputVideo.isOpened())
            {
                    syslog(LOG_USER|LOG_INFO,"Could not open the input video.\n");
                    return -1;
            }
            Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), (int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
    
            Mat frame,clrframe;
            inputVideo >> clrframe; // Dummy read to start camera
    
            for (;;) 
            {
                    (void) time(&the_time);
                    s_time=localtime(&the_time);
                    if (rec){
                            inputVideo >> frame;
                            if(!frame.empty()){ 
                                    b2=b1;g2=g1;r2=r1;
                                    b1=frame.at<Vec3b>(320,240)[0];
                                    g1=frame.at<Vec3b>(320,240)[1];
                                    r1=frame.at<Vec3b>(320,240)[2];
                                    if(abs(b1-b2)+abs(g1-g2)+abs(r1-r2)>50 && timecount>0){
                                            chdir(MOVIEDIR);
                                            sprintf(outfile, "%03d.jpg", movienumber);
                                            imwrite(outfile, frame);
                                            syslog(LOG_USER|LOG_INFO,"write jpg.");
                                            timecount=DETECTINT;
                                            rec=false;
                                            movienumber++;
                                            if(movienumber>=MAXMOVIENUM){
                                                    syslog(LOG_USER|LOG_INFO,"picture number over.");
                                            }
                                    }
                            }
                            timecount++;
                            if(timecount>MOVIETIME){
                                    rec = false;
                                    syslog(LOG_USER|LOG_INFO,"time over.");
                            }
                            nanosleep(&wt,NULL);
                    }else if(GET_GPIO(4) > 0){
                            if(timecount>0){
                                    timecount=DETECTINT;
                            }else if(s_time->tm_hour>=6 && s_time->tm_hour<9){
    //                        }else if(1){
                                    GPIO_SET = 1<<17;
                                    if(speakweather()!=0){
                                            syslog(LOG_USER|LOG_INFO,"Error:speakweather error.");
                                    }
                                    GPIO_CLR = 1<<17;
                                    timecount=DETECTINT;
    //                        }else if(s_time->tm_hour>=9 && s_time->tm_hour<20 && movienumber<MAXMOVIENUM){
                            }else if(movienumber<MAXMOVIENUM){
                                    rec = true;
                                    timecount=0;
                                    inputVideo >> clrframe; // Dummy reads to skip old cache.
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    syslog(LOG_USER|LOG_INFO,"detect.");
                            }
                    }else{
                            nanosleep(&wt,NULL);
                            if(timecount>0){timecount--;}
                            if(s_time->tm_hour==3 && s_time->tm_min==0 && movienumber>0){  // reset movienumber at every morning
                                    chdir(MOVIEDIR);
                                    for(movienumber=19;movienumber>0;movienumber--){
                                            sprintf(workcommand, "rm -f %03d.jpg", movienumber);
                                            system(workcommand);
                                    }
                                    movienumber=0;
                            }
                    }
            }
            GPIO_CLR = 1<<17;
            inputVideo.release();
            syslog(LOG_USER|LOG_INFO,"Finished.");
            return 0;
    }
    
    //
    // Set up a memory regions to access GPIO
    //
    void setup_io()
    {
       /* open /dev/mem */
       if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
          syslog(LOG_USER|LOG_INFO,"Error:can't open /dev/mem ");
          exit(-1);
       }
     
       /* mmap GPIO */
       gpio_map = mmap(
          NULL,             //Any adddress in our space will do
          BLOCK_SIZE,       //Map length
          PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
          MAP_SHARED,       //Shared with other processes
          mem_fd,           //File to map
          GPIO_BASE         //Offset to GPIO peripheral
       );
     
       close(mem_fd); //No need to keep mem_fd open after mmap
     
       if (gpio_map == MAP_FAILED) {
          syslog(LOG_USER|LOG_INFO,"Error:mmap error %d", (int)gpio_map);//errno also set!
          exit(-1);
       }
     
       // Always use volatile pointer!
       gpio = (volatile unsigned *)gpio_map;
     
     
    } // setup_io
    
    int speakweather()
    {
      struct sockaddr_in *remote;
      int sock;
      int tmpres;
      char *ip;
      char *get;
      char totalbuf[RSSSIZE+1];
      char buf[BUFSIZ+1];
      char titlebuf[BUFSIZ+1];
      char todayweekday[100];
      char todayweekdayjp[100];
      char host[]=HOST;
      char page[]=PAGE;
      char *tempchar;
      int titlenum;
      int index;
    
      time_t timer;
      struct tm *date;
      timer = time(NULL);
      date = localtime(&timer);
      strftime(todayweekday, sizeof(todayweekday), "%A", date);
      if (strcmp(todayweekday,"Sunday")==0){
        strcpy(todayweekdayjp,"日");
      }else
      if (strcmp(todayweekday,"Monday")==0){
        strcpy(todayweekdayjp,"月");
      }else
      if (strcmp(todayweekday,"Tuesday")==0){
        strcpy(todayweekdayjp,"火");
      }else
      if (strcmp(todayweekday,"Wednesday")==0){
        strcpy(todayweekdayjp,"水");
      }else
      if (strcmp(todayweekday,"Thursday")==0){
        strcpy(todayweekdayjp,"木");
      }else
      if (strcmp(todayweekday,"Friday")==0){
        strcpy(todayweekdayjp,"金");
      }else{
        strcpy(todayweekdayjp,"土");
      }
    
      sock = create_tcp_socket();
      if(sock<0){
        return -1;
      }
      ip = get_ip(host);
      if(strcmp(ip,"err")==0){
        free(ip);
        close(sock);
        return -1;
      }
      remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
      remote->sin_family = AF_INET;
      tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
      if( tmpres < 0)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't set remote->sin_addr.s_addr");
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }else if(tmpres == 0){
        syslog(LOG_USER|LOG_INFO,"Error:%s is not a valid IP addressn", ip);
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }
      remote->sin_port = htons(PORT);
    
      if(connect(sock, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
        syslog(LOG_USER|LOG_INFO,"Error:Could not connect");
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }
      get = build_get_query(host, page);
    
      //Send the query to the server
      int sent = 0;
      while(sent < strlen(get))
      {
        tmpres = send(sock, get+sent, strlen(get)-sent, 0);
        if(tmpres == -1){
          syslog(LOG_USER|LOG_INFO,"Error:Can't send query");
        }
        sent += tmpres;
      }
      //now it is time to receive the page
      memset(buf, 0, sizeof(buf));
      memset(totalbuf, 0, sizeof(totalbuf));
      char * htmlcontent;
      while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0){
        if(strlen(totalbuf)+strlen(buf) < RSSSIZE){
          strcat(totalbuf, buf);
        }
        memset(buf, 0, tmpres);
      }
      if(tmpres < 0)
      {
          syslog(LOG_USER|LOG_INFO,"Error: receiving data");
      }
    
      htmlcontent = totalbuf;
      while(get_weather(htmlcontent, &index, titlebuf)==0){
        if(strstr(titlebuf, todayweekdayjp)!=NULL){
          chdir(SPEAKDIR);
          system("aplay -D hw:2,0 tenki.wav > /dev/null 2>&1");
          if(strstr(titlebuf,"雨")!=NULL){
            system("aplay -D hw:2,0 ame.wav > /dev/null 2>&1");
            system("aplay -D hw:2,0 kasa.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"雪")!=NULL){
            system("aplay -D hw:2,0 yuki.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"曇")!=NULL){
            system("aplay -D hw:2,0 kumori.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"晴")!=NULL){
            system("aplay -D hw:2,0 hare.wav > /dev/null 2>&1");
          }else{
            syslog(LOG_USER|LOG_INFO,"Error:No match.");
          }
          break;
        }
        htmlcontent += index + 15;
      }
      free(get);
      free(remote);
      free(ip);
      close(sock);
      return 0;
    }
    
    int create_tcp_socket()
    {
      int sock;
      if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
        syslog(LOG_USER|LOG_INFO,"Error:Can't create TCP socket");
      }
      return sock;
    }
    
    
    char *get_ip(char *host)
    {
      struct hostent *hent;
      int iplen = 15; //XXX.XXX.XXX.XXX
      char *ip = (char *)malloc(iplen+1);
      memset(ip, 0, iplen+1);
      if((hent = gethostbyname(host)) == NULL)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't get IP");
        strcpy(ip,"err");
        return ip;
      }
      if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't resolve host");
        strcpy(ip,"err");
        return ip;
      }
      return ip;
    }
    
    char *build_get_query(char *host, char *page)
    {
      char *query;
      char *getpage = page;
      char tpl[] = "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
      if(getpage[0] == '/'){
        getpage = getpage + 1;
        syslog(LOG_USER|LOG_INFO,"Removing leading \"/\", converting %s to %s\n", page, getpage);
      }
      // -5 is to consider the %s %s %s in tpl and the ending \0
      query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
      sprintf(query, tpl, getpage, host, USERAGENT);
      return query;
    }
    
    int get_weather(char *rssbuf, int *index, char *title)
    {
      char* ret;
      char* retend;
      ret = strstr(rssbuf, "<title>");
      if(ret!=NULL){
        ret+=7;
        retend = strstr(ret, "</title>");
        if(retend!=NULL && retend-ret<BUFSIZ){
          strncpy(title, ret, retend-ret);
          *index=retend-rssbuf;
          return 0;
        }
      }
      return -1;
    }
    
    
  • Source code ver.1
    
    #include <iostream>
    #include <iostream>
    #include <string>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <time.h>
    #include <sys/time.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <syslog.h>
    
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <netdb.h>
    
    #define BCM2708_PERI_BASE        0x3F000000
    #define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
    #define PAGE_SIZE (4*1024)
    #define BLOCK_SIZE (4*1024)
    #define MOVIEFPS 8
    #define MAXMOVIENUM 20
    #define MOVIETIME 100
    #define DETECTINT 600
    
    #define HOST "rss.weather.yahoo.co.jp"
    #define RSSSIZE 8096
    #define PAGE "rss/days/4410.xml"
    #define PORT 80
    #define USERAGENT "HTMLGET 1.0"
    
    using namespace std;
    using namespace cv;
    
    int  mem_fd;
    void *gpio_map;
    // I/O access
    volatile unsigned *gpio;
    
    // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
    #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
    #define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
    #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
    
    #define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
    #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
    
    #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
    
    #define GPIO_PULL *(gpio+37) // Pull up/pull down
    #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
    
    #define MOVIEDIR "/home/www/pi"
    #define SPEAKDIR "/home/pi/cpp/homepi"
    
    int movienumber;
    int timecount;
    int jpgcount;
    bool rec;
    
    void setup_io();
    
    int create_tcp_socket();
    int speakweather();
    char *get_ip(char *host);
    char *build_get_query(char *host, char *page);
    int get_weather(char *rssbuf, int *index, char *title);
    
    int main(int argc, char *argv[])
    {
            if (daemon(1,0) == -1) {
                    syslog(LOG_USER|LOG_INFO,"failed to launch daemon.\n");
                    return -1;
            }
    
            VideoWriter outputVideo;
            char outfile[20];
            char workcommand[1000];
    
            struct timespec wt={0,100000000}; // sleep time of main loop 100mS.
    
            struct tm *s_time;
            time_t the_time;
    
            syslog(LOG_USER|LOG_INFO,"Start");
    
            setup_io();
            INP_GPIO(4);
            INP_GPIO(17);
            OUT_GPIO(17);
    
            movienumber = 0;
            timecount = 0;
            jpgcount = 0;
            rec = false;
    
            VideoCapture inputVideo(0);
            if (!inputVideo.isOpened())
            {
                    syslog(LOG_USER|LOG_INFO,"Could not open the input video.\n");
                    return -1;
            }
            Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), (int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
    
            Mat frame,clrframe;
            inputVideo >> clrframe; // Dummy read to start camera
    
            for (;;)
            {
                    if (rec){
                            inputVideo >> frame;
                            if(!frame.empty()){
                                    outputVideo << frame;
                            }
                            timecount++;
                            if(timecount>MOVIETIME){
                                    rec = false;
                                    outputVideo.release();
                                    syslog(LOG_USER|LOG_INFO,"released. convert avi to 3gp.");
                                    chdir(MOVIEDIR);
                                    sprintf(workcommand, "avconv -y -i %03d.avi -r:v 30 -codec:v mpeg4 -b:v 64k -s:v 320x240 -codec:a libaac -ar:a 48000 %03d.3gp", movienumber, movienumber);
                                    system(workcommand);
                                    syslog(LOG_USER|LOG_INFO,"send 3gp to docomo.");
                                    sprintf(workcommand, "sh mymail.sh %03d.3gp", movienumber);
                                    system(workcommand);
                                    movienumber++;
                                    if(movienumber>=MAXMOVIENUM){
                                            syslog(LOG_USER|LOG_INFO,"movie number over.");
                                    }
                                    timecount=DETECTINT;
                                    syslog(LOG_USER|LOG_INFO,"done.");
                            }
                    }else if(GET_GPIO(4) > 0){
                            (void) time(&the_time);
                            s_time=localtime(&the_time);
                            if(timecount>0){
                                    timecount=DETECTINT;
                            }else if(s_time->tm_hour>=6 && s_time->tm_hour<9){
    //                      }else if(0){
                                    GPIO_SET = 1<<17;
                                    if(speakweather()!=0){
                                            syslog(LOG_USER|LOG_INFO,"Error:speakweather error.");
    //                                      break;
                                    }
                                    GPIO_CLR = 1<<17;
                                    timecount=DETECTINT;
                                    movienumber=0;
                            }else if(s_time->tm_hour>=9 && s_time->tm_hour<20 && movienumber<MAXMOVIENUM){
    //                      }else if(movienumber<MAXMOVIENUM){
                                    rec = true;
                                    timecount=0;
                                    chdir(MOVIEDIR);
                                    sprintf(outfile, "%03d.avi", movienumber);
                                    outputVideo.open(outfile, CV_FOURCC('M', 'P', '4', '2'), MOVIEFPS, S, true);
                                    if (!outputVideo.isOpened())
                                    {
                                            syslog(LOG_USER|LOG_INFO,"Error:Could not open the output video.");
                                            return -1;
                                    }
                                    inputVideo >> clrframe; // Dummy reads to skip old cache.
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    syslog(LOG_USER|LOG_INFO,"detected.");
                            }
                    }else{
                            nanosleep(&wt,NULL);
                            if(timecount>0){timecount--;}
                            if(jpgcount<6000){
                                    jpgcount++;
                            }else{
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    inputVideo >> clrframe;
                                    chdir(MOVIEDIR);
                                    imwrite("000.jpg",clrframe);
                                    jpgcount=0;
                            }
                    }
            }
            GPIO_CLR = 1<<17;
            outputVideo.release();
            inputVideo.release();
            syslog(LOG_USER|LOG_INFO,"Finished.");
            return 0;
    }
    
    //
    // Set up a memory regions to access GPIO
    //
    void setup_io()
    {
       /* open /dev/mem */
       if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
          syslog(LOG_USER|LOG_INFO,"Error:can't open /dev/mem ");
          exit(-1);
       }
    
       /* mmap GPIO */
       gpio_map = mmap(
          NULL,             //Any adddress in our space will do
          BLOCK_SIZE,       //Map length
          PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
          MAP_SHARED,       //Shared with other processes
          mem_fd,           //File to map
          GPIO_BASE         //Offset to GPIO peripheral
       );
    
       close(mem_fd); //No need to keep mem_fd open after mmap
    
       if (gpio_map == MAP_FAILED) {
          syslog(LOG_USER|LOG_INFO,"Error:mmap error %d", (int)gpio_map);//errno also set!
          exit(-1);
       }
    
       // Always use volatile pointer!
       gpio = (volatile unsigned *)gpio_map;
    
    
    } // setup_io
    
    int speakweather()
    {
      struct sockaddr_in *remote;
      int sock;
      int tmpres;
      char *ip;
      char *get;
      char totalbuf[RSSSIZE+1];
      char buf[BUFSIZ+1];
      char titlebuf[BUFSIZ+1];
      char todayweekday[100];
      char todayweekdayjp[100];
      char host[]=HOST;
      char page[]=PAGE;
      char *tempchar;
      int titlenum;
      int index;
    
      time_t timer;
      struct tm *date;
      timer = time(NULL);
      date = localtime(&timer);
      strftime(todayweekday, sizeof(todayweekday), "%A", date);
      if (strcmp(todayweekday,"Sunday")==0){
        strcpy(todayweekdayjp,"日");
      }else
      if (strcmp(todayweekday,"Monday")==0){
        strcpy(todayweekdayjp,"月");
      }else
      if (strcmp(todayweekday,"Tuesday")==0){
        strcpy(todayweekdayjp,"火");
      }else
      if (strcmp(todayweekday,"Wednesday")==0){
        strcpy(todayweekdayjp,"水");
      }else
      if (strcmp(todayweekday,"Thursday")==0){
        strcpy(todayweekdayjp,"木");
      }else
      if (strcmp(todayweekday,"Friday")==0){
        strcpy(todayweekdayjp,"金");
      }else{
        strcpy(todayweekdayjp,"土");
      }
    
      sock = create_tcp_socket();
      if(sock<0){
        return -1;
      }
      ip = get_ip(host);
      if(strcmp(ip,"err")==0){
        free(ip);
        close(sock);
        return -1;
      }
      remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
      remote->sin_family = AF_INET;
      tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
      if( tmpres < 0)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't set remote->sin_addr.s_addr");
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }else if(tmpres == 0){
        syslog(LOG_USER|LOG_INFO,"Error:%s is not a valid IP addressn", ip);
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }
      remote->sin_port = htons(PORT);
    
      if(connect(sock, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
        syslog(LOG_USER|LOG_INFO,"Error:Could not connect");
        free(ip);
        free(remote);
        close(sock);
        return -1;
      }
      get = build_get_query(host, page);
    
      //Send the query to the server
      int sent = 0;
      while(sent < strlen(get))
      {
        tmpres = send(sock, get+sent, strlen(get)-sent, 0);
        if(tmpres == -1){
          syslog(LOG_USER|LOG_INFO,"Error:Can't send query");
        }
        sent += tmpres;
      }
      //now it is time to receive the page
      memset(buf, 0, sizeof(buf));
      memset(totalbuf, 0, sizeof(totalbuf));
      char * htmlcontent;
      while((tmpres = recv(sock, buf, BUFSIZ, 0)) > 0){
        if(strlen(totalbuf)+strlen(buf) < RSSSIZE){
          strcat(totalbuf, buf);
        }
        memset(buf, 0, tmpres);
      }
      if(tmpres < 0)
      {
          syslog(LOG_USER|LOG_INFO,"Error: receiving data");
      }
    
      htmlcontent = totalbuf;
      while(get_weather(htmlcontent, &index, titlebuf)==0){
        if(strstr(titlebuf, todayweekdayjp)!=NULL){
          chdir(SPEAKDIR);
          printf("%s\n",titlebuf);
          system("aplay tenki.wav > /dev/null 2>&1");
          if(strstr(titlebuf,"雨")!=NULL){
            system("aplay ame.wav > /dev/null 2>&1");
            system("aplay kasa.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"雪")!=NULL){
            system("aplay yuki.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"曇")!=NULL){
            system("aplay kumori.wav > /dev/null 2>&1");
          }else
          if(strstr(titlebuf,"晴")!=NULL){
            system("aplay hare.wav > /dev/null 2>&1");
          }
          break;
        }
        htmlcontent += index + 15;
      }
      free(get);
      free(remote);
      free(ip);
      close(sock);
      return 0;
    }
    
    int create_tcp_socket()
    {
      int sock;
      if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
        syslog(LOG_USER|LOG_INFO,"Error:Can't create TCP socket");
      }
      return sock;
    }
    
    
    char *get_ip(char *host)
    {
      struct hostent *hent;
      int iplen = 15; //XXX.XXX.XXX.XXX
      char *ip = (char *)malloc(iplen+1);
      memset(ip, 0, iplen+1);
      if((hent = gethostbyname(host)) == NULL)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't get IP");
        strcpy(ip,"err");
        return ip;
      }
      if(inet_ntop(AF_INET, (void *)hent->h_addr_list[0], ip, iplen) == NULL)
      {
        syslog(LOG_USER|LOG_INFO,"Error:Can't resolve host");
        strcpy(ip,"err");
        return ip;
      }
      return ip;
    }
    
    char *build_get_query(char *host, char *page)
    {
      char *query;
      char *getpage = page;
      char tpl[] = "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
      if(getpage[0] == '/'){
        getpage = getpage + 1;
        syslog(LOG_USER|LOG_INFO,"Removing leading \"/\", converting %s to %s\n", page, getpage);
      }
      // -5 is to consider the %s %s %s in tpl and the ending \0
      query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
      sprintf(query, tpl, getpage, host, USERAGENT);
      return query;
    }
    
    int get_weather(char *rssbuf, int *index, char *title)
    {
      char* ret;
      char* retend;
      ret = strstr(rssbuf, "<title>");
      if(ret!=NULL){
        ret+=7;
        retend = strstr(ret, "</title>");
        if(retend!=NULL && retend-ret<BUFSIZ){
          strncpy(title, ret, retend-ret);
          *index=retend-rssbuf;
          return 0;
        }
      }
      return -1;
    }