智能家居项目

智能家居项目

1.概述

该项目是基于香橙派(实现)的,用到的硬件模块有香橙派,继电器组,LED灯,语音模块,超声波模块,继电器,风扇,433M无线模块,蜂鸣器,火灾传感器,门锁。

该项目架构是简单工厂模式,将每一个功能写成一个文件,分控制工厂和设备工厂;用线程池放不同功能的线程

项目实现功能:
1.通过语音识别指令开关灯
2.通过网络开光灯
3.实现火灾报警
4.通过语音识别来实现人脸识别
5.遥控开启风扇(也可以开启空调(a原理一致))
6.超声波控制开关灯
7.人脸识别开关锁

2.项目代码

bathroomLight.c

#include "contrlDevices.h"

int bathroomLightOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int bathroomLightClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int bathroomLightInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices bathroomLight={
       .deviceName="bathroomLight",
       .pinNum=16,   //引脚16控制的是浴室灯
       .open=bathroomLightOpen,
       .close=bathroomLightClose,
       .deviceInit=bathroomLightInit 
};

struct Devices* addBathroomLightDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &bathroomLight;
     }
     else
     {
          bathroomLight.next=phead;
          phead=&bathroomLight; 
          return phead;
     }
}

beep.c

#include "contrlDevices.h"

int beepOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int beepClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int beepInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices beep={
       .deviceName="beep",
       .pinNum=2,   //2脚控制的是蜂鸣器
       .open=beepOpen,
       .close=beepClose,
       .deviceInit=beepInit 
};

struct Devices* addBeepDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &beep;
     }
     else
     {
          beep.next=phead;
          phead=&beep; 
          return phead;
     }
}

camera.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "contrlDevices.h"

// 数据类型别名用typedef  有分号
#define true 1 // 宏定义(替换)用define         无冒号
#define false 0

char buf[1024] = {'\0'};

size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
    strncpy(buf, ptr, 1024);
}

char *getPic(char *pic)
{
    char cmd[128] = {'\0'};
    memset(cmd, '\0', 128);
    sprintf(cmd, "base64 %s > tmpFile", pic);
    system(cmd);
    int fd = open("./tmpFile", O_RDWR);
    int filelen = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);
    char *base64Buf = (char *)malloc(filelen + 8);
    memset(base64Buf, '\0', filelen + 8);
    read(fd, base64Buf, filelen + 8);
    close(fd);
    system("rm -f tmpFile");
    return base64Buf;
}

char *getFacePic(char *pic)
{
    printf("人脸数据采集中...\n");
    system("sudo fswebcam -d /dev/video0 --no-banner -r 1280x720 -S 5 ./image.jpg");

    while (access("./image.jpg", F_OK) != 0)
        ; // 判断是否拍照完毕

    printf("数据采集完毕\n");

    char *base64BufFaceRec = getPic("./image.jpg");
    system("rm image.jpg");  // 采集完成删除,防止占内存
    return base64BufFaceRec; // 返回刚才拍照的base64
}

int postUrl() // POST请求
{
    CURL *curl;
    CURLcode res;
    char *postString = NULL;

    char faceData[4][24] = {"./ly.jpg", "./reba.jpg", "./pyy1.jpg", "end"};
    char *base64Buf1 = getPic("./pyy2.jpg");

    char *key = "LgwugBLsKaggzYt4FsCtx5";
    char *secret = "64b0c42971764ac0b7075c945a954ebc";
    int typeld = 21;
    char *format = "xml";

    int i = 0;
    int len = 0;
    while (strcmp(faceData[0 + i], "end") != 0)
    {
        char *base64Buf2 = getPic(faceData[0 + i]);
        printf("%s\n", faceData[0 + i]);
        i++;

        len = strlen(key) + strlen(secret) + strlen(format) + strlen(base64Buf1) + strlen(base64Buf2) + 128;
        printf("%d", len);
        postString = (char *)malloc(len);
        sprintf(postString, "img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s", base64Buf1, base64Buf2, key, secret, typeld, format);
        curl = curl_easy_init();
        if (curl)
        {
            curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");            // 指定cookie文件
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);                   // 指定post内容:用户信息 字段之间&连接,尝试登陆新浪邮箱
            curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);
            res = curl_easy_perform(curl); // 执行
            printf("res = %d\n", res);
            if (strstr(buf, "是") != NULL)
            {
                printf("is same people\n");
                return 2;
            }
            else
            {
                printf("is not the same people\n");
            }
            curl_easy_cleanup(curl);
        }
    }
    printf("not have this people,error!\n");
    return true;
}

struct Devices camera = {
    .deviceName = "camera",
    .url = postUrl
};

struct Devices *cameraLink(struct Devices *Phead)
{
    if (Phead == NULL)
    {
        return &camera;
    }
    else
    {
        camera.next = Phead;
        Phead = &camera;
        return Phead;
    }
}

原代码:上面的是整合后的样子

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
typedef unsigned int bool;//数据类型别名用typedef
#define true 1            //宏定义用define 就是宏替换
#define false 0
 
char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据
 
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)//回调函数,把从后台的数据拷贝给ocrRetBuf
{
        strncpy(ocrRetBuf,ptr,1024);
}
 
char* getBase64FromFile(char* filePath)
{
        char* base64Buf = NULL;
        char cmd[256] = {'\0'};
 
        sprintf(cmd,"base64 %s > tmpFile",filePath);//图片的base64流导入到文件中
        system(cmd);
 
        int fd = open("./tmpFile",O_RDWR);
        int fileLen = lseek(fd,0,SEEK_END);        //计算文件大小
        lseek(fd,0,SEEK_SET);                      
 
        base64Buf = (char* )malloc(fileLen+8);
        memset(base64Buf,'\0',fileLen+8);
 
        read(fd,base64Buf,fileLen+8);              //从文件中读取base64流到字符串 
        close(fd);
        system("rm -f tmpFile");
 
        return base64Buf;//指针变量随着子程序调用结束消失,但malloc开辟的空间地址还在,我拿到了这块地址,就能读
}
 
 
bool postUrl()       //根据文档,接口调用方法为post请求     
{
        CURL *curl;
        CURLcode res;
        
        //根据翔云平台的接口要求  分开定义,然后字符串拼接
        char* base64BufPic1 = getBase64FromFile("./jd1.jpg");//图片base64流
        char* base64BufPic2 = getBase64FromFile("./jd2.jpg");
        char* key    = "Tnf7EDJaQ1qFZkow29xxxx";
        char* secret = "66d49fdbfd4944ec93035f14ea14xxxx";
        int   typeId = 21;
        char* format = "xml"; 
        
        int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;//分配空间不够会>导致栈溢出
        char* postString = (char* )malloc(len);
        memset(postString,'\0',len);//因为postString是一个指针,不能用sizeof来计算其指向的大小
	//字符串拼接函数 	
	sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",base64BufPic1,base64BufPic2,key,secret,typeId,format);
 
        curl = curl_easy_init();
        if(curl){
                //curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");// 指定cookie缓存文件 
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);//指定post传输内容,get请求将URL和postString一次性发送
                curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData);  //回调函数读取返回值
                res = curl_easy_perform(curl);
                printf("OK:%d\n",res);
                
                if(strstr(ocrRetBuf,"否") != NULL){    //字符串检索 判断翔云后台返回的一大堆字符串中有没有“否”
                        printf("不是同一个人\n");
                }
                else{
                        printf("是同一个人\n");
                }
     
                curl_easy_cleanup(curl);
        }
        return true;
}
 
int main(void)
{
        postUrl();
        return 0;
}

fengshan.c

#include "contrlDevices.h"

int  fengOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int  fengClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int  fengInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices feng={
       .deviceName="feng",
       .pinNum=16,   //引脚16控制的是浴室灯
       .open= fengOpen,
       .close=fengClose,
       .deviceInit=fengInit 
};

struct Devices* addFengDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &feng;
     }
     else
     {
          feng.next=phead;
          phead=&feng; 
          return phead;
     }
}

fire.c

#include "contrlDevices.h"

int  fireAlarmInit(int pinNum)
{
      pinMode(pinNum,INPUT); //火灾报警器要输入,读取电平
      digitalWrite(pinNum,HIGH);  
}

int fireAlarmReadStatus(int pinNum)
{
      digitalRead(pinNum);
}

struct Devices fireAlarm={
       .deviceName="fireAlarm",
       .pinNum=6,   //引脚6控制的是火焰传感器
       .deviceInit= fireAlarmInit,
       .readStatus=fireAlarmReadStatus
};

struct Devices* addFireAlarmDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &fireAlarm;
     }
     else
     {
          fireAlarm.next=phead;
          phead=&fireAlarm; 
          return phead;
     }
}

livingroomLight.c

#include "contrlDevices.h"

int livingroomLightOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int livingroomLightClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int livingroomLightInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices livingroomLight={
       .deviceName="livingroomLight",
       .pinNum=13,   //引脚13控制的是客厅灯
       .open=livingroomLightOpen,
       .close=livingroomLightClose,
       .deviceInit=livingroomLightInit 
};

struct Devices* addLivingroomLightDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &livingroomLight;
     }
     else
     {
          livingroomLight.next=phead;
          phead=&livingroomLight; 
          return phead;
     }
}

lock.c

#include "contrlDevices.h"

int lockOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int lockClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int lockInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices lock={
       .deviceName="lock",
       .pinNum=1,   //引脚1控制的是门锁
       .open=lockOpen,
       .close=lockClose,
       .deviceInit=lockInit 
};

struct Devices* addLockDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &lock;
     }
     else
     {
          lock.next=phead;
          phead=&lock; 
          return phead;
     }
}

remote.c

#include "contrlDevices.h"

int  remoteInit(int pinNum)
{
      pinMode(pinNum,INPUT); //火灾报警器要输入,读取电平
      digitalWrite(pinNum,LOW);  
}

int remoteReadStatus(int pinNum)
{
      digitalRead(pinNum);
}

struct Devices remote={
       .deviceName="remote",
       .pinNum=14,   //引脚6控制的是火焰传感器
       .pinNum2=12,
       .deviceInit= remoteInit,
       .readStatus=remoteReadStatus
};

struct Devices* addRemoteDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &remote;
     }
     else
     {
          remote.next=phead;
          phead=&remote; 
          return phead;
     }
}

restaurantLight.c

#include "contrlDevices.h"

int restaurantLightOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int restaurantLightClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int restaurantLightInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices restaurantLight={
       .deviceName="restaurantLight",
       .pinNum=10,   //引脚10控制的是餐厅灯
       .open= restaurantLightOpen,
       .close=restaurantLightClose,
       .deviceInit=restaurantLightInit 
};

struct Devices* addRestaurantLightDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &restaurantLight;
     }
     else
     {
          restaurantLight.next=phead;
          phead=&restaurantLight; 
          return phead;
     }
}

upstairLight.c

#include "contrlDevices.h"

int upstairLightOpen(int pinNum)
{
      digitalWrite(pinNum,LOW);
}

int upstairLightClose(int pinNum)
{
      digitalWrite(pinNum,HIGH);
}

int upstairLightInit(int pinNum)
{
      pinMode(pinNum,OUTPUT);
      digitalWrite(pinNum,HIGH);  
}

struct Devices upstairLight={
       .deviceName="upstairLight",
       .pinNum=15,   //引脚15控制的是二楼灯
       .open=upstairLightOpen,
       .close=upstairLightClose,
       .deviceInit=upstairLightInit 
};

struct Devices* addUpstairLightDeviceLink(struct Devices *phead)
{
     if(phead==NULL)
     {
          return &upstairLight;
     }
     else
     {
          upstairLight.next=phead;
          phead=&upstairLight; 
          return phead;
     }
}

socketContrl.c

#include "InputCommand.h"

/*
int socketGetcommand(struct InputCommander *socketMes)
{
    int c_fd;
    int n_read;

    struct sockaddr_in c_addr;

    memset(&c_addr, 0, sizeof(struct sockaddr_in));

    // 4.accept
    int clen = sizeof(struct sockaddr_in);

    c_fd = accept(socketMes->sfd, (struct sockaddr *)&c_addr, &clen);
    if (c_fd == -1)
    {
        perror("accept");
    }

    n_read = read(c_fd, socketMes->command, sizeof(socketMes->command));
    if(n_read == -1)
    {
        perror("read");
    }
    else
    {
        printf("get message: %d ,%s\n", n_read, socketMes->command);
    }

    return n_read;
}
*/
int socketInit(struct InputCommander *socketMes, char *ipAdress, char *port)
{
    int s_fd;

    struct sockaddr_in s_addr;

    memset(&s_addr, 0, sizeof(struct sockaddr_in));

    // 1.socket
    s_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (s_fd == -1)
    {
        perror("socked");
        exit(-1);
    }

    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(socketMes->port));
    inet_aton(socketMes->ipAdress, &s_addr.sin_addr);

    // bind
    bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));

    // 3.listen
    listen(s_fd, 10);
    
    printf("socket sever listening....\n");
    socketMes->sfd = s_fd;

    return s_fd;
}

struct InputCommander socketContrl = {
    .commandName = "socketServer",
    .command = {'\0'},
    .port = "8988",
    .ipAdress = "192.168.251.50",
    .Init = socketInit,
    .log = {'\0'},
    .next = NULL
};

struct InputCommander *addSocketCommandLink(struct InputCommander *phead)
{
    if (phead == NULL)
    {
        return &socketContrl;
    }
    else
    {
        socketContrl.next = phead;
        phead = &socketContrl;
        return phead;
    }
}

voiceContrl.c

#include "InputCommand.h"


int voiceGetcommand(struct InputCommander *voice)
{
       int nread=0;

       nread=read(voice->fd,voice->command,sizeof(voice->command));
       
       return nread;              
}


int voiceInit(struct InputCommander *voice,char *ipAdress,char *port)
{
    int fd; 

    if ((fd = serialOpen (voice->deviceName, 115200)) < 0)
    {
        printf("open serial failed\n");
        return 1 ;
    }

    voice->fd=fd;
    return fd;
}


struct InputCommander voiceContrl={
      .commandName="voice", 
      .deviceName="/dev/ttyS5",
      .command={'\0'},
      .Init=voiceInit,
      .getCommand=voiceGetcommand,
      .log={'\0'},
      .next=NULL
};

struct InputCommander* addVoiceCommandLink(struct InputCommander *phead)
{
       if(phead==NULL)
       {
           return &voiceContrl;
       }
       else
       {
           voiceContrl.next=phead;
           phead=&voiceContrl;
           return phead;
       }
} 

csbContrl.c

#include "InputCommand.h"

#define  Trag 5
#define  Echo 7


double getDistance()
{
      double dis;

     struct timeval time_start;
     struct timeval time_stop;   

     pinMode(Trag,OUTPUT);
     pinMode(Echo,INPUT);
     
     digitalWrite(Trag,LOW);
     usleep(5); 
     digitalWrite(Trag,HIGH);
     usleep(10);
     digitalWrite(Trag,LOW);
     
     while(!digitalRead(Echo));
     gettimeofday(&time_start,NULL);
     while(digitalRead(Echo));
     gettimeofday(&time_stop,NULL);

     long longTime=1000000*(time_stop.tv_sec-time_start.tv_sec)+(time_stop.tv_usec-time_start.tv_usec);
    // printf("longTime=%ld\n",longTime);
     dis=(double)longTime/1000000*34000/2;

     return dis;
   
}


struct InputCommander csbContrl={
      .commandName="csb", 
      .getDistance=getDistance,
      .log={'\0'},
      .next=NULL
};

struct InputCommander* addCsbCommandLink(struct InputCommander *phead)
{
       if(phead==NULL)
       {
           return &csbContrl;
       }
       else
       {
           csbContrl.next=phead;
           phead=&csbContrl;
           return phead;
       }
} 

mainPro.c

#include 
#include 
#include 
#include 
#include "InputCommand.h"
#include "contrlDevices.h"

struct Devices *pDevicehead = NULL;
struct InputCommander *pCommandhead = NULL;
struct InputCommander *sockettmp = NULL;

static int openVoice = 0;
static int openSocket = 0;

char ocrRetBuf[1024] = {'\0'}; // 全局变量,用来接收从OCR后台返回的数据

pthread_mutex_t mutex;

// 查找设备工厂的节点
struct Devices *findDeviceByName(char *name, struct Devices *phead)
{
    struct Devices *tmp = phead;

    if (phead == NULL)
    {
        return NULL;
    }

    while (tmp != NULL)
    {
        if (strcmp(tmp->deviceName, name) == 0)
        {
            return tmp;
        }
        tmp = tmp->next;
    }

    return NULL;
}

struct InputCommander *findCommandByName(char *name, struct InputCommander *phead)
{
    struct InputCommander *tmp = phead;

    if (phead == NULL)
    {
        return NULL;
    }

    while (tmp != NULL)
    {
        if (strcmp(tmp->commandName, name) == 0)
        {
            return tmp;
        }
        tmp = tmp->next;
    }

    return NULL;
}

// 打开所有设备
void openAllDevices(struct InputCommander *cmd)
{
    struct Devices *tmp = NULL;

    pthread_mutex_lock(&mutex);

    if (strncmp("AO1", cmd->command, 3) == 0)
    {
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }
        openVoice = 1;
    }

    pthread_mutex_unlock(&mutex);
}

// 关闭所有设备
void closeAllDevices(struct InputCommander *cmd)
{
    struct Devices *tmp = NULL;

    pthread_mutex_lock(&mutex);

    if (strncmp("AC1", cmd->command, 3) == 0)
    {
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        openVoice = 0;
    }

    pthread_mutex_unlock(&mutex);
}

// 语音控制设备
void voiceCommand(struct InputCommander *cmd)
{
    struct Devices *tmp = NULL; // 设备节点

    if (strncmp("O1", cmd->command, 2) == 0) // 语音打开浴室灯
    {
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
            openVoice = 1;
        }
    }

    if (strncmp("O2", cmd->command, 2) == 0) // 语音打开二楼灯
    {
        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
            openVoice = 1;
        }
    }

    if (strncmp("O3", cmd->command, 2) == 0) // 语音打开客厅灯
    {
        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
            openVoice = 1;
        }
    }

    if (strncmp("O4", cmd->command, 2) == 0) // 语音打开餐厅灯
    {
        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
            openVoice = 1;
        }
    }

    if (strncmp("C1", cmd->command, 2) == 0) // 语音关闭浴室灯
    {
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
            openVoice = 0;
        }
    }

    if (strncmp("C2", cmd->command, 2) == 0) // 语音关闭二楼灯
    {
        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
            openVoice = 0;
        }
    }

    if (strncmp("C3", cmd->command, 2) == 0) // 语音关闭客厅灯
    {
        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
            openVoice = 0;
        }
    }

    if (strncmp("C4", cmd->command, 2) == 0) // 语音打开餐厅灯
    {
        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
            openVoice = 0;
        }
    }

    openAllDevices(cmd); // 语音打开所有灯

    closeAllDevices(cmd); // 语音关闭所有灯

    if (strncmp("OCR", cmd->command, 3) == 0)
    {
        tmp = findDeviceByName("camera", pDevicehead);
        if (tmp != NULL)
        {
            int mark = tmp->url();

            if (mark == 2)
            {
                tmp = findDeviceByName("lock", pDevicehead);
                if (tmp != NULL)
                {
                    tmp->open(tmp->pinNum);
                    printf("已经为你开门!\n");
                    delay(10);
                    tmp->close(tmp->pinNum);
                }
            }
            else
            {
                printf("人脸识别失败\n");
            }
        }
    }
}

int get_cmd_type(struct InputCommander *cmd)
{
    if (!strncmp("one", cmd->command, 3))
        return 1;
    if (!strncmp("two", cmd->command, 3))
        return 2;
    if (!strncmp("there", cmd->command, 3))
        return 3;
    if (!strncmp("four", cmd->command, 3))
        return 4;
    if (!strncmp("five", cmd->command, 3))
        return 5;
    if (!strncmp("six", cmd->command, 3))
        return 6;
    if (!strncmp("seven", cmd->command, 3))
        return 7;
    if (!strncmp("eight", cmd->command, 3))
        return 8;
    if (!strncmp("night", cmd->command, 3))
        return 9;
    if (!strncmp("ten", cmd->command, 3))
        return 10;

    return -1;
}

void socketCommand(struct InputCommander *cmd)
{
    struct Devices *tmp = NULL;
    int ret = 0;

    ret = get_cmd_type(cmd);
    printf("ret=%d\n", ret);

    switch (ret)
    {
    case 1:
        printf("open bathroomLight\n");
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
            printf("open bathroomLight success\n");
        }
        break;
    case 2:
        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }
        break;
    case 3:
        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }
        break;
    case 4:
        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }
        break;
    case 5:
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        break;
    case 6:
        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        break;
    case 7:
        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        break;
    case 8:
        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        break;
    case 9:
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }

        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->open(tmp->pinNum);
        }
        break;
    case 10:
        tmp = findDeviceByName("bathroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("upstairLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("livingroomLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }

        tmp = findDeviceByName("restaurantLight", pDevicehead);
        if (tmp != NULL)
        {
            tmp->deviceInit(tmp->pinNum);
            tmp->close(tmp->pinNum);
        }
        break;
    }
}

void *firehandler()
{

    struct Devices *firetmp = NULL;
    struct Devices *beeptmp = NULL;
    char *firename = "fireAlarm";
    char *beepname = "beep";
    int firestatus;

    while (1)
    {
        firetmp = findDeviceByName(firename, pDevicehead);
        //  printf("%s\n",firetmp->deviceName);
        if (firetmp != NULL)
        {
            firetmp->deviceInit(firetmp->pinNum);
            firestatus = firetmp->readStatus(firetmp->pinNum);
        }
        beeptmp = findDeviceByName(beepname, pDevicehead);
        // printf("%s\n", beeptmp->deviceName);
        if (beeptmp != NULL)
        {
            if (firestatus == 0)
            {
                // printf("报警\n");
                beeptmp->deviceInit(beeptmp->pinNum);
                beeptmp->open(beeptmp->pinNum);
            }
            else
            {
                // printf("安全\n");
                beeptmp->deviceInit(beeptmp->pinNum);
                beeptmp->close(beeptmp->pinNum);
            }
        }
    }
}

void *voicehandler()
{

    struct InputCommander *voicetmp = NULL;
    int nread = 0;

    voicetmp = findCommandByName("voice", pCommandhead); // 查找链表中的节点,通过名字来检索
    if (voicetmp == NULL)
    {
        printf("find voicetmp error\n");
        pthread_exit(NULL);
    }
    else
    {
        if (voicetmp->Init(voicetmp, NULL, NULL) < 0)
        {
            printf("voice init error\n");
        }

        printf("%s init success\n", voicetmp->commandName);

        while (1)
        {
            memset(voicetmp->command, 0, sizeof(voicetmp->command));
            nread = voicetmp->getCommand(voicetmp);
            if (nread == -1)
            {
                printf("no data from voice\n");
            }
            else
            {
                printf("nread:%d,get data->%s\n", nread, voicetmp->command);
                voiceCommand(voicetmp); // 语音控制设备
                openVoice=1;
            }
        }
    }
}

void *readhandler()
{
    int nread = 0;

    while (1)
    {
        memset(sockettmp->command, 0, sizeof(sockettmp->command));
        nread = read(sockettmp->fd, sockettmp->command, sizeof(sockettmp->command));
        if (nread == -1)
        {
            printf("no data from socket\n");
        }
        else if (nread == 0) // 防止客户端退出,服务端崩掉
        {
            printf("client out\n");
            break;
        }
        else
        {
            printf("get data:%s\n", sockettmp->command);
            socketCommand(sockettmp);
            openSocket=1;
        }
    }
}

void *sockethandler()
{
    int c_fd;

    pthread_t read_t;

    struct sockaddr_in c_addr;

    memset(&c_addr, 0, sizeof(struct sockaddr_in));

    int clen = sizeof(struct sockaddr_in);

    sockettmp = findCommandByName("socketServer", pCommandhead); // 查找链表中的节点,通过名字来检索
    if (sockettmp == NULL)
    {
        printf("find voicetmp error\n");
        pthread_exit(NULL);
    }

    else
    {
        if (sockettmp->Init(sockettmp, NULL, NULL) < 0)
        {
            printf("perror:\n");
        }
        printf("%s init success\n", sockettmp->commandName);

        while (1)
        {

            c_fd = accept(sockettmp->sfd, (struct sockaddr *)&c_addr, &clen);
            if (c_fd == -1)
            {
                perror("accept");
            }
            sockettmp->fd = c_fd;
            pthread_create(&read_t, NULL, readhandler, NULL);
        }
    }
}

void *remotehandler()
{
    struct Devices *remotetmp = NULL;
    struct Devices *fengtmp = NULL;
    int onstatus;
    int offstatus;

    while (1)
    {
        remotetmp = findDeviceByName("remote", pDevicehead);
        //  printf("%s\n",firetmp->deviceName);
        if (remotetmp != NULL)
        {
            remotetmp->deviceInit(remotetmp->pinNum);
            onstatus = remotetmp->readStatus(remotetmp->pinNum);

            remotetmp->deviceInit(remotetmp->pinNum2);
            offstatus = remotetmp->readStatus(remotetmp->pinNum2);
        }
        fengtmp = findDeviceByName("feng", pDevicehead);
        // printf("%s\n", beeptmp->deviceName);
        if (fengtmp != NULL)
        {
            if (onstatus == 1)
            {
                // printf("开启\n");
                fengtmp->deviceInit(fengtmp->pinNum);
                fengtmp->open(fengtmp->pinNum);
            }

            if (offstatus == 0)
            {
                // printf("关闭\n");
                fengtmp->deviceInit(fengtmp->pinNum);
                fengtmp->close(fengtmp->pinNum);
            }
        }
    }
}

void *openhandler()
{
    struct Devices *tmp = NULL;

    tmp = findDeviceByName("bathroomLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->open(tmp->pinNum);
    }

    tmp = findDeviceByName("upstairLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->open(tmp->pinNum);
    }

    tmp = findDeviceByName("livingroomLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->open(tmp->pinNum);
    }

    tmp = findDeviceByName("restaurantLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->open(tmp->pinNum);
    }

     usleep(500000);
}

void *closehandler()
{
    struct Devices *tmp = NULL;

    tmp = findDeviceByName("bathroomLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->close(tmp->pinNum);
    }

    tmp = findDeviceByName("upstairLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->close(tmp->pinNum);
    }

    tmp = findDeviceByName("livingroomLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->close(tmp->pinNum);
    }

    tmp = findDeviceByName("restaurantLight", pDevicehead);
    if (tmp != NULL)
    {
        tmp->deviceInit(tmp->pinNum);
        tmp->close(tmp->pinNum);
    }

    usleep(500000);
}

void *csbhandler()
{
    struct InputCommander *csbtmp = NULL;
    struct Devices *tmp = NULL;

    pthread_t open_t;
    pthread_t close_t;

    double dis = 0;

    csbtmp = findCommandByName("csb", pCommandhead); // 查找链表中的节点,通过名字来检索
    if (csbtmp == NULL)
    {
        printf("find csbtmp error\n");
        pthread_exit(NULL);
    }

    else
    {
        printf("find csb success\n");
        while (1)
        {
            dis = csbtmp->getDistance();
            if (dis < 10)
            {
                printf("dis=%lf\n", dis);
                pthread_create(&open_t, NULL, openhandler, NULL);
              //  sleep(5);

                //pthread_exit(NULL);
            }
            else
            {
                printf("dis=%lf\n", dis);
                pthread_create(&close_t, NULL, closehandler, NULL);
                
            }
        }
    }
}

int main()
{
    // char name[128] = {0};

    pthread_t fire_t;
    pthread_t voice_t;
    pthread_t socket_t;
    pthread_t remote_t;
    pthread_t csb_t;
    pthread_t oled_t;

    if (wiringPiSetup() == -1)
    {
        printf("init error\n");
        return -1;
    }

    // 指令工厂初始化
    pCommandhead = addVoiceCommandLink(pCommandhead); // 把对应指令节点加入到指令工厂
    pCommandhead = addSocketCommandLink(pCommandhead);
    pCommandhead = addCsbCommandLink(pCommandhead);

    // 设备工厂初始化
    pDevicehead = addBathroomLightDeviceLink(pDevicehead); // 把对应的设备节点加入到设备工厂
    pDevicehead = addUpstairLightDeviceLink(pDevicehead);
    pDevicehead = addLivingroomLightDeviceLink(pDevicehead);
    pDevicehead = addRestaurantLightDeviceLink(pDevicehead);
    pDevicehead = addFireAlarmDeviceLink(pDevicehead);
    pDevicehead = addBeepDeviceLink(pDevicehead);
    pDevicehead = addFengDeviceLink(pDevicehead);
    pDevicehead = addRemoteDeviceLink(pDevicehead);
    pDevicehead = cameraLink(pDevicehead);
    pDevicehead = addLockDeviceLink(pDevicehead);

    pthread_mutex_init(&mutex, NULL);

    // 语音线程
    pthread_create(&voice_t, NULL, voicehandler, NULL); // 语音控制设备

    // socket线程
    pthread_create(&socket_t, NULL, sockethandler, NULL); // 网络控制设备

    // 火灾报警线程
    pthread_create(&fire_t, NULL, firehandler, NULL); // 火灾报警

    // 风扇线程
    pthread_create(&remote_t, NULL, remotehandler, NULL);

    // 超声波线程
    pthread_create(&csb_t, NULL, csbhandler, NULL);

    // oled线程
    pthread_create(&oled_t,NULL,oledhandler,NULL);

    pthread_join(fire_t, NULL);
    pthread_join(voice_t, NULL);
    pthread_join(socket_t, NULL);
    pthread_join(remote_t, NULL);
    pthread_join(csb_t, NULL);
    
    pthread_mutex_destroy(&mutex);

    return 0;
}

contrlDevices.h

#include
#include

struct Devices
{
    char deviceName[128]; //设备名
    int status; //设备状态
    int pinNum;
    int pinNum2; //第二个引脚

    int (*open)(int pinNum); //打开设备
    int (*close)(int pinNum); //关闭设备
    int (*deviceInit)(int pinNum); //设备初始化 

    int (*readStatus)(int pinNum); //读取设备状态
    int (*chageStatus)(int status); //改变设备状态
    int (*url)();

    struct Devices* next;
};

struct Devices* addBathroomLightDeviceLink(struct Devices *phead);
struct Devices* addUpstairLightDeviceLink(struct Devices *phead);
struct Devices* addLivingroomLightDeviceLink(struct Devices *phead);
struct Devices* addRestaurantLightDeviceLink(struct Devices *phead);
struct Devices* addFireAlarmDeviceLink(struct Devices *phead);
struct Devices* addBeepDeviceLink(struct Devices *phead);
struct Devices* addFengDeviceLink(struct Devices *phead);
struct Devices* addLockDeviceLink(struct Devices *phead);
struct Devices* addRemoteDeviceLink(struct Devices *phead);
struct Devices *cameraLink(struct Devices *Phead);
struct Devices* addLockDeviceLink(struct Devices *phead);

InputCommand.h

#include
#include
#include
#include
#include
#include
#include
#include          /* See NOTES */
#include
#include
#include
#include
#include 

#define one    1
#define two    2
#define there  3
#define four   4
#define five   5
#define six    6
#define seven  7
#define eight  8
#define night  9
#define ten   10

struct InputCommander
{
     char commandName[128]; //控制设备的指令名
     char deviceName[128];
     char command[128];  //发送的指令


     int (*Init)(struct InputCommander *name,char *ipAdress,char *port); //初始化语音和网络
     int (*getCommand)(struct InputCommander *cmd); //读取指令
     double (*getDistance)();
     char log[1024]; //日志
     char port[12];
     char ipAdress[32];
     int sfd;
     int fd;
    

     struct InputCommander  *next;
};

struct InputCommander* addVoiceCommandLink(struct InputCommander *phead);
struct InputCommander *addSocketCommandLink(struct InputCommander *phead);
struct InputCommander* addCsbCommandLink(struct InputCommander *phead);

3.总结

通过这个项目,我学习到了第三方库的使用,分析语音sdk和工厂模式,也得到了综合锻炼。

你可能感兴趣的:(智能家居)