【毕设级项目】基于嵌入式的智能家居控制板(完整工程资料源码)

news2024/11/19 15:11:14

基于嵌入式的智能家居控制板演示效果

基于嵌入式的智能家居控制板

前言:

        随着科技的不断进步,物联网技术得到了突飞猛进的发展。智能家居是物联网技术的典型应用领域之一。智能家居系统将独立家用电器、安防设备连接成一个具有思想的整体,实现家居设备的智能管理和远程监控。

        本项目系统设计与实现使用Keil、vscode和qt三种集成开发工具实现代码的编写与调试。家居设备之间的数据通信采用TCP/IP网络协议,保证数据传输稳定可靠。使用嵌入式平台作为核心控制器能够提高整个系统的稳定性,数据传输采用TCP/IP协议能够很好解决目前一些系统中存在的数据传输不稳定问题。基于嵌入式的方式能够降低智能家居系统的成本,大大降低市场中由于智能家居价格较高无法普及现象,使智能家居能够走入普通百姓家中。

关键字:智能家居系统,嵌入式技术,qt

目录:

基于嵌入式的智能家居控制板演示效果

前言:

目录:

一、系统方案:

1.1 项目背景

1.2 项目目标

1.3 需求分析

1.4 项目设计

1.5 实施计划

二、功能与指标

2.1 功能

2.2 主要指标

三、实现原理

3.1 PCB原理图

3.2 软件界面

​编辑 ​编辑

3.3 Stm32端源代码

 3.4 QT端上位机源代码

 3.5 web服务器端源代码

四、硬件框图

五、流程框图

六、系统测试方案

6.1 功能测试

6.2 用户界面测试 

6.3 兼容性测试

七、测试设备

 八、测试数据

九、结果分析 

十、实现功能

十一、特色

11.1 电路集成

11.2.火灾警报:

11.3.网页控制:

11.4.APP开发:

11.5.单片机控制:

11.6.语音交互:

11.7.人脸识别:

十二、资源获取链接:毕设&大创&项目&竞赛-基于嵌入式的智能家居控制板演示效果.zip资源-CSDN文库

成品展示:

资源详情:

12.1 资源包目录:

 12.2 源代码

12.3 手机app打包程序

 12.4 数据​编辑

12.5 用户手册

        总结:


一、系统方案:

1.1 项目背景

        2019年以来,随着科学的进步,人工智能行业也是飞速的发展,而以人工智能为基础的智能家居也是年年创下新高。人工智能“大跃进”后,会真正攻陷人类的家庭,智能家居届时也许会被称之为“AI家居”。人类正在逐步失去耐心,从社会运作到家庭生活,都将需要各种设备来承载“短平快”的需求。当“AI家居”的智商与能力足以成为这种载体时,新一代网络打破信息孤岛,大数据也将有效信息加以利用,届时人类的生活将会呈现出质的变化。从目前的智能语音“全面入侵”智能家居设备来看,这将是耶和华的真理。2022年智能家居行业该如何发展?——人工智能+物联网。

        从2000年智能家居行业被提出开始,近22年来的智能家居行业,每年都有不同的角色参与进来,许多都是极具时代特征的新角色,其主要集中在感知、判断、动作三个控制逻辑层面,多年来,产业链各阵营都在努力实现多设备互联的集中控制化,目前产业链中的各模块已然齐全,芯片、解决方案、产品、集成安装、云等一应俱全,各角色定位划分非常清晰。所以说,目前整个智能家居产业链的纵向阶段已经完成,在全面控制的当下也代表着传统智能化升级、万物互联,日新月异的智能化历史规律,已经将智能家居推向基于AI技术的AIOT新时代。

        因此智能家居项目是一个具有极大潜力的项目,并且值得我们深入挖掘与研究,在项目的开发中,不仅能够提升个人的专业知识水平,更能够使我们了解当前行业发展的水平,在实践中创新、在实践中进步。

1.2 项目目标

        智能家居嵌入式系统控制,它利用先进的计算机技术、嵌入式系统技术、网络通信技术和传感器技术等,将家中的各种设备(照明系统、环境控制系统、安防系统、智能家电等)有机地连接到一起。通过手机或网页控制家中各种设备,为大家的生活带来很多便利。

        火警、烟警、有毒气体泄露报警。门阀控功能:水、煤气等电动阀的通/断控制。室内空气温度、湿度等的自动调节功能。洗衣机、热水器等各类家用电器开/关控制。声音和光电报警,远程控制及报警等。智能家居嵌入式系统控制,让用户采用更方便的手段来管理家庭设备,比如,通过无线遥控器、电话、互联或者语音识别控制家用设备,根据场景设定设备动作,使多个设备形成联动。智能家居内的各种设备相互间可以通讯,不需要用户指挥也能根据不同的状态互动运行,从而在最大程度上给用户提供高效、便利、舒适与安全的居住环境和工作环境。

1.3 需求分析

        中国的市场,随着新企业的不断加入,竞争变得更加激烈,同时消费者需求的多样化和个性化,使得任何一个新进入该行业的企业所面临的市场广阔而又复杂。中东部地区比较发达,人们观念比较先进。而西北部就相对落后。而中端市场没有明显的特点,虽然品牌较多,但是没有较突出的优势。至于消费群体来说,人们的理念越来越先进,个性也越来越鲜明。现在的大学生即将成为将来社会的主导力量,是消费群体中不可忽视的主导者。

        技术含量高、运行稳定性好,满足顾客的需求,另外,通讯系统、增值服务的推广和销售面对的大多是重点大客户,而智能家居控制的销售却要面对为数众多、千差万别的消费者。

        随着科技的发展和社会的进步,人们走进了智能化的生活,扫码支付、网上购物、呼叫快车等技术手段都得到了广泛的应用,人们的衣食住行都越来越方便快捷。智能家居作为人们生活智能化的重要代表,近年来得到了迅猛发展,从扫地机器人、智能洗碗机、智能冰箱等智能机器,到智能照明、智能感知、网络通信、家庭影音等智能系统,智能家居覆盖了人们的日常生活。

        所以,如果说年轻人追求时尚,便捷的生活方式。老年人则是,智能家居则是刚性需求。毕竟老年人行动不便,更需要高科技的辅助。智能联网设备使家更安全,使日常生活更轻松。

1.4 项目设计

        嵌入式智能家居控制板通过无线, WIFI,局域网的方式,控制家用电器控制,家庭安防控制,家庭监视监测控制,家庭信息控制,栋(户)门口机可视对讲,家庭娱乐控制,家庭环境控制等。同时也可以通过APP远程控制嵌入式智能家居控制板,来控制家居各种电器及相关设备场景监控。手机终端也可以通过远程浏览WAP网页,来控制家居各种电器及相关设备场景监控。

1.5 实施计划

(1)投入和目前,嵌入式智能家居控制板通过无线, WIFI,局域网的方式,可控制家用电器,家庭环境控制等控制。下一阶段,将增加其他功能,家庭安防系统,家庭娱乐环境等系统。

(2)嵌入式智能家居控制板已完全可以在手机app界面进行控制,未发生其他情况。下一阶段,将完善手机app的界面,及功能,将其他功能添加进去。

(3)嵌入式智能家居控制板在网页端的控制已初步形成,未来一段时间将继续完善网页的界面视图,添加与手机app相同的功能,更好的让客户操作简单,简单明了。

二、功能与指标

2.1 功能

(1)本项目在服务器上选择部署在阿里云服务器,使用epoll多线程的服务端编程与http协议,将STM32单片机,APP,网页控制连接上服务器,从而实现远程数据通信与控制,使人们能够无视距离的限制来查看并控制自己的家居,搭载了语音信息交互,使得用户可以在家里更方便地操作家居,查看当前的天气,温湿度,网络时间等情况,人脸识别功能的加入,提高了控制板的智能化,当客人或者用户没带钥匙时,可以通过人脸信息打开大门,通过K210的深度学习神经网络,增加了数据的可信度,放置误识别导致的错误。

(2)电路集成化思路的加入,使得智能家居控制系统板减少了杜邦线的使用,增加了电路的稳定性与可靠性。通过将多种智能控制方式集于一体 ,实现智能管理与控制,真正让用户真切感知到智能家居的强大,感受到人工智能时代智能化对人们日常生活提供的便利。

2.2 主要指标

(1)手机app搭载基于阿里云服务器,基于epoll多线程编程,通过QT开发APP上位机。

(2)控制面板服务器基于http协议实现数据传输,通过AD软件将STM32最小系统板,温度传感器,火焰传感器,湿度传感器,ESP8266,无源蜂鸣器等模块集成在一块PCB板上。

(3)网页控制,通过连接http通信协议的服务器实现的web的网络通信,利用Visual Studio 软件编写web代码。

三、实现原理

        采用无线wifi模块,控制家用电器,智能灯控开关,自动窗帘控制器,无线通用报警盒,无线紧 急按钮,智能调光开关等。利用嵌入Linux操作系统,采用linux2.6.21内核,支持多种网络应用。处理器采用,S3C6410X是基于ARM1176JZF-S核地用于手持、移动等终端设备的通用处理器。Internet 远程TCP/IP控制技术,采用了国际通用标准TCP/IP协议。B/S工作模式下,用户只需在客户端装有通用的浏览器,就可以向网络上的某一WEB服务器提出请求。WEB服务器对用户身份进行验证后,接受用户的请求,执行相应的扩展应用程序与数据库服务器进行连接,数据库服务器接收WEB服务器对数据操作请求后,实现用户对数据查询、更改、更新等功能,把运行结果提交给WEB服务器。WEB服务器利用HTTP协议把运行结果通过主页形式传到客户端,客户机接收传来的主页文件,并把它显示在WEB浏览器上。手机app,采用Internet 远程TCP/IP控制技术,采用了国际通用标准TCP/IP协议。B/S工作模式下,用户手机客服端便可以控制。

3.1 PCB原理图

3.2 软件界面

 

3.3 Stm32端源代码

#include "stm32f4xx.h"
#include "./usart/bsp_debug_usart.h"
#include "./adc/bsp_adc.h"
#include "./led/bsp_led.h"
#include <stdio.h>
#include "bsp_general_tim.h"
#include "obj_fire.h"  
#include "obj_dht11.h"
#include "./systick/bsp_SysTick.h"
#include "obj_esp8266.h"
#include "string.h"
#include "obj_door.h"
extern int TData[7]; 

// ADC转换的电压值通过MDA方式传到SRAM
extern __IO uint16_t ADC_ConvertedValue[RHEOSTAT_NOFCHANEL];

// 局部变量,用于保存转换计算后    的电压值 	 
float ADC_ConvertedValueLocal[RHEOSTAT_NOFCHANEL]={0}; 
int tran;
char Stq[7]="\0";
extern uint8_t DataBuf[5];
int dk=0,jud=0;
int zt=0;
extern char js;
int connect_statue = 0;		//0为未连接 1为连上树莓派 2为连上天气	3为连上时间
char Datax[40]="\0",tqx[15]="\0";
char sdu[5]="\0";
void send_sd(int x){
	printf("n0.val=%d\xff\xff\xff",x);
	sdu[0] = '%';
	sdu[1] = '\0';
	sdu[2] = '\0';
	sdu[3] = '\0';
	sdu[4] = '\0';
	if(x<10){
		sdu[0]=x+48;
		sdu[1]='%';
	}
	else if(x <100){
		sdu[0]=(x/10)+48;
		sdu[1]=(x%10)+48;
		sdu[2]='%';
	}
	else{
		sdu[0]=(x/100)+48;
		sdu[1]=(x%100/10)+48;
		sdu[2]=(x%10)+48;
		sdu[3]='%';
	}
	Usart_SendString(ESP8266_USART,sdu);
}
int main(void)
{	
	int book,i;
	SysTick_Init(0);
  /*初始化USART 配置模式为 115200 8-N-1,中断接收*/
	Debug_USART_Config();
	ESP8266_USART_Config();
	HMI_USART_Config();
	LED_GPIO_Config();
	TIMx_Configuration();
	FIRE_GPIO_Config();
	DHT11_GPIO_Config();
	DOOR_Configuration();
	
	LED_RGBOFF
	
//	while(1){	
//		book = get_dht11_data();
//		if(book ==1){
//			printf("温度:%d  湿度:%d  ",DataBuf[2],DataBuf[0]);
//		}
//		else{
//			printf("no\n");
//		}
//		printf("MQ-6=%d 火焰=%d\n",read_mq(),read_fire());
//		delay_ms(1500);
//	}
//	Usart_SendString(DEBUG_USART,"Test Start\n");
delay_ms(200);
//	tran = 0;
//	connect_time();
//	delay_ms(500);
	//Usart_SendByte(DEBUG_USART,'1');
	tran = 0;
	connect_tq();
	delay_ms(500);
	while(tran == 0);
	tran = 0;
	connect_smp();
	delay_ms(1200);

	//Usart_SendByte(DEBUG_USART,'3');			//连接树莓派
//	for(i=0;i<25;i++){
//		Usart_SendByte(DEBUG_USART,Datax[i]);
//	}
//	Usart_SendByte(DEBUG_USART,'\n');
//	for(i=0;i<5;i++){
//		Usart_SendByte(DEBUG_USART,tqx[i]);
//	}
	Usart_SendByte(DEBUG_USART,'\n');		
//	Data_trans();
//	printf("n2.val=%d\xff\xff\xff",TData[2]);
//	printf("n3.val=%d\xff\xff\xff",TData[0]);
//	printf("n4.val=%d\xff\xff\xff",TData[1]);
//	printf("n5.val=%d\xff\xff\xff",TData[3]);
//	printf("n6.val=%d\xff\xff\xff",TData[4]);
//	printf("ts=%d\xff\xff\xff",TData[5]);
	delay_ms(50);
	printf("t31.txt=\"已连接\"\xff\xff\xff");
	delay_ms(50);
while(1){
	
	book = get_dht11_data();
	if(book ==1){
			send_sd(DataBuf[0]);//发送湿度
		delay_ms(500);
			Send_Temp();//发送温度
	}
	//connect_smp();
	delay_ms(500);
	get_tq();
	if(strcmp(Stq,"Sun") == 0||strcmp(Stq,"Cle") ||strcmp(Stq,"Lig") == 0){
		Usart_SendString(ESP8266_USART,"Q");
		Usart_SendString(HMI_USART,"t18.txt=\"晴天\"\xff\xff\xff");
	}
	else if(strcmp(Stq,"Clo") == 0){
		Usart_SendString(ESP8266_USART,"D");
		Usart_SendString(HMI_USART,"t18.txt=\"多云\"\xff\xff\xff");
	}
	else if(strcmp(Stq,"Sno") == 0){
		Usart_SendString(ESP8266_USART,"X");
		Usart_SendString(HMI_USART,"t18.txt=\"雪天\"\xff\xff\xff");
	}
	else if(strcmp(Stq,"Rai") == 0){
		Usart_SendString(ESP8266_USART,"Y");
		Usart_SendString(HMI_USART,"t18.txt=\"雨天\"\xff\xff\xff");
	}			//发送天气情况	
	delay_ms(500);
	if(read_fire() == 1){
		Usart_SendString(ESP8266_USART,"O");
		TIM_SetCompare2(GENERAL_TIM, 79);
		Usart_SendString(HMI_USART,"t20.txt=\"危险\"\xff\xff\xff");
	}
	else if(read_fire() == 0){
		Usart_SendString(ESP8266_USART,"N");
		TIM_SetCompare2(GENERAL_TIM, 0);
		Usart_SendString(HMI_USART,"t20.txt=\"安全\"\xff\xff\xff");

	}
	delay_ms(500);
	Data_trans();		//时间转换
	Usart_SendString(ESP8266_USART,"y\n");
}
while(1);
}



/*********************************************END OF FILE**********************/

 3.4 QT端上位机源代码

#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QDebug>
#include <QThread>
#include <QMessageBox>
#include <QCloseEvent>
#include <QDebug>
#include <QCommandLinkButton>
#include "widget.h"
#include <QPicture>
#include <QIcon>

#include <QPainter>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{

    this->setWindowIcon(QIcon(":/res/favicon.ico"));

    ui->setupUi(this);
    QPixmap icon1(":/res/favicon.ico");
    ui->pushButton->setIcon(icon1);


    this->setFixedSize(this->width(), this->height());
    qDebug()<<this->width()<<' '<<this->height();
    setWindowTitle("你好慧生活");
    m = new QWidget();
    m->setWindowIcon(QIcon(":/res/favicon.ico"));

    QPixmap *pax = new QPixmap(":/picture/gtx.jpg");
    ui->label->setScaledContents(true);
    ui->label->setPixmap(*pax);

    QPixmap *pax1 = new QPixmap(":/picture/xbmu.jpg");
    ui->label_9->setScaledContents(true);
    ui->label_9->setPixmap(*pax1);

    QPixmap *pax2 = new QPixmap(":/picture/DZSJ.jpg");
    ui->label_11->setScaledContents(true);
    ui->label_11->setPixmap(*pax2);


    ui->radioButton_2->setChecked(true);
    ui->radioButton_4->setChecked(true);
    ui->radioButton_6->setChecked(true);
    ui->radioButton_8->setChecked(true);
    ui->radioButton_9->setChecked(true);

    tcpsocket = new QTcpSocket();


    //服务器ip地址
    tcpsocket ->connectToHost("124.223.213.54",987);
    connect(tcpsocket,&QTcpSocket::connected,[=](){
        tcpsocket->write("w\n");
    });
    connect(tcpsocket,&QTcpSocket::readyRead,[=](){
        QByteArray arry = tcpsocket->readAll();
        qDebug()<<arry;
        if(strcmp(arry,"L0")==0){
            ui->radioButton->setChecked(true);
        }
        else if(strcmp(arry,"L1")==0){
            ui->radioButton_2->setChecked(true);
        }
        if(strcmp(arry,"L2")==0){
            ui->radioButton_3->setChecked(true);
        }
        else if(strcmp(arry,"L3")==0){
            ui->radioButton_4->setChecked(true);
        }
        if(strcmp(arry,"L4")==0){
            ui->radioButton_5->setChecked(true);
        }
        else if(strcmp(arry,"L5")==0){
            ui->radioButton_6->setChecked(true);
        }
        if(strcmp(arry,"L6")==0){
            ui->radioButton_7->setChecked(true);
        }
        else if(strcmp(arry,"L7")==0){
            ui->radioButton_8->setChecked(true);
        }
        else if(strcmp(arry,"f0")==0){
            ui->radioButton_9->setChecked(true);
        }
        else if(strcmp(arry,"f1")==0){
            ui->radioButton_10->setChecked(true);
        }
        else if(strcmp(arry,"f2")==0){
            ui->radioButton_11->setChecked(true);
        }
        else if(strcmp(arry,"f3")==0){
            ui->radioButton_12->setChecked(true);
        }




        //火灾警报
        if(strcmp(arry,"O")==0){
            Fire_Data->setText("危险");
        }
        else if(strcmp(arry,"N")==0){
            Fire_Data->setText("安全");
        }

        //湿度检测
        if(strcmp(arry,"0%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"1%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"2%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"3%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"4%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"5%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"6%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"7%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"8%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"9%")==0){
            DHT_Data->setText(arry);
        }
        if(strcmp(arry,"10%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"11%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"12%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"13%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"14%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"15%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"16%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"17%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"18%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"19%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"20%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"21%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"22%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"23%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"24%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"25%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"26%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"27%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"28%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"29%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"30%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"31%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"32%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"33%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"34%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"35%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"36%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"37%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"38%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"39%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"40%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"41%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"42%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"43%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"44%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"45%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"46%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"47%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"48%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"49%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"50%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"51%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"52%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"53%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"54%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"55%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"56%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"57%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"58%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"59%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"60%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"61%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"62%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"63%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"64%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"65%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"66%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"67%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"68%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"69%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"70%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"71%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"72%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"73%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"74%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"75%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"76%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"77%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"78%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"79%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"80%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"81%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"82%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"83%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"84%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"85%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"86%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"87%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"88%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"89%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"90%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"91%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"92%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"93%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"94%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"95%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"96%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"97%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"98%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"99%")==0){
            DHT_Data->setText(arry);
        }
        else if(strcmp(arry,"100%")==0){
            DHT_Data->setText(arry);
        }

        //天气检测
        if(strcmp(arry,"Q")==0){
            Sun_Data->setText("晴天");
        }
        else if(strcmp(arry,"Y")==0){
            Sun_Data->setText("雨天");
        }
        else if(strcmp(arry,"D")==0){
            Sun_Data->setText("多云");
        }
        else if(strcmp(arry,"X")==0){
            Sun_Data->setText("雪天");
        }
        //温度检测
        if(strcmp(arry,"-13")==0){
            Tempature_Data->setText("-13°");
        }
        if(strcmp(arry,"-12")==0){
            Tempature_Data->setText("-12°");
        }
        if(strcmp(arry,"-11")==0){
            Tempature_Data->setText("-11°");
        }
        if(strcmp(arry,"-10")==0){
            Tempature_Data->setText("-10°");
        }
        if(strcmp(arry,"-9")==0){
            Tempature_Data->setText("-9°");
        }
        if(strcmp(arry,"-8")==0){
            Tempature_Data->setText("-8°");
        }
        if(strcmp(arry,"-7")==0){
            Tempature_Data->setText("-7°");
        }
        if(strcmp(arry,"-6")==0){
            Tempature_Data->setText("-6°");
        }
        if(strcmp(arry,"-5")==0){
            Tempature_Data->setText("-5°");
        }
        if(strcmp(arry,"-4")==0){
            Tempature_Data->setText("-4°");
        }
        if(strcmp(arry,"-3")==0){
            Tempature_Data->setText("-3°");
        }
        if(strcmp(arry,"-2")==0){
            Tempature_Data->setText("-2°");
        }
        if(strcmp(arry,"-1")==0){
            Tempature_Data->setText("-1°");
        }
        if(strcmp(arry,"0")==0){
            Tempature_Data->setText("0°");
        }
        else if(strcmp(arry,"1")==0){
            Tempature_Data->setText("1°");
        }
        else if(strcmp(arry,"2")==0){
            Tempature_Data->setText("2°");
        }
        else if(strcmp(arry,"3")==0){
            Tempature_Data->setText("3°");
        }
        else if(strcmp(arry,"4")==0){
            Tempature_Data->setText("4°");
        }
        else if(strcmp(arry,"5")==0){
            Tempature_Data->setText("5°");
        }
        else if(strcmp(arry,"6")==0){
            Tempature_Data->setText("6°");
        }
        else if(strcmp(arry,"7")==0){
            Tempature_Data->setText("7°");
        }
        else if(strcmp(arry,"8")==0){
            Tempature_Data->setText("8°");
        }
        else if(strcmp(arry,"9")==0){
            Tempature_Data->setText("9°");
        }
        else if(strcmp(arry,"10")==0){
            Tempature_Data->setText("10°");
        }
        else if(strcmp(arry,"11")==0){
            Tempature_Data->setText("11°");
        }
        else if(strcmp(arry,"12")==0){
            Tempature_Data->setText("12°");
        }
        else if(strcmp(arry,"13")==0){
            Tempature_Data->setText("13°");
        }
        else if(strcmp(arry,"14")==0){
            Tempature_Data->setText("14°");
        }
        else if(strcmp(arry,"15")==0){
            Tempature_Data->setText("15°");
        }
        else if(strcmp(arry,"16")==0){
            Tempature_Data->setText("16°");
        }
        else if(strcmp(arry,"17")==0){
            Tempature_Data->setText("17°");
        }
        else if(strcmp(arry,"18")==0){
            Tempature_Data->setText("18°");
        }
        else if(strcmp(arry,"19")==0){
            Tempature_Data->setText("19°");
        }
        else if(strcmp(arry,"20")==0){
            Tempature_Data->setText("20°");
        }
        else if(strcmp(arry,"21")==0){
            Tempature_Data->setText("21°");
        }
        else if(strcmp(arry,"22")==0){
            Tempature_Data->setText("22°");
        }
        else if(strcmp(arry,"23")==0){
            Tempature_Data->setText("23°");
        }
        else if(strcmp(arry,"24")==0){
            Tempature_Data->setText("24°");
        }
        else if(strcmp(arry,"25")==0){
            Tempature_Data->setText("25°");
        }
        else if(strcmp(arry,"26")==0){
            Tempature_Data->setText("26°");
        }
        else if(strcmp(arry,"27")==0){
            Tempature_Data->setText("27°");
        }
        else if(strcmp(arry,"28")==0){
            Tempature_Data->setText("28°");
        }
        else if(strcmp(arry,"29")==0){
            Tempature_Data->setText("29°");
        }
        else if(strcmp(arry,"30")==0){
            Tempature_Data->setText("30°");
        }
        else if(strcmp(arry,"31")==0){
            Tempature_Data->setText("31°");
        }
        else if(strcmp(arry,"32")==0){
            Tempature_Data->setText("32°");
        }
        else if(strcmp(arry,"33")==0){
            Tempature_Data->setText("33°");
        }
        else if(strcmp(arry,"34")==0){
            Tempature_Data->setText("34°");
        }
        else if(strcmp(arry,"35")==0){
            Tempature_Data->setText("35°");
        }
        else if(strcmp(arry,"36")==0){
            Tempature_Data->setText("36°");
        }
        else if(strcmp(arry,"37")==0){
            Tempature_Data->setText("37°");
        }
        else if(strcmp(arry,"38")==0){
            Tempature_Data->setText("38°");
        }
        else if(strcmp(arry,"39")==0){
            Tempature_Data->setText("39°");
        }
        else if(strcmp(arry,"40")==0){
            Tempature_Data->setText("40°");
        }
        else if(strcmp(arry,"41")==0){
            Tempature_Data->setText("41°");
        }
        else if(strcmp(arry,"42")==0){
            Tempature_Data->setText("42°");
        }
        else if(strcmp(arry,"43")==0){
            Tempature_Data->setText("43°");
        }
        else if(strcmp(arry,"44")==0){
            Tempature_Data->setText("44°");
        }
        else if(strcmp(arry,"45")==0){
            Tempature_Data->setText("45°");
        }
    });
    m->hide();
    Environment();
}
void Widget:: Environment(){


    m->setFixedSize(1006, 1050);
    m->setWindowTitle("慧生活");


    Tempature_Text = new QLabel(m);
    Tempature_Data = new QLabel(m);
    Sun_Text = new QLabel(m);
    Sun_Data = new QLabel(m);
    Gas_Text = new QLabel(m);
    Gas_Data = new QLabel(m);
    DHT_Text = new QLabel(m);
    DHT_Data = new QLabel(m);
    Fire_Text = new QLabel(m);
    Fire_Data = new QLabel(m);
    Title = new QLabel(m);
    Picture = new QLabel(m);
    Test = new QLabel(m);
    XBMU = new QLabel(m);
    DZSJ = new QLabel(m);
    Next = new QCommandLinkButton("控制面板",m);

    Show_DHT();
    Show_picture();
    Show_Title();
    Show_Sun();
    Show_Tempature();
    Show_Fire();


    Next->setGeometry(830,700,170,71);
    Next->show();
    connect(Next,&QCommandLinkButton::clicked,[=](){
        this->show();
        m->hide();
    });
}



//qt图片路径
void Widget::Show_picture(){
    QPixmap *pax1 = new QPixmap(":/picture/gtx.jpg");
    Picture->setScaledContents(true);
    Picture->setPixmap(*pax1);
    Picture->resize(430,430);
    Picture->move(600,190);

    QPixmap *pax2 = new QPixmap(":/picture/xbmu.jpg");
    XBMU->setScaledContents(true);
    XBMU->setPixmap(*pax2);
    XBMU->resize(100,100);
    XBMU->move(100,40);

    QPixmap *pax3 = new QPixmap(":/picture/DZSJ.jpg");
    DZSJ->setScaledContents(true);
    DZSJ->setPixmap(*pax3);
    DZSJ->resize(181,101);
    DZSJ->move(820,40);



}
void Widget::paintEvent(QPaintEvent *){

    QPainter painter(this);
    QPixmap pix;
    pix.load(":/picture/beijing.jpg");
    painter.drawPixmap(0,0,this->width(),this->height(),pix);

}


void Widget::Show_Title(){
    Title->setAlignment(Qt::AlignHCenter);        //设置label属性
    Title->setText("智慧生活");                  //设置label内容
    QFont Title_font ("黑体", 22, 30);
    Title->setGeometry(120,30,801,90);
    Title->setFont(Title_font);
    Title->show();
}

void Widget::Show_Tempature(){
    Tempature_Text->setAlignment(Qt::AlignHCenter);        //设置label属性
    Tempature_Text->setText("温度大小:");                  //设置label内容
    QFont Tempature_font ("楷体", 15, 0);
    Tempature_Text->setGeometry(40,200,251,61);
    Tempature_Text->setFont(Tempature_font);
    Tempature_Text->show();

    Tempature_Data->setAlignment(Qt::AlignHCenter);        //设置label属性
    Tempature_Data->setText("27°");                  //设置label内容
    QFont Tempature_Data_font ("楷体", 15, 0);
    Tempature_Data->setGeometry(270,210,251,61);
    Tempature_Data->setFont(Tempature_Data_font);
    Tempature_Data->show();
}
void Widget::Show_Sun(){
    Sun_Text->setAlignment(Qt::AlignHCenter);        //设置label属性
    Sun_Text->setText("天气情况:");                  //设置label内容
    QFont Sun_font ("楷体", 15, 0);
    Sun_Text->setGeometry(40,330,251,61);
    Sun_Text->setFont(Sun_font);
    Sun_Text->show();

    Sun_Data->setAlignment(Qt::AlignHCenter);        //设置label属性
    Sun_Data->setText("晴天");                  //设置label内容
    QFont Sun_Data_font ("楷体", 15, 0);
    Sun_Data->setGeometry(270,330,251,61);
    Sun_Data->setFont(Sun_Data_font);
    Sun_Data->show();
}
void Widget::Show_Fire(){
    Fire_Text->setAlignment(Qt::AlignHCenter);        //设置label属性
    Fire_Text->setText("火灾警报:");                  //设置label内容
    QFont Fire_font ("楷体", 15, 0);
    Fire_Text->setGeometry(40,460,251,61);
    Fire_Text->setFont(Fire_font);
    Fire_Text->show();

    Fire_Data->setAlignment(Qt::AlignHCenter);        //设置label属性
    Fire_Data->setText("安全");                  //设置label内容
    QFont Fire_Data_font ("楷体", 15, 0);
    Fire_Data->setGeometry(270,460,251,61);
    Fire_Data->setFont(Fire_Data_font);
}
void Widget::Show_DHT(){
    DHT_Text->setAlignment(Qt::AlignHCenter);        //设置label属性
    DHT_Text->setText("湿度大小:");                  //设置label内容
    QFont DHT_font ("楷体", 15, 0);
    DHT_Text->setGeometry(40,590,251,61);
    DHT_Text->setFont(DHT_font);
    DHT_Text->show();

    DHT_Data->setAlignment(Qt::AlignHCenter);        //设置label属性
    DHT_Data->setText("44%");                  //设置label内容
    QFont DHT_Data_font ("楷体", 15, 0);
    DHT_Data->setGeometry(270,600,251,61);
    DHT_Data->setFont(DHT_Data_font);
    DHT_Data->show();
}

Widget::~Widget()
{
    delete ui;
}
void Widget::closeEvent(QCloseEvent* ){
        tcpsocket->write("close");

         //服务器ip地址
        tcpsocket ->connectToHost("124.223.213.54",987);
}

void Widget::on_radioButton_clicked()
{
    tcpsocket->write("1");
}

void Widget::on_radioButton_2_clicked()
{
    tcpsocket->write("2");
}

void Widget::on_radioButton_3_clicked()
{
     tcpsocket->write("3");
}

void Widget::on_radioButton_4_clicked()
{
    tcpsocket->write("4");
}

void Widget::on_radioButton_5_clicked()
{
    tcpsocket->write("5");
}

void Widget::on_radioButton_6_clicked()
{
    tcpsocket->write("6");
}

void Widget::on_radioButton_7_clicked()
{
    tcpsocket->write("7");
}

void Widget::on_radioButton_8_clicked()
{
    tcpsocket->write("8");
}


void Widget::on_radioButton_9_clicked()
{
    tcpsocket->write("a");
}

void Widget::on_radioButton_10_clicked()
{
    tcpsocket->write("b");
}

void Widget::on_radioButton_11_clicked()
{
    tcpsocket->write("c");
}

void Widget::on_radioButton_12_clicked()
{
    tcpsocket->write("d");
}

void Widget::on_commandLinkButton_clicked()
{
    m->show();
    this->hide();
}

void Widget::on_pushButton_clicked()
{
    tcpsocket->write("close");
    tcpsocket ->connectToHost("124.223.213.54",987);
}

 3.5 web服务器端源代码

#include <errno.h>
#include <dirent.h>
#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <sys/wait.h>  
#include <sys/types.h>  
#include <sys/epoll.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <strings.h>
#define MAXSIZE 2048  
#include <ctype.h>
/*w\n是app,y\n是树莓派,1是树莓派,2是客户端,3是web*/
int mgq=1;
//int ti_web_fd[10];
//int flag[5];
struct xxx{
	int ti_fd;
	int status; 
}sock[10];
struct xx{
	int bed_light;
	int yc_light;
	int kt_light;
	int ct_light;
	int fs_speed;
	int ct_door;
}home;

void send_index(int cfd)
{
	int ret;
	char buf[4094]="\0";
	char name[100]="你好贾维斯";
	sprintf(buf,"<html><head><title>%s</title></head>",name);
	sprintf(buf+strlen(buf),"<body><h1 style=\"text-align:center;font-size:70px;\">贾维斯终端系统</h1><table>");
	
	if(home.yc_light == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">泳池灯:</p><a href=\"http://124.223.213.54:987/1 \" style=\"text-decoration:none;color:black;font-size:50px;\"> 开</a>  <p style=\"color:red; display:inline-block;font-size:50px;\"   >   关</p></h1><table>");
	}else{ 
		 sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">泳池灯:</p> <p style=\"color:red;display:inline-block;font-size:50px;\" >开</p> <a href=\"http://124.223.213.54:987/2 \" style=\"text-decoration:none;color:black;display:inline-block;font-size:50px; \">关</a></h1><table>");
	}
	if(home.bed_light == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">浴室灯:</p><a href=\"http://124.223.213.54:987/3 \" style=\"text-decoration:none;color:black;font-size:50px;\"> 开</a> <p style=\"color:red; display:inline-block;font-size:50px;\">关</p></h1><table>");
	}else{ 
		 sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">浴室灯:</p> <p style=\"color:red;display:inline-block;font-size:50px;\" >开</p> <a href=\"http://124.223.213.54:987/4 \" style=\"text-decoration:none;color:black;display:inline-block;font-size:50px; \">关</a></h1><table>");
	}
	if(home.kt_light == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">客厅灯:</p><a href=\"http://124.223.213.54:987/5 \" style=\"text-decoration:none;color:black;font-size:50px;\"> 开</a> <p style=\"color:red; display:inline-block;font-size:50px;\">关</p></h2><table>");
	}else{ 
		 sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">客厅灯:</p> <p style=\"color:red;display:inline-block;font-size:50px; \" >开</p> <a href=\"http://124.223.213.54:987/6 \" style=\"text-decoration:none;color:black;display:inline-block;font-size:50px; \">关</a></h2><table></body></html>");
	}
	if(home.ct_light == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">餐厅灯:</p><a href=\"http://124.223.213.54:987/7 \" style=\"text-decoration:none;color:black;font-size:50px;\"> 开</a> <p style=\"color:red; display:inline-block;font-size:50px;\">关</p></h2><table></body></html>");
	}else{ 
		 sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">餐厅灯:</p> <p style=\"color:red;display:inline-block;font-size:50px; \" >开</p> <a href=\"http://124.223.213.54:987/8 \" style=\"text-decoration:none;color:black;display:inline-block;font-size:50px; \">关</a></h2><table></body></html>");
	}
	if(home.ct_door == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">大门:</p><a href=\"http://124.223.213.54:987/m \" style=\"text-decoration:none;color:black;font-size:50px;\"> 开</a>  <p style=\"color:red; display:inline-block;font-size:50px;\"   >   关</p></h1><table>");
	}else{ 
		 sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">大门:</p> <p style=\"color:red;display:inline-block;font-size:50px;\" >开</p> <a href=\"http://124.223.213.54:987/k \" style=\"text-decoration:none;color:black;display:inline-block;font-size:50px; \">关</a></h1><table>");
	}
	if(home.fs_speed == 0){
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">电风扇:</p><p style=\"color:red;display:inline-block;font-size:50px;  \">&nbsp;&nbsp;&nbsp;0</p><a href=\"http://124.223.213.54:987/b \" style=\"text-decoration:none;color:black;font-size:50px;  \">&nbsp;&nbsp;&nbsp;1</a><a href=\"http://124.223.213.54:987/c \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;2</a><a href=\"http://124.223.213.54:987/d \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;3</a></h1><table></body></html>");
	}else if(home.fs_speed == 1){ 
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">电风扇:</p><a href=\"http://124.223.213.54:987/a \" style=\"text-decoration:none;color:black;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;0</a><p style=\"color:red;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;1</p><a href=\"http://124.223.213.54:987/c \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;2</a><a href=\"http://124.223.213.54:987/d \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;3</a></h1><table></body></html>");
	}
	else if(home.fs_speed == 2){ 
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">电风扇:</p><a href=\"http://124.223.213.54:987/a \" style=\"text-decoration:none;color:black;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;0</a><a href=\"http://124.223.213.54:987/b \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;1</a><p style=\"color:red;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;2</p><a href=\"http://124.223.213.54:987/d \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;3</a></h1><table></body></html>");
	}
	else if(home.fs_speed == 3){ 
		sprintf(buf+strlen(buf),"<h1><p style=\"font-size:60px;display:inline-block;\">电风扇:</p><a href=\"http://124.223.213.54:987/a \" style=\"text-decoration:none;color:black;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;0</a><a href=\"http://124.223.213.54:987/b \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;1</a><a href=\"http://124.223.213.54:987/c \" style=\"text-decoration:none;color:black;font-size:50px; \">&nbsp;&nbsp;&nbsp;2</a><p style=\"color:red;font-size:50px;display:inline-block; \">&nbsp;&nbsp;&nbsp;3</p></h1><table></body></html>");
	}
	ret = send(cfd,buf,strlen(buf),0);
	
}
int get_line(int cfd, char *buf, int size)
{
	int i = 0;
	char c = '\0';
	int n;
	while((i <size-1) && (c != '\n')){
		n = recv(cfd , &c, 1, 0);
		if(n > 0){
			if(c == '\r'){
				n = recv(cfd , &c , 1 , MSG_PEEK);
				if((n>0) && (c=='\n')){
					recv(cfd , &c , 1, 0);
				}else{
					c = '\n';
				}
			}
			buf[i] =c;
			i++;
		}else{
			c ='\n';
		}
	}
	buf[i] ='\0';
	if(n == -1){
		i=n;
	}
	return i;
}
int hexit(char c)
{
	if(c>='0'&&c<='9') return c-'0';
	if(c>='a'&&c<='f')  return c-'a'+10;
	if(c>='A'&&c<='F') return c-'A'+10;
}
void encode_str(char* to, int tosize, const char *from)
{
	int tolen;
	for(tolen = 0;*from!='\0'&&tolen+4<tosize;++from){
		if(isalnum(*from)||strchr("/_.-~",*from)!=(char *)0){
			*to=*from;
			++to;
			++tolen;
		}else{
			sprintf(to,"%%%02x",(int)*from&0xff);
			to+=3;
			tolen+=3;
		}
	}
	*to='\0';
}
void decode_str(char *to,char *from)
{
	for(;*from!='\0';++to,++from){
		if(from[0]=='%'&&isxdigit(from[1])&&isxdigit(from[2])){
			*to=hexit(from[1])*16+hexit(from[2]);
			from+=2;
		}else{
			*to=*from;
		}
	}
	*to='\0';
}

// 通过文件名获取文件的类型  
char *get_file_type(const char *name)  
{  
    char* dot;  
  
    // 自右向左查找‘.’字符, 如不存在返回NULL  
    dot = strrchr(name, '.');     
    if (dot == NULL)  
        return "text/plain; charset=utf-8";  
    if (strcmp(dot, ".html") == 0 || strcmp(dot, ".htm") == 0)  
        return "text/html; charset=utf-8";  
    if (strcmp(dot, ".jpg") == 0 || strcmp(dot, ".jpeg") == 0)  
        return "image/jpeg";  
    if (strcmp(dot, ".gif") == 0)  
        return "image/gif";  
    if (strcmp(dot, ".png") == 0)  
        return "image/png";  
    if (strcmp(dot, ".css") == 0)  
        return "text/css";  
    if (strcmp(dot, ".au") == 0)  
        return "audio/basic";  
    if (strcmp( dot, ".wav" ) == 0)  
        return "audio/wav";  
    if (strcmp(dot, ".avi") == 0)  
        return "video/x-msvideo";  
    if (strcmp(dot, ".mov") == 0 || strcmp(dot, ".qt") == 0)  
        return "video/quicktime";  
    if (strcmp(dot, ".mpeg") == 0 || strcmp(dot, ".mpe") == 0)  
        return "video/mpeg";  
    if (strcmp(dot, ".vrml") == 0 || strcmp(dot, ".wrl") == 0)  
        return "model/vrml";  
    if (strcmp(dot, ".midi") == 0 || strcmp(dot, ".mid") == 0)  
        return "audio/midi";  
    if (strcmp(dot, ".mp3") == 0)  
        return "audio/mpeg";  
    if (strcmp(dot, ".ogg") == 0)  
        return "application/ogg";  
    if (strcmp(dot, ".pac") == 0)  
        return "application/x-ns-proxy-autoconfig";  
  
    return "text/plain; charset=utf-8";  
}  

void send_error(int cfd, int status, char *title, char *text)  
{  
    char buf[4096] = {0};  
  
    sprintf(buf, "%s %d %s\r\n", "HTTP/1.1", status, title);  
    sprintf(buf+strlen(buf), "Content-Type:%s\r\n", "text/html");  
    sprintf(buf+strlen(buf), "Content-Length:%d\r\n", -1);  
    sprintf(buf+strlen(buf), "Connection: close\r\n");  
    send(cfd, buf, strlen(buf), 0);  
    send(cfd, "\r\n", 2, 0);  
  
    memset(buf, 0, sizeof(buf));  
  
    sprintf(buf, "<html><head><title>%d %s</title></head>\n", status, title);  
    sprintf(buf+strlen(buf), "<body bgcolor=\"#cc99cc\"><h2 align=\"center\">%d %s</h4>\n", status, title);  
    sprintf(buf+strlen(buf), "%s\n", text);  
    sprintf(buf+strlen(buf), "<hr>\n</body>\n</html>\n");  
    send(cfd, buf, strlen(buf), 0);  
      
    return ;  
}  
  
void send_respond(int cfd, int no, char *disp, char *type, int len)  
{  
	char buf[4096] = {0};  

	sprintf(buf, "HTTP/1.1 %d %s\r\n", no, disp);  
	send(cfd, buf, strlen(buf), 0);  

	sprintf(buf, "Content-Type: %s\r\n", type);  
	sprintf(buf+strlen(buf), "Content-Length:%d\r\n", len);  
	send(cfd, buf, strlen(buf), 0);  

	send(cfd, "\r\n", 2, 0);  
}

// 处理http请求, 判断文件是否存在, 回发  

void send_file(int cfd, const char *file)  
{  
	int n = 0,i;  
	char f1[2]={"1"},o1[2]={"2"},f2[2]={"3"},o2[2]={"4"},f3[2]={"5"},f4[2]={"7"},o3[2]={"6"},o4[2]={"8"};
	char s1[2]={"a"},s2[2]={"b"},s3[2]={"c"},s4[2]={"d"};
	char door1[2]={"m"},door2[2]={"k"};
//	char buf[1024]="\0";
	char sbuf[1024]="\0";
	printf("%s\n",file);
	if (strcmp(door1,file)==0)
	{	
		printf("web =1");
		home.ct_door=1;
		//write(1,"1",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"m",1);
				else	write(sock[i].ti_fd,"m",1);
				
			}
		}
	}
	if (strcmp(door2,file)==0)
	{	
		printf("web=0");
		home.ct_door=0;
		//write(1,"1",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"k",1);
				else	write(sock[i].ti_fd,"k",1);
				
			}
		}
	}
	if (strcmp(f1,file)==0)
	{	
		home.yc_light=1;
		//write(1,"1",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"1",1);
				else	write(sock[i].ti_fd,"L0",2);
				
			}
		}
	}
	else if(strcmp(o1,file)==0)
	{
		home.yc_light=0;
		//write(1,"2",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"2",1);
				else	write(sock[i].ti_fd,"L1",2);
				
			}
		}
	//	for(i=0;i<5;i++){
		//	write(ti_web_fd[0],"2",1);
	//	}
	}
	if (strcmp(f2,file)==0)
	{	
		home.bed_light=1;
		//write(1,"3",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"3",1);
				else	write(sock[i].ti_fd,"L2",2);
				
			}
		}
	//	for(i=0;i<5;i++){
		//	write(ti_web_fd[0],"3",1);
		//}
	}
	else if(strcmp(o2,file)==0)
	{
		home.bed_light=0;
		//write(1,"4",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"4",1);
				else	write(sock[i].ti_fd,"L3",2);
				
			}
		}
	//	for(i=0;i<5;i++){
		//	write(ti_web_fd[0],"4",1);
		//}
	}
	if (strcmp(f3,file)==0)
	{	
		home.kt_light=1;
		//write(1,"5",1);

		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"5",1);
				else	write(sock[i].ti_fd,"L4",2);
				
			}
		}
		//for(i=0;i<5;i++){
	//		write(ti_web_fd[0],"5",1);
		//}
	}
	else if(strcmp(o3,file)==0)
	{
		home.kt_light=0;
		//write(1,"6",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"6",1);
				else	write(sock[i].ti_fd,"L5",2);
				
			}
		}
	//	for(i=0;i<5;i++){
	//		write(ti_web_fd[0],"6",1);
		//}
	}
	if (strcmp(f4,file)==0)
	{	
		home.ct_light=1;
		//write(1,"7",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"7",1);
				else	write(sock[i].ti_fd,"L6",2);
				
			}
		}
	//	for(i=0;i<5;i++){
			//write(ti_web_fd[0],"7",1);
		//}
	}
	else if(strcmp(o4,file)==0)
	{
		home.ct_light=0;
		//write(1,"8",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"8",1);
				else	write(sock[i].ti_fd,"L7",2);
				
			}
		}
	//	for(i=0;i<10;i++){
	//		if()
	//		write(ti_web_fd[0],"8",1);
}
	if(strcmp(s1,file)==0){
		//write(1,"a",1);
		home.fs_speed=0;
		for(i=0;i<10;i++){
		if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"a",1);
				else	write(sock[i].ti_fd,"f0",2);		
		}
}
	}
	else if(strcmp(s2,file)==0){
		//write(1,"b",1);
		home.fs_speed=1;
		for(i=0;i<10;i++){
		if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"b",1);
				else	write(sock[i].ti_fd,"f1",2);		
		}
}
	}
	else if(strcmp(s3,file)==0){
		//write(1,"c",1);
		home.fs_speed=2;
		for(i=0;i<10;i++){
		if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"c",1);
				else	write(sock[i].ti_fd,"f2",2);		
		}
}
	}
	else if(strcmp(s4,file)==0){
		//write(1,"d",1);
		home.fs_speed=3;
		for(i=0;i<10;i++){
		if(sock[i].status == 1||sock[i].status == 2){
				if(sock[i].status == 1)	write(sock[i].ti_fd,"d",1);
				else	write(sock[i].ti_fd,"f3",2);		
		}
}
	}
	send_index(cfd);
}  
void send_dir(int cfd, const char* dirname)
{
	int i,ret;
	char buf[4094]={0};
	sprintf(buf,"<html><head><title>目录名:%s</title></head>",dirname);
	sprintf(buf+strlen(buf),"<body><h1>目录%s</h1><table>",dirname);
	
	char enstr[1024] = {'\0'};
	char path[1024] = {0};
	
	struct dirent** ptr;
	int num = scandir(dirname, &ptr, NULL, alphasort);
	for(i=0;i<num;i++){
		char *name=ptr[i]->d_name;
//		strcpy(enstr,dirname);
//		strcpy(enstr+strlen(enstr),name);
		sprintf(path,"%s/%s",dirname,name);
//		printf("path = %s ========\n",path);
		struct stat st;
		stat(path, &st);
		//printf("name:%s\n",name);
		encode_str(enstr, sizeof(enstr), name);
		if(S_ISREG(st.st_mode)){
			sprintf(buf+strlen(buf),"<tr><td><a href=\"%s\">%s</a></td><td>%ld</td></tr>",enstr,name,(long)st.st_size);
		}else if(S_ISDIR(st.st_mode)){
			sprintf(buf+strlen(buf),"<tr><td><a href=\"%s/\">%s/</a></td><td>%ld</td></tr>",enstr,name,(long)st.st_size);
		}
		ret = send(cfd,buf,strlen(buf),0);
		if(ret == -1){
			if(errno ==EINTR){
				continue;
			}
			else{
				perror("Send error");
				exit(1);
			}
		}
	//	memset(enstr,0,sizeof(enstr));
		memset(buf,0,sizeof(buf));
	}
}
void http_request(int cfd, const char *file)  
{ 
	//char buf[1024]="\0"; 
	struct stat sbuf;  
	
	char *buf;
	char name[1024]="\0";
	buf = (char *) malloc (1024);
      
	// 判断文件是否存在  
	int ret = stat(file, &sbuf);  
	if (ret != 0) {  	
	// 回发浏览器 404 错误页面  	
		send_error(cfd, 404,"error","Not Find");  
	//	perror("stat");  
	//	exit(1);      
	}  
	
	if(S_ISREG(sbuf.st_mode)) {     // 是一个普通文件  
		buf = get_file_type(file);

		// 回发 http协议应答  

 	       send_respond(cfd, 200, "OK", get_file_type(".html"), -1);  
		// 回发 给客户端请求数据内容。  
		send_file(cfd, file);  
	}else if(S_ISDIR(sbuf.st_mode)) {       // 目录   
        // 发送头信息  
 	       send_respond(cfd, 200, "OK", get_file_type(".html"), -1);  
 	       // 发送目录信息  
	//	if(strcmp(file,"./")==0){
			send_index(cfd);
		//}
       	//	send_dir(cfd, file); 
	}

}  
int init_listen_fd(int port, int epfd)  
{  
	// 创建监听的套接字 lfd  
	int lfd = socket(AF_INET, SOCK_STREAM, 0);  
	if (lfd == -1) {      
		perror("socket error");  
		exit(1);  
	}  
	// 创建服务器地址结构 IP+port  
	struct sockaddr_in srv_addr;  

	bzero(&srv_addr, sizeof(srv_addr));  
	srv_addr.sin_family = AF_INET;  
	srv_addr.sin_port = htons(port);  
	srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  

	// 端口复用  
	int opt = 1;  
	setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  

	// 给 lfd 绑定地址结构  
	int ret = bind(lfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));  
	if (ret == -1) {     
		perror("bind error");  
		exit(1);  
	}  
	// 设置监听上限  
	ret = listen(lfd, 128);  
	if (ret == -1) {   
		perror("listen error");  
		exit(1);  
	}  

	// lfd 添加到 epoll 树上  
	struct epoll_event ev;  
	ev.events = EPOLLIN;  
	ev.data.fd = lfd;  

	ret = epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &ev);  
	if (ret == -1) {   
		perror("epoll_ctl add lfd error");  
		exit(1);  
	}  

	return lfd;  
}  

void do_accept(int lfd, int epfd)  
{
	struct sockaddr_in clt_addr;  
    socklen_t clt_addr_len = sizeof(clt_addr);  
      
    int cfd = accept(lfd, (struct sockaddr*)&clt_addr, &clt_addr_len);  
    if (cfd == -1) {     
        perror("accept error");  
        exit(1);  
    }  
  
    // 打印客户端IP+port  
    char client_ip[64] = {0};  
	for(int i=0;i<10;i++){
		if(sock[i].ti_fd ==-1){
			sock[i].ti_fd=cfd;
			printf("cfd=%d i=%d\n",cfd,i);
			sock[i].status =3;//web模式
			break;
		}
	}  
    // 设置 cfd 非阻塞  
    int flag = fcntl(cfd, F_GETFL);  
    flag |= O_NONBLOCK;  
    fcntl(cfd, F_SETFL, flag);  
  
    // 将新节点cfd 挂到 epoll 监听树上  
    struct epoll_event ev;  
    ev.data.fd = cfd;  
      
    // 边沿非阻塞模式  
    ev.events = EPOLLIN | EPOLLET;  
      
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);  
    if (ret == -1)  {  
        perror("epoll_ctl add cfd error");  
        exit(1);  
    } 
	
/*	if(mgq==1){
		mgq=0;
		printf("ti'cfd=%d,web'cfd=%d\n",ti_web_fd[0],ti_web_fd[1]); 
	}*/
}  
void  disconnect(int cfd,int epfd)
{
	epoll_ctl(epfd, EPOLL_CTL_DEL,  cfd, NULL);
	close(cfd);
}
void app_dispose(int cfd,char buf[1024],int epfd){
	int i;
	if(strcmp(buf,"close")==0){
	//	printf("xx\n");
		for(i=0;i<10;i++){
			if(sock[i].ti_fd == cfd){
	//			printf("%d\n",i);
				sock[i].ti_fd = -1;
				sock[i].status=0;
				
			//	epoll_ctl(epfd, EPOLL_CTL_DEL,  cfd, NULL);
				disconnect(cfd,epfd);
				break;
			}
		}
	}
	else if(strcmp(buf,"1")==0){
		home.yc_light=1;
//		printf("1");
		write(1,"1",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"1",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"2")==0){
		home.yc_light=0;
		write(1,"2",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"2",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"3")==0){
		home.bed_light=1;
		write(1,"3",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"3",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"4")==0){
		home.bed_light=0;
		write(1,"4",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"4",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"5")==0){
		home.kt_light=1;
		write(1,"5",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"5",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"6")==0){
		home.kt_light=0;
		write(1,"6",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"6",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"7")==0){
		home.ct_light=1;
		write(1,"7",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				write(sock[i].ti_fd,"7",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"8")==0){
		home.ct_light=0;
		write(1,"8",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"8",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"a")==0){
		home.ct_light=0;
		write(1,"a",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"a",1);
				break;
			}
		}
	}	
	else if(strcmp(buf,"b")==0){
		home.ct_light=0;
		write(1,"b",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"b",1);
				break;
			}
		}
	}	
	else if(strcmp(buf,"c")==0){
		home.ct_light=0;
		write(1,"c",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"c",1);
				break;
			}
		}
	}	
	else if(strcmp(buf,"d")==0){
		home.ct_light=0;
		write(1,"d",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"d",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"m")==0){
		home.ct_door=1;
		write(1,"d",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"m",1);
				break;
			}
		}
	}
	else if(strcmp(buf,"k")==0){
		home.ct_door=0;
		write(1,"d",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
		//		printf("qwe");
				write(sock[i].ti_fd,"k",1);
				break;
			}
		}
	}
}
void smp_dispose(int cfd,char buf[1024],int epfd){
	int i;
	if(strcmp(buf,"z")==0){
		write(1,"z",1);
		for(i=0;i<10;i++){
			if(sock[i].status == 1){
				epoll_ctl(epfd, EPOLL_CTL_DEL,  cfd, NULL);
				sock[i].status = -1;
				break;
			}
		}
	}
	else{
		for(i=0;i<10;i++){
			if(sock[i].status == 2){
				write(sock[i].ti_fd,buf,strlen(buf));
				break;
			}
		}
	}
}
void do_read(int cfd, int epfd)  
{  
	char x;
	// 读取一行http协议, 拆分, 获取 get 文件名 协议号     
	char line[1024] = {0};  
	char method[16], path[256]="\0", protocol[16];   
	char name[1024]={"\0"};
	for(int i=0;i<10;i++){
		if(sock[i].ti_fd == cfd){
			if(sock[i].status==1){
			read(cfd,line,sizeof(line));
			smp_dispose(cfd,line,epfd);
			//做出响应的处理
		//	printf("smp");
			return;
			}
			else if(sock[i].status==2){
			//	printf("app ");
				read(cfd,line,sizeof(line));
		//		printf("%s\n",line);
				app_dispose(cfd,line,epfd);
				return;
			}
		}
	}
	int len = get_line(cfd, line, sizeof(line)); //读 http请求协议首行 GET /hello.c HTTP/1.1  
	printf("%c\n",line[0]);
	//usleep(2000);
	if((len == 2)&&(line[0]=='w'||line[0]=='y'||line[0]=='t')){
		//printf("come\n");
		//app发送
		if(line[0]=='w')
			for(int i=0;i<10;i++){
				if(sock[i].ti_fd==cfd) {
		//			printf("%d ,status=2\n",sock[i].ti_fd);
					printf("app已连接\n");
					sock[i].status = 2;
					break;
				}
			}
		//树莓派
		else if(line[0]=='y'){
			for(int i=0;i<10;i++){
				if(sock[i].ti_fd==cfd){
					printf("单片机已连接\n");
		//			printf("%d ,status=1\n",sock[i].ti_fd);
					sock[i].status = 1;
					break;
				}
			}
		}
		else if(line[0]=='t'){
			for(int i=0;i<10;i++){
				if(sock[i].ti_fd==cfd){
					printf("替身已连接\n");
		//			printf("%d ,status=1\n",sock[i].ti_fd);
					sock[i].status = 7;
					break;
				}
			}
		}
		return ;
	}
	else if (len == 0) {  
		//printf("服务器,检查到客户端关闭....\n");     
		disconnect(cfd, epfd); 
		return;
	}
	 else {  

		sscanf(line, "%[^ ] %[^ ] %[^ ]", method, path, protocol);    
	//	printf("method=%s, path=%s, protocol=%s\n", method, path, protocol);  

		while (1) {  
			char buf[1024] = {0};  
			len = get_line(cfd, buf, sizeof(buf));    
			if (buf[0] == '\n') {  
				break;    
			} else if (len == -1)  
				break;  
		}     

	} 
	 
	decode_str(path,path);
	if (strncasecmp(method, "GET", 3) == 0)  
	{  
		char *file = path+1;   // 取出 客户端要访问的文件名  
//		char* file = path+1; // 去掉path中的/ 获取访问文件名  
      
 		   // 如果没有指定访问的资源, 默认显示资源目录中的内容  
 		if(strcmp(path, "/") == 0) {      
        		// file的值, 资源目录的当前位置  
        		file = "./";  
    		}  
		
//		printf("%s\n",file);
		http_request(cfd, file);  
		
		disconnect(cfd, epfd);  
		for(int i=0;i<10;i++){
			if(sock[i].ti_fd==cfd){
				sock[i].ti_fd=-1;
				sock[i].status=0;
				break;
			}
		}
	}  
}  

void epoll_run(int port)  
{  
	int i = 0;  
	struct epoll_event all_events[MAXSIZE];  
	// 创建一个epoll监听树根  
	int epfd = epoll_create(MAXSIZE);  
	if (epfd == -1) {   
		perror("epoll_create error");  
		exit(1);  
	}  
	// 创建lfd,并添加至监听树  
	int lfd = init_listen_fd(port, epfd);  
	while (1) {  
		// 监听节点对应事件  
		int ret = epoll_wait(epfd, all_events, MAXSIZE, -1);  
		if (ret == -1) {        
			perror("epoll_wait error");  
			exit(1);  
		}  

		for (i=0; i<ret; ++i) {  

			// 只处理读事件, 其他事件默认不处理  
			struct epoll_event *pev = &all_events[i];  

			// 不是读事件  
			if (!(pev->events & EPOLLIN)) {                       
				continue;  
			}  
			if (pev->data.fd == lfd) {       // 接受连接请求     

				do_accept(lfd, epfd);  

			} else {                        // 读数据  

				do_read(pev->data.fd, epfd);  
			}  
		}  
	}  
}  

int main(int argv,char* argc[])  
{   
	// 命令行参数获取 端口 和 server提供的目录  

	home.bed_light = 0;
	home.kt_light = 0;
	home.ct_light = 0;
	home.yc_light = 0;
	home.fs_speed = 0;
	home.ct_door = 0;
	// 获取用户输入的端口   
	int port = atoi("987");  

	// 改变进程工作目录  
	int ret = chdir("./");  
	for(int i=0;i<10;i++){
		sock[i].ti_fd = -1;
		sock[i].status = 0;
	}
	if (ret != 0) {  
		perror("chdir error");    
		exit(1);  
	}  

	// 启动 epoll监听  
	epoll_run(port);  

	return 0;  
}  


四、硬件框图

        项目硬件是由stm32开发板为控制板,搭载嵌入式控制板;通过服务器访问,利用软件app、网页和控制面板控制各个模块的功能。搭建硬件,需要对控制工具进行初始化,利用esp8266模块,建立网络连接,使各个控制工具能够正常控制家居所要的功能。家居主要有一些家用电器模块和传感器构成。正是由于这些模块传感器的存在,家居的功能显得更加充实,更加完美。此外,控制面板,需要设置图形化界面,配置环境等,可使用户看起来清晰可见,易于操作,简单明了。 

五、流程框图

        软件控制主要有app和网页构成。App的开发是由qt软件来完成开发,该软件易与开发,适合初学者使用。该开发软件需要配置安卓环境,为移植到手机app提供前提环境。网页使由Visual Studio 软件进行编写,通过端口号访问网页。网页和手机app都需要通过服务器访问,才能连接到硬件,进行控制。 

六、系统测试方案

6.1 功能测试

测试范围

App、网页、控制面板,模块运行正常等

测试目标

核实所有功能实现是否与需求一致

工具与方法

手工测试

开始标准

开发阶段对应的功能一致

完成标准

测试用例全部通过,高级缺陷全部解决

6.2 用户界面测试 

测试范围

测试目标

核实窗口风格均与需求一致,符合接受标准,保证用户的友好型,易操作性,用户习惯

技术

Web、app测试通用工具

工具与方法

手工测试

开始标准

界面开发完成

完成标准

符合接受标准,符合用户的友好型,易操作性,用户习惯

6.3 兼容性测试

测试范围

网页使用不同版本的浏览器、分辨率进行测试;app使用不同品牌的手机、分辨率进行测试

测试目标

核实不同软件和硬件中运行稳定

工具与方法

手工测试

开始标准

通过审核,可移交系统测试

完成标准

不同情况下,各功能正常运用

七、测试设备

        手机app:可使用不同类型、不同版本的手机进行测试,如:huawei、oppo、小米、vivo、三星等。但是该app不兼容苹果系统的手机,不能用来测试。

        网页:可利用不用版本的浏览器进行测试,如:、Yandex Browser、vivaldi browser、Chrome等。

        控制面板:利用项目所携带的控制面板进行测试。

 八、测试数据

测试功能

测试情况

手机app

服务器访问正常,控制正常,IU界面符合需求

网页

服务器访问正常,控制正常,IU界面符合需求

控制面板

可与手机app,网页联动控制,服务器访问无异常

模块使用

能够根据指令可做出相应的反应

服务器访问

能够接受手机app、网页、控制面板的访问,做出相应的应答。

九、结果分析 

        项目各项功能运行正常,手机app除苹果手机外,任何一台手机皆可运行,对项目的各项功能均可以实现。手机app界面符合用户的需求,可观性强,易操作。除了对各个模块的控制之外,可以显示家居的温湿度,安全情况等。网页app的测试与预计效果一致。在各个浏览器上可以正常显示,对功能的测试未出现其他情况。IU界面的窗口格式符合用户的需求,易操作强。控制面板可访问服务器,与手机app,网页显示一致,能够共同联动,可通过控制面板上的各个功能达到所需要的需求。

十、实现功能

        用户通过人机交互系统产品与安卓手机app,手机端网页通讯,安卓手机通过自定义协议数据处理及传输,网页通过Http协议数据处理及传输,搭建在阿里云服务器上。STM32单片机通过利用ESP8266WIFI模块访问服务器接受数据,控制房间客厅灯,浴室灯,卧室灯,泳池灯,大门,温湿度,火灾报警等各个智能模块的运行,最终达到更懂用户的效果。 

十一、特色

11.1 电路集成

 通过AD软件实现将整块系统板的电路集成在一块PCB上。

(1)故障率低
        于集成电路的故障发生率相对分立元器件电路而言比较低,所以降低了整机电路的故障发生率。

(2)电路简单
        由于采用了集成电路,简化了整机电路的设计、调试和安装,特别是采用一些专用集成电路后,整机电路显得更为简单。

(3)能耗较小
        集成电路还具有耗电小、体积小、经济等优点。同一功能的电路,采用集成电路要比采用分立电子元器件的电路功耗小许多。

(4)性价比高
        相对于分立元器件电路而言,采用集成电路构成的整机电路性能指标更高,与分立电子元器件电路相比,集成电路的成本、价格更低。例如,集成运放电路的增益之高、零点漂移之小是分立电子元器件电路无法比拟的。

(5)可靠性强
        集成电路具有可靠性高的优点,从而提高了整机电路工作的可靠性,提高了电路的工作性能和一致性。另外,采用集成电路后,电路中的焊点大幅度减少,出现虚焊的可能性下降,使整机电路工作更为可靠。

11.2.火灾警报:

        使用火焰传感器模块,实现对火焰的检测,当发现明火时,蜂鸣器响起,并通过触摸屏与APP发起警报,可以早期发现火灾,并及时采取有效措施,控制和扑灭火灾。

11.3.网页控制:

        服务器基于http协议实现网页的数据传输,达到控制效果。可靠性高、安全性强、响应快速、组网自动化、自动诊断和恢复系统故障。

11.4.APP开发:

        通过QT实现安卓APP的开发,并通过socket实现于服务器建立连接,达到数据通信与控制效果。

11.5.单片机控制:

        主要从各个模块中获取信息,对获取的信息进行编码,通过ESP8266模块实现对服务器的连接,之后可将编码的信息通过网络发送给服务器,再通过服务器将数据分发给APP能够控制整个系统功能的正常运行。

11.6.语音交互:

        通过语音模块收集外部的信息,并传输给单片机,单片机再做出反馈,实现基本的控制功能,并且可以实现通过特定的指令将信息传递给单片机,并反馈给用户当前的环境信息。

11.7.人脸识别:

        该开发板可以置于门口,通过K210摄像头实现人脸识别开关门,并支持人脸信息的录入。

十二、资源获取链接:毕设&amp;大创&amp;项目&amp;竞赛-基于嵌入式的智能家居控制板演示效果.zip资源-CSDN文库

成品展示:

资源详情:

12.1 资源包目录:

 12.2 源代码

(1)单片机源程序 :

(2) 手机app:

(3)服务器端:

 

12.3 手机app打包程序

 

 12.4 数据

12.5 用户手册

 总结:

        随着智能家居的快速发展,越来越多的人已经开始了解并接受智能家居。智能家居使用较多的产品是智能家电,智能锁,智能音箱,智能面板,智能窗帘,智能摄像头、监控安防、插电式的电暖气片、智能家用机器人、无线门铃、小夜灯等。其中,智能面板安装美观,产品成熟,分布广泛。这些产品深受用户青睐。此外,用户在选择过程中看重的是智能家居的实用性,产品的品牌以及相应的配套安装服务,因此安全性与系统需求更显重要,对于非专业的用户而言,更看重安装服务。在客户需求当中系统维护显得尤为重要。另外,由于行业缺乏统一的准入标准而导致在产品的价格,产品的体验感与产品功能的实用性上出现了参差不齐的局面这是用户关注的问题,也是需要解决的问题。用户的主要需求集中在照明+安防,有线与无线相结合的技术方式,场景联动需求凸显,越来越看重系统稳定性。在未来的需求当中,室内外与社区的智能体验将呈现一体化,DT时代数据化服务将智慧社区与智能家居统一用户ID,借助AI算法等技术打通信息孤岛,在统一的设备层上实现完整的一体化服务运营。

        因此智能家居项目是一个具有极大潜力的项目,并且值得我们深入挖掘与研究,在项目的开发中,不仅能够提升个人的专业知识水平,更能够使我们了解当前行业发展的水平,在实践中创新、在实践中进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1514507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Studio入门——页面跳转

1.工程目录 2.MainActivity package com.example.demo01;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCo…

数据集成工具 ---- datax 3.0

1、datax: 是一个异构数据源离线同步工具&#xff0c;致力于实现关系型数据库&#xff08;mysql、oracle等&#xff09;hdfs、hive、hbase等各种异构数据源之间的数据同步 2、参考网址文献&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.mdhttps:/…

pycharm配置解释器

pycharm配置解释器 1.mac配置解释器 1.mac配置解释器

【C++庖丁解牛】STL简介 | string容器初次见面

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1. 什么是STL2. STL的版本…

扫描全能王发布2023“绿色数据”:减碳超12万吨,相当于多种700万棵树

近年来&#xff0c;“绿色转型”“低碳生活”成为全民热议话题。从全国覆盖率越来越高的“垃圾分类”&#xff0c;到蓬勃发展的“无纸化办公”&#xff0c;低碳生活、绿色消费的环保风尚不断兴起。植树节将至&#xff0c;合合信息旗下扫描全能王发布了年度用户文档扫描数据&…

详细分析Mysql中的LOCATE函数(附Demo)

目录 1. 基本概念2. Demo3. 实战 1. 基本概念 LOCATE()函数在SQL中用于在字符串中查找子字符串的位置 它的一般语法如下&#xff1a; LOCATE(substring, string, start)LOCATE()函数返回子字符串在主字符串中第一次出现的位置 如果未找到子字符串&#xff0c;则返回0 具体的…

如何在群晖用Docker本地搭建Vocechat聊天服务并无公网ip远程交流协作

文章目录 1. 拉取Vocechat2. 运行Vocechat3. 本地局域网访问4. 群晖安装Cpolar5. 配置公网地址6. 公网访问小结 7. 固定公网地址 如何拥有自己的一个聊天软件服务? 本例介绍一个自己本地即可搭建的聊天工具,不仅轻量,占用小,且功能也停强大,它就是Vocechat. Vocechat是一套支持…

【BFS二叉树】113路径总和II

113路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 思路&#xff1a; 题目最终输出的是路径&#xff0c;因此用BFS遍历的时候&#xff0c;需要记录走到每个节点的路径&#xff1…

ISIS单区域实验简述

ISIS 中间系统到中间系统&#xff0c;也是链路状态协议&#xff0c;工作在数据链路层&#xff0c;不依赖IP地址&#xff1b;与OSPF一样采用最短路径SPF算法&#xff0c;收敛速度快。 实验基础配置&#xff1a; r1: sys sysname r1 undo info enable int g0/0/0 ip add 12.1.1.1…

基于XMind的E-R图制作【笔记】

基于XMind的E-R图制作【笔记】 前言版权基于XMind的E-R图制作1.打开XMind2.选择模板3.插入一个自由主题4.为它插入子主题5.快速插入子主题6. 统一设置子主题样式 最后 前言 2024-3-11 10:36:33 以下内容源自《【创作模板】》 仅供学习交流使用 版权 禁止其他平台发布时删除…

js【详解】ajax (含XMLHttpRequest、 同源策略、跨域)

ajax 的核心API – XMLHttpRequest get 请求 // 新建 XMLHttpRequest 对象的实例 const xhr new XMLHttpRequest(); // 发起 get 请求&#xff0c;open 的三个参数为&#xff1a;请求类型&#xff0c;请求地址&#xff0c;是否异步请求&#xff08; true 为异步&#xff0c;f…

程序语言设计

一、程序设计语言及其构成 1.程序设计语言 2.高级程序设计语言划分 3.常见的高级程序语言 4.标记语言 5.程序设计语言的构成 二、表达式 表达式的类型及转换规则 三、传值和传址调用 1.数据类型 2.传值和传址调用 四、语言处理程序 1.语言处理程序 语言处理程序&#xff1…

kangle一键安装脚本

Kangle一键脚本&#xff0c;是一款可以一键安装KangleEasypanelMySQLPHP集合的Linux脚本。 脚本本身集成&#xff1a;PHP5.38.2、MYSQL5.68.0&#xff0c;支持极速安装和编译安装2种模式&#xff0c;支持CDN专属安装模式。同时也对Easypanel面板进行了大量优化。 脚本特点 ◎…

FreeRTOS 的任务挂起和恢复

1. 任务挂起和恢复的 API 函数 API函数描述vTaskSuspend()挂起任务vTaskResume()恢复被挂起的任务xTaskResumeFromISR()在中断中恢复被挂起的任务 挂起&#xff1a;挂起任务类似暂停&#xff0c;可恢复&#xff1b; 删除任务&#xff0c;堆栈都给释放掉了&#xff0c;无法恢复…

某电信公司组织结构优化咨询项目成功案例纪实

——构建前后端组织结构&#xff0c;提升组织运营效率 随着企业的不断发展&#xff0c;行业的竞争也越来越激烈&#xff0c;企业只能不断调整自身的战略才能更好的适应这样的大环境。在战略调整的过程中&#xff0c;企业往往会面临这样的问题&#xff1a;管理层的经营理念各不…

从0到1快速搭建一个jeecg 企业级应用管理后台

一. 基本介绍 官网地址&#xff1a;https://jeecg.com/ JeecgBoot 是一款企业级的低代码平台&#xff01;前后端分离架构 SpringBoot2.x&#xff0c;SpringCloud&#xff0c;Ant Design&Vue3&#xff0c;Mybatis-plus&#xff0c;Shiro&#xff0c;JWT 支持微服务。强大的…

Linux内核编译(版本6.0以及版本v0.01)并用qemu驱动

系统环境&#xff1a; ubuntu-22.04.1-desktop-amd64 目标平台: x86 i386 内核版本: linux-6.0.1 linux-0.0.1 环境配置 修改root密码 sudo passwd 修改软件源&#xff08;非必要&#xff09; vmtools安装&#xff08;实现win-linux软件互传&#xff09; 安装一些必须的软件&…

day02vue学习

day02 一、今日学习目标 1.指令补充 指令修饰符v-bind对样式增强的操作v-model应用于其他表单元素 2.computed计算属性 基础语法计算属性vs方法计算属性的完整写法成绩案例 3.watch侦听器 基础写法完整写法 4.综合案例 &#xff08;演示&#xff09; 渲染 / 删除 / 修…

ctf杂项总结

1.文件无法打开 1.1.文件拓展名损坏/错误导致 方法&#xff1a; 1.使用kali当中的file命令查看&#xff0c;之后修改为正确的后缀即可 2.通过16进制编辑器打开查看文件头 3.文件头残缺/错误&#xff0c;可以先使用kail当中的file命令查看它的类型&#xff0c;之后再通过 16…

[SAP ABAP] 数值向上/向下取整

ceil()函数对数值进行向上取整&#xff0c;floor()函数对数值进行向下取整 输出结果&#xff1a;