[統合システム]
system
 
[構成]
connect
Raspberry Pi2
USB電源KSY UB310-0520
ケース
ソリッドステートリレーSainSmart 2ch SSR
5Aヒューズ
USBカメラC270
USB無線LANWLI-UC-G301N
USBハブU2H-TZ420SBK
赤外線センサーHC-SR501
USB HDDHDJ-UT2.0B
ジャンパワイヤメス-メス 10cmx6

 
[機能概要]
  • SDカードに優しい天気予報だけ運用してましたが、HDD化したので監視カメラも統合しました。
  • ver.2で、OpenCVでカメラ画像の変化の有無を確認するようにし、ムービーをやめて画像だけの保存に変えました。
  • 赤外線センサーで、人体検出します。
  • 午前の場合、天気予報をYahoo! JapanのRSSから取得します。
    リレー制御でスピーカー電源ONします。
    天気予報をアナウンスします。
    スピーカー電源OFFします。
  • (ver.1)午後の場合、カメラで一定期間ムービーを保存します。
    保存したAVI形式ファイルを、ガラケーの3gp形式ファイルに変換します。保存先はWEBサーバのDocumentRoot下にします。
    変換したファイルをメールで送信します。
  • (ver.2)午後の場合、一定期間内にカメラ画像の中心に変化があった場合のみ画像を保存します。保存先はWEBサーバのDocumentRoot下にします。

 
[メインプログラム]
  • ソースコード 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;
    }
    
    
  • ソースコード 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;
    }
    
    
[メンテナンス]
  • NTP Version 4.2.8p7に更新JVNVU#91176422
    http://www.ntp.org/downloads.htmlからソースをダウンロード。
    
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ sudo service ntp stop
    [ ok ] Stopping NTP server: ntpd.
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ ./configure
    [省略]
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ make
    [省略]
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ sudo make install
    [省略]
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ sudo ntpdate -b ntp.nict.jp
    [省略]
    pi@raspberrypi ~/ntp/ntp-4.2.8p7 $ sudo service ntp stop
    [ ok ] Starting NTP server: ntpd.
    

    /etc/init.d/ntpを以下書き換える。実行ファイル場所が変わるのと、デフォルトインストールでは--userオプション無いため。
    
    #DAEMON=/usr/sbin/ntpd
    DAEMON=/usr/local/sbin/ntpd
    
    #  start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $NTPD_OPTS
       start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE
    
  • OpenSSL Version 1.0.2hに更新JVNVU#93163809
    https://www.openssl.org/source/からソースをダウンロード。
    
    pi@raspberrypi ~/openssl/openssl-1.0.2h $ ./config
    [省略]
    pi@raspberrypi ~/openssl/openssl-1.0.2h $ make depend
    [省略]
    pi@raspberrypi ~/openssl/openssl-1.0.2h $ make test
    [省略]
    pi@raspberrypi ~/openssl/openssl-1.0.2h $ sudo make install
    [省略]
    

    PATHに/usr/local/ssl/binを追加する。apache2の証明書を一応作り直しておく。
     
     
TOP PAGECONTACT