整体实现(1.0版本)
- arduino IDE部分:
一. 包含库的调用和创建对象
- 库的安装在此不做赘述,可参考太极创客esp8266教程
- 如果是其他空调,库函数调用是记得更改<ir_Gree.h>为所需空调库,具体库文件详情可在此查看
#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi库
#include <ESP8266WiFiMulti.h> // 本程序使用ESP8266WiFiMulti库
#include <ESP8266WebServer.h> // 本程序使用ESP8266WebServer库
#include <FS.h> // 本程序使用SPIFFS库
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Gree.h>
const uint16_t kIrLed = 2;
IRGreeAC ac(kIrLed,YBOFB);
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
ESP8266WebServer esp8266_server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
二.主体程序
/*设置空调开启时的各个状态,传入参数tem为设置温度,目前对于温度调节和其他调节还没整出网页,所以暂时只具备开关机功能*/
void handleset(int tem){
ac.setModel(YBOFB);
ac.begin();
ac.on();
gree_ac_remote_model_t getModel(void);
ac.setMode(kGreeCool);
ac.setTemp(tem);
ac.setSwingVertical(false, kGreeSwingAuto);
ac.setFan(2);
ac.setLight(true);
ac.send();
}
void setup(){
Serial.begin(9600); //启动串口通讯
Serial.println("");
//通过addAp函数存储 WiFi名称 WiFi密码
wifiMulti.addAP("WiFi账号", "密码"); //*将需要连接的一系列WiFi ID和密码输入这里,其实可以直接用WiFi库创建的对象建立连接,用我这种方式可以从多个网络中选择网络信号强的连接*,记得更改为自家网络账号密码/
Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { // 在当前环境中搜索addAP函数所存储的WiFi
delay(1000); // 如果搜到多个存储的WiFi那么NodeMCU
Serial.print(i++); Serial.print('.'); // 将会连接信号最强的那一个WiFi信号。
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n'); // WiFi连接成功后
Serial.print("Connected to "); // NodeMCU将通过串口监视器输出。
Serial.println(WiFi.SSID()); // 连接的WiFI名称
Serial.print("IP address:\t"); // 以及
Serial.println(WiFi.localIP()); // NodeMCU的IP地址
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");//输出启动状态,表明启动与否
}
esp8266_server.on("/AC-open", handleLEDControl1);// 告知系统如何处理AC-open请求
//注意,由调用的闪存文件在根目录下(用“/”表示),所以后续调用网页文件的时候是从根目录下调用,废话这么多,想强调的是注意文件存储的相对位置
esp8266_server.on("/AC-close", handleLEDControl2);// 告知系统如何处理AC-close请求
esp8266_server.onNotFound(handleUserRequest); // 告知系统如何处理其它用户请求
esp8266_server.begin(); // 启动网站服务
Serial.println("HTTP server started");
}
void loop(){
esp8266_server.handleClient(); //处理用户请求
}
// 处理/LED-Control请求
void handleLEDControl1(){
handleset(25);//启动空调并设置温度为25°C
esp8266_server.sendHeader("Location", "/AC.html");
esp8266_server.send(303); //执行完毕再次回到初始页面
//本人web知识比较薄弱,正在攻关中,目前只会通过这种类似刷新的方式向esp8266传递指令
}
void handleLEDControl2(){
ac.off();//关闭空调指令
ac.send();//空调指令发送,必须有,才能发送信息
esp8266_server.sendHeader("Location", "/AC.html");
esp8266_server.send(303); //同上
}
// 处理用户浏览器的HTTP访问
void handleUserRequest() {
/*由于刚开始调用闪存文件时,是调用根目录文件,此时是“/”,然而我们设置的主页却在根目录下“/AC.html”,所以第一次执行时,会调用此函数,我们知道的是,调用“/”时,由于根目录文件下还有文件,所以网页此时是不能正常打开与运行的,所以在第一次调用此函数是,我们需要运用一个函数(handleFileRead)来调用我们需要的,存储在根目录下的网页文件*/
// 获取用户请求资源(Request Resource)
String reqResource = esp8266_server.uri();//相当于将访问网页的url赋值给reqResource
Serial.print("reqResource: ");
Serial.println(reqResource);
// 通过handleFileRead函数处处理用户请求资源
bool fileReadOK = handleFileRead(reqResource);
// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)
if (!fileReadOK){
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) { //处理浏览器HTTP访问
if (resource.endsWith("/")) { // 如果访问地址以"/"为结尾
resource = "/AC.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
}
String contentType = getContentType(resource); // 获取文件类型
if (SPIFFS.exists(resource)) { // 如果访问的文件可以在SPIFFS中找到
File file = SPIFFS.open(resource, "r"); // 则尝试打开该文件
esp8266_server.streamFile(file, contentType);// 并且将该文件返回给浏览器
file.close(); // 并且关闭文件
return true; // 返回true
}
return false; // 如果文件未找到,则返回false
}
// 获取文件类型
String getContentType(String filename){
if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
三.网页文件
- 内容很简单,其中的相机网址是我远程观看空调状态的一种方法
- 由于我这网络环境特殊,在校园内,宿舍wifi和学校提供的通用wifi在一个内网,所以省去了内网穿透的需要,如果道友想要在户外控制家中的空调,建议道友查查如何进行内网穿透,怕折腾选择花生壳就好,一个人月几块钱;
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>格力空调1.0</title>
</head>
<body>
<center>
<h1>空调</h1>
<form action="AC-open"><input type="submit" value="开机">
</form>
<br>
<form action="AC-close"><input type="submit" value="关机">
</form>
<br>
<form action="index.html"><input type="submit" value="返回首页">
</form>
<p>相机网址 <a href="http://192.168.31.17" target="_black">http://192.168.31.17</a>
</center>
</body>
</html>
四.最后
- 在此要非常感谢太极创客团队给我们这些小白进行的免费知识普及,可谓吾师矣,希望团队可以越做越强!
- 后续还会对程序进行进一步完善,目前准备先再看看web前端和小程序开发,做出一套完备方案出来,或许可以为毕设做准备?至于安卓软件和ios软件开发,或许要我寒假去学学看了。