智能家居2.0

该博客介绍了智能家居项目,基于Java开发安卓App实现对外设控制,如灯光、人脸识别开启等,还能显示监控视频、温湿度等信息。采用工厂模式开发,用树莓派为主控,通过守护进程保证程序不退出,使用Socket网络通信实现App与外设交互。

功能描述

  1. 实现安卓App对外设的控制,如灯光、人脸识别开启等。
  2. App上能显示监控视频内容、显示温湿度、是否发生火灾等。
  3. 守护进程,保证不退出;树莓派开机自启等。

硬件图

在这里插入图片描述

项目整体思路

  1. 项目代码规范:整体采用工厂模式去对项目进行开发;主要分为指令工厂和设备工厂。
  2. 使用树莓派作为主控。
  3. 使用守护进程udev去守护智能家居进程(防止程序意外),实现系统上电就能启动项目,不需要手动运行。
  4. 基于祥云平台OCR + 树莓派摄像头实现的人脸识别。
  5. 基于Java 去开发安卓App。
  6. 使用Socket 网络通信,实现App 控制外设。

代码如下

守护进程:

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>
static bool flag = true;
void handler(int sig)
{
	printf("I got a signal %d\nI'm quitting.\n", sig);
	flag = false;
}
int judMent()
{
	FILE *file;
	char buffer[128] = {'\0'};
	char *cmd = "ps -elf |grep SmartHome|grep -v grep";
	file = popen(cmd, "r");
	fgets(buffer, 128, file);
	if(strstr(buffer, "SmartHome") != NULL){
		return 0;
	}else{
		return -1;
	}
	printf("BUFFER:%s\n",buffer);
}
int main()
{
	time_t t;
	int fd;
	//创建守护进程
	if(-1 == daemon(0, 0)){
		printf("daemon error\n");
		exit(1);
	}
	//设置信号处理函数
	struct sigaction act;
	act.sa_handler = handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	if(sigaction(SIGQUIT, &act, NULL)){
		printf("sigaction error.\n");
		exit(0);
	}
	sleep(30);
	//进程工作内容
	while(flag){
		if( judMent() == -1){
			system("/home/pi/SmartHome &");
		}
		sleep(5);
	}
	return 0;
}

人脸识别:(Camera.c)

#include "contrlDevices.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

void postUrl();
size_t readData1(void *ptr, size_t size, size_t nmemb, void *stream);
char* getFace1();
char* getPicFromOCRBase641(char *Filepath);
struct Devices* addcameraToDeviceLink(struct Devices *phead);
int cameraInit(int pinNum);
 
 
char ocrRetBuf[1024] = {'\0'};
 
size_t readData1(void *ptr, size_t size, size_t nmemb, void *stream)
//回调函数,把从后台的数据拷贝给ocrRetBuf
{
        strncpy(ocrRetBuf,ptr,1024);//ocrRetBuf接收从OCR后台返回的数据,并打印
		 printf("%s\n",ocrRetBuf);
}
 
char* getFace1()
{
	printf("pai zhao zhong\n");
	//system("raspistill -q 5 -t 1 -o image.jpg");
	system("wget  http://192.168.101.223:8080/?action=snapshot -O ./image.jpg ");
	while(access("./image.jpg",F_OK) != 0); //判断是否拍照完毕
	
	printf("paizhao wanbi\n");
	
	char* base64BufFaceRec = getPicFromOCRBase641("./image.jpg");
	//system("rm image.jpg");
	
	return base64BufFaceRec;   //返回刚才拍照的base64
}
 
char *getPicFromOCRBase641(char *Filepath)
{
        int fd;
        int filelen;
        char cmd[128]={'\0'};
 
        sprintf(cmd,"base64 %s > tmpFile",Filepath);
        system(cmd);
 
        fd=open("./tmpFile",O_RDWR);
        filelen=lseek(fd,0,SEEK_END);//计算文件大小
        lseek(fd,0,SEEK_SET);        //移动光标到头
 
        char *bufpic=(char *)malloc(filelen+2);
        memset(bufpic,'\0',filelen+2);
        read(fd,bufpic,filelen+128);    //把内容读到bufpic内
 
        system("rm -rf tmpFile");//删除这个临时文件
        close(fd);
 
 
        return bufpic; //返回bufpic这个地址
 
}
 
void postUrl()
{
        CURL *curl;
        CURLcode res;
 
        char* key    = "5xxxsWxxxGfP2pmxxxchSJ";	//翔云平台购买人脸识别后的key
        char* secret = "396xxxd33xxx487exxxf139axxx6d789";	//翔云平台购买人脸识别后的secret
        int   typeId = 21;	
        char* format = "xml";
 
        char* base64BufPic1 = getFace1();
 
        char* base64BufPic2 = getPicFromOCRBase641("lit1.jpg");
 
        int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;
        char* postString = (char* )malloc(len);
        memset(postString,'\0',len);
        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_POSTFIELDS, postString);  //指定post内容,传入参数  
                curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData1);  //回调函数readDate读取返回值
                res = curl_easy_perform(curl);          
                printf("OK:%d\n",res);
 
                if(strstr(ocrRetBuf,"是") != NULL){    //判断翔云后台返回的字符串中有没有“是”
                        printf("是同一个人\n");
                   		// 这里可以开锁,上锁的操作
                }
                else{
                        printf("不是同一个人\n");
                }
                curl_easy_cleanup(curl);
        }
 
}
 
int cameraInit(int pinNum)//该函数无用
{
	pinMode(0,OUTPUT);				
	digitalWrite(0,HIGH);
}
 
struct Devices camera = {
 
	.deviceName = "camera",
	.deviceInit = cameraInit,
	.pinNum = 0,             //此引脚号无用
	.justDoOnce = postUrl,
	.getFace = getFace1,
	.getPicFromOCRBase64 = getPicFromOCRBase641,
	.readData = readData1
 
};
 
struct Devices* addcameraToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &camera;
	}
	else{
		camera.next = phead;
		phead = &camera;
	}
}

了解到门锁的玩法,低电平 LOW开锁,HIGH:上锁,暂时不打算买这个硬件了哈,这里的思路已经调通了的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

APP端展示

  1. 显示温湿度,视频监控
  2. 按键控制灯、人脸识别开启

视频监控脚本 (start_web_video.sh)

cd ../mjpg-streamer/mjpg-streamer-experimental/

./mjpg_streamer -i "./input_raspicam.so" -o "./output_http.so -w ./www"

注意: 写好脚本后,记得给该脚本文件加上可执行权限。
在这里插入图片描述

app控制外设

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值