分享一个在局域网红外遥控格力空调与风扇的源码
经常坐在电脑面前打游戏工作的时候,打开天猫精灵广告多,步骤麻烦,语音设别率低。所以就打算搞了这么一个东西。可以在电脑或者手机浏览器直接控制空调和风扇就很方便。
控制方法。有两种输入ESP8266的ip地址就直接跳转到控制面板。
还有就是安装浏览器扩展,设置好ESP8266的ip就可以直接控制
#include "IR-AC-control.h"
#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266WebServer.h>
#endif // ESP8266
#if defined(ESP32)
#include <ESPmDNS.h>
#include <WebServer.h>
#include <WiFi.h>
#include <Update.h>
#endif // ESP32
//天气
#include <Ticker.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <NTPClient.h>
//天气
#include <WiFiUdp.h>
#include <WiFiManager.h>
#include <ArduinoJson.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ArduinoOTA.h>
//空调品牌设置 可以修改成自己空调品牌的.h文件和静态变量,IRremoteESP8266库里面可以找到
#include "ir_Gree.h"
#define AUTO_MODE kGreeAuto
#define COOL_MODE kGreeCool
#define DRY_MODE kGreeDry
#define HEAT_MODE kGreeHeat
#define FAN_MODE kGreeFan
#define FAN_AUTO kGreeFanAuto
#define FAN_MIN kGreeFanMin
#define FAN_MED kGreeFanMed
#define FAN_HI kGreeFanMax
//空调品牌
const uint16_t kIrLed = 4;
IRGreeAC ac(kIrLed);
IRsend irsend(kIrLed);
//天气
Ticker ticker;
int count, old_h;
bool check_temp; //气温检查开关。晚点到一定的气温,会关闭风扇,晚上睡觉经常谁到感冒,要申请高德天气key才可以使用
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
int temparr = {3, 4, 5, 6, 7};//检查气温的时间
int openTemp;
//天气
struct state
{
uint8_t Swingmode = 1, temperature = 27, fan = 0, operation = 1;
bool powerStatus;
};
uint16_t fanPower = {1166, 432, 1164, 462, 314, 1312, 1110, 490, 1136, 462, 314, 1312, 314, 1310, 316, 1312, 314, 1310, 314, 1310, 314, 1312, 1138, 7014, 1164, 462, 1138, 462, 314, 1310, 1138, 462, 1138, 462, 316, 1286, 340, 1284, 338, 1290, 338, 1284, 340, 1286, 338, 1312, 1138, 7014, 1166, 486, 1140, 512, 316, 1310, 1138, 488, 1138, 462, 314, 1288, 338, 1286, 340, 1284, 340, 1284, 342, 1284, 340, 1288, 1162, 7014, 1164, 488, 1136, 464, 314, 1284, 1164, 462, 1138, 438, 338, 1284, 342, 1282, 342, 1284, 342, 1284, 340, 1286, 342, 1284, 1164, 7014, 1138, 466, 1164, 436, 340, 1286, 1164, 436, 1164, 462, 340, 1282, 344, 1284, 342, 1284, 342, 1282, 342, 1284, 342, 1284, 1166, 7016, 1136, 462, 1164, 436, 342, 1284, 1164, 436, 1138, 462, 342, 1284, 340, 1286, 340, 1286, 338, 1288, 340, 1286, 316, 1308, 1162, 7016, 1162, 464, 1162, 490, 314, 1312, 1160, 440, 1164, 462, 310, 1312, 312, 1314, 312, 1314, 312, 1314, 312, 1314, 312, 1312, 1162, 7018, 1162, 438, 1160, 460, 316, 1290, 1160, 488, 1138, 462, 314, 1314, 314, 1310, 314, 1312, 314, 1310, 316, 1310, 314, 1312, 1138};
uint16_t fanSleep = {1166, 482, 1138, 486, 316, 1336, 1138, 486, 1140, 486, 316, 1308, 316, 1286, 340, 1308, 316, 1310, 314, 1310, 1136, 490, 316, 7840, 1164, 486, 1114, 510, 316, 1310, 1138, 512, 1138, 486, 316, 1284, 342, 1286, 340, 1286, 340, 1310, 314, 1310, 1138, 488, 314, 7838, 1164, 486, 1140, 486, 316, 1310, 1138, 512, 1138, 488, 316, 1312, 314, 1282, 342, 1312, 316, 1286, 340, 1312, 1138, 486, 316, 7864, 1166, 486, 1138, 488, 314, 1286, 1164, 512, 1138, 488, 314, 1284, 342, 1284, 342, 1312, 340, 1284, 342, 1284, 1164, 514, 314, 7842, 1164, 514, 1138, 486, 316, 1284, 1166, 514, 1114, 512, 314, 1284, 342, 1284, 342, 1284, 344, 1280, 344, 1282, 1166, 458, 342, 7838, 1164, 486, 1164, 460, 342, 1282, 1140, 484, 1166, 460, 342, 1308, 340, 1286, 340, 1286, 340, 1312, 342, 1310, 1172, 452, 344};
uint16_t fanSwing = {1166, 484, 1112, 512, 316, 1336, 1136, 516, 1126, 500, 314, 1310, 316, 1310, 1112, 514, 314, 1312, 314, 1312, 314, 1308, 316, 7838, 1164, 486, 1138, 462, 314, 1308, 1140, 486, 1138, 488, 316, 1308, 316, 1312, 1138, 486, 316, 1310, 342, 1310, 314, 1310, 316, 7838, 1138, 540, 1116, 510, 316, 1310, 1140, 486, 1138, 486, 316, 1312, 316, 1310, 1114, 512, 316, 1312, 314, 1312, 314, 1310, 316, 7838, 1166, 512, 1116, 510, 316, 1288, 1160, 486, 1116, 510, 316, 1310, 316, 1336, 1116, 510, 316, 1312, 314, 1336, 314, 1292, 336, 7840, 1138, 514, 1116, 510, 316, 1288, 1138, 510, 1116, 510, 316, 1286, 342, 1288, 1136, 514, 316, 1314, 338, 1286, 340, 1310, 340, 7842, 1138, 540, 1114, 510, 316, 1284, 1138, 516, 1138, 488, 316, 1284, 342, 1286, 1136, 516, 314, 1286, 340, 1312, 340, 1284, 342};
uint16_t fanMode = {1166, 484, 1168, 458, 316, 1310, 1138, 462, 1138, 486, 314, 1310, 316, 1308, 314, 1310, 316, 1310, 1166, 460, 314, 1310, 314, 7862, 1166, 436, 1164, 488, 314, 1310, 1138, 488, 1136, 490, 314, 1310, 316, 1310, 314, 1312, 314, 1310, 1138, 488, 314, 1310, 316, 7840, 1160, 486, 1116, 510, 316, 1310, 1136, 486, 1140, 486, 314, 1310, 316, 1310, 314, 1308, 316, 1310, 1138, 488, 314, 1310, 316, 7838, 1162, 488, 1138, 488, 314, 1312, 1140, 460, 1188, 462, 316, 1308, 316, 1310, 316, 1312, 314, 1310, 1138, 488, 316, 1284, 340, 7840, 1162, 492, 1134, 492, 314, 1286, 1164, 486, 1114, 512, 316, 1338, 312, 1312, 314, 1312, 316, 1284, 1162, 490, 316, 1312, 314, 7842, 1162, 516, 1110, 518, 316, 1288, 1160, 466, 1156, 492, 316, 1286, 338, 1338, 314, 1310, 314, 1286, 1160, 492, 316, 1284, 342};
File fsUploadFile;
state acState;
char deviceName[] = "AC Remote Control";
#if defined(ESP8266)
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdateServer;
#endif // ESP8266
#if defined(ESP32)
WebServer server(80);
#endif // ESP32
//天气
void updateTime()
{
timeClient.update();
Serial.print("校准时间");
Serial.println(timeClient.getFormattedTime());
}
void tickerCount()
{
count++;
}
void getTemp()
{
std::unique_ptr<BearSSL::WiFiClientSecure> client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
if (https.begin(*client, "https://restapi.amap.com/v3/weather/weatherInfo?city=450105&key=高德天气key"))
{ // HTTPS
int httpCode = https.GET();
if (httpCode > 0)
{
Serial.printf(" GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
{
String payload = https.getString();
Serial.println(payload);
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
JsonObject lives_0 = doc["lives"];
const char *info_weather = lives_0["weather"]; // "多云"
int temperature = lives_0["temperature"].as<int>();
if (temperature <= openTemp)
{
int currentHour = timeClient.getHours();
int i = 0;
while (i <= 5)
{
if (temparr == currentHour)
{
irsend.sendRaw(fanPower, 191, 38);
Serial.println("条件满足");
}
i++;
}
}
check_temp = true;
}
}
else
{
Serial.printf(" GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
}
else
{
Serial.printf(" Unable to connect\n");
}
}
//天气
bool handleFileRead(String path)
{
if (path.endsWith("/"))
path += "index.html";
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if (FILESYSTEM.exists(pathWithGz) || FILESYSTEM.exists(path))
{
if (FILESYSTEM.exists(pathWithGz))
path += ".gz";
File file = FILESYSTEM.open(path, "r");
server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
String getContentType(String filename)
{
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(".ico"))
return "image/x-icon";
else if (filename.endsWith(".gz"))
return "application/x-gzip";
return "text/plain";
}
void handleFileUpload()
{
HTTPUpload &upload = server.upload();
if (upload.status == UPLOAD_FILE_START)
{
String filename = upload.filename;
if (!filename.startsWith("/"))
filename = "/" + filename;
fsUploadFile = FILESYSTEM.open(filename, "w");
filename = String();
}
else if (upload.status == UPLOAD_FILE_WRITE)
{
if (fsUploadFile)
fsUploadFile.write(upload.buf, upload.currentSize);
}
else if (upload.status == UPLOAD_FILE_END)
{
if (fsUploadFile)
{
fsUploadFile.close();
server.sendHeader("Location", "/success.html");
server.send(303);
}
else
{
server.send(500, "text/plain", "500: couldn't create file");
}
}
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++)
{
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
void setup()
{
Serial.begin(115200);
Serial.println();
ac.begin();
delay(1000);
Serial.println("mounting " FILESYSTEMSTR "...");
if (!FILESYSTEM.begin())
{
return;
}
WiFiManager wifiManager;
if (!wifiManager.autoConnect(deviceName))
{
delay(3000);
ESP.restart();
delay(5000);
}
#if defined(ESP8266)
httpUpdateServer.setup(&server);
#endif // ESP8266
//设置空调
server.on("/state", HTTP_POST, []()
{
DynamicJsonDocument root(1024);
DeserializationError error = deserializeJson(root, server.arg("plain"));
if (error) {
server.send(404, "text/plain", "FAIL. " + server.arg("plain"));
} else {
if (root.containsKey("temp")) {
acState.temperature = (uint8_t) root["temp"];
}
if (root.containsKey("fan")) {
acState.fan = (uint8_t) root["fan"];
}
if (root.containsKey("power")) {
acState.powerStatus = root["power"];
}
if (root.containsKey("mode")){
acState.operation = root["mode"];
}
if (root.containsKey("Swingmode")){
acState.Swingmode = (uint8_t) root["Swingmode"];
}
String output;
serializeJson(root, output);
server.send(200, "text/plain", output);
delay(200);
if (acState.powerStatus) {
ac.on();
ac.setTemp(acState.temperature);
if (acState.operation == 0) {
ac.setMode(AUTO_MODE);
ac.setFan(FAN_AUTO);
acState.fan = 0;
} else if (acState.operation == 1) {
ac.setMode(COOL_MODE);
} else if (acState.operation == 2) {
ac.setMode(DRY_MODE);
} else if (acState.operation == 3) {
ac.setMode(HEAT_MODE);
} else if (acState.operation == 4) {
ac.setMode(FAN_MODE);
}
if (acState.operation != 0) {
if (acState.fan == 0) {
ac.setFan(FAN_AUTO);
} else if (acState.fan == 1) {
ac.setFan(FAN_MIN);
} else if (acState.fan == 2) {
ac.setFan(FAN_MED);
} else if (acState.fan == 3) {
ac.setFan(FAN_HI);
}
if (acState.Swingmode == 1 || acState.Swingmode == 11 || acState.Swingmode == 9 || acState.Swingmode == 7 ) {
ac.setSwingVertical(true, acState.Swingmode);
} else{
ac.setSwingVertical(false, acState.Swingmode);
}
}
} else {
ac.off();
}
ac.send();
} });
//风扇
server.on("/fan", HTTP_GET, []()
{
if (server.arg("state") =="0")
{
irsend.sendRaw(fanPower, 191, 38);
}
else if (server.arg("state") == "1")
{
irsend.sendRaw(fanSwing, 143, 38);
}
else if (server.arg("state") == "2")
{
irsend.sendRaw(fanMode, 143, 38);
}
else if (server.arg("state") == "3")
{
irsend.sendRaw(fanSleep, 143, 38);
}
server.send(200, "text/html", "ok"); });
//文件上传
server.on(
"/up", HTTP_POST,
[]()
{
server.send(200);
},
handleFileUpload);
server.on("/up", HTTP_GET, []()
{
String html = "<form method=\"post\" enctype=\"multipart/form-data\">";
html += "<input type=\"file\" name=\"name\">";
html += "<input class=\"button\" type=\"submit\" value=\"Upload\">";
html += "</form>";
server.send(200, "text/html", html); });
server.on("/", []()
{
server.sendHeader("Location", String("index.html"), true);
server.send(302, "text/plain", ""); });
server.on("/tq", HTTP_GET, []() {server.send(200, "text/plain",String(openTemp) +"="+String(check_temp)); });
server.on("/tianqi", HTTP_GET, []() {
String t_tmp =server.arg("opentemp");
openTemp=t_tmp.toInt();
if (server.arg("weather")=="true")
{
check_temp=true;
}else{
check_temp=false;
}
server.send(200, "text/plain", "ok"); });
//返回空调设置
server.on("/state", HTTP_GET, []()
{
DynamicJsonDocument root(1024);
root["mode"] = acState.operation;
root["fan"] = acState.fan;
root["temp"] = acState.temperature;
root["power"] = acState.powerStatus;
root["Swingmode"] = acState.Swingmode;
String output;
serializeJson(root, output);
server.send(200, "text/plain", output); });
server.on("/reset", []()
{
server.send(200, "text/html", "reset");
delay(100);
ESP.restart(); });
server.serveStatic("/", FILESYSTEM, "/", "max-age=86400");
server.enableCORS(true);
server.onNotFound(handleNotFound);
server.begin();
ArduinoOTA.setHostname("ESP8266");
ArduinoOTA.setPassword("12345678");
ArduinoOTA.begin();
//天气
timeClient.begin();
ticker.attach(1, tickerCount);
openTemp=27;
}
void loop()
{
server.handleClient();
ArduinoOTA.handle();
if (count >= 1800 && check_temp)
{
updateTime();
delay(1000);
getTemp();
count = 0;
}
}
优秀!太棒了,羡慕! 什么时候我能像你这么优秀;P 库有吗?有些找不到 没有库咋整 能发一份给我吗965153391@qq.com
页:
[1]