分享一个在局域网红外遥控格力空调与风扇的源码-Arduino中文社区 - Powered by Discuz! Archiver

jjhx526 发表于 2022-8-31 13:38

分享一个在局域网红外遥控格力空调与风扇的源码

经常坐在电脑面前打游戏工作的时候,打开天猫精灵广告多,步骤麻烦,语音设别率低。所以就打算搞了这么一个东西。
可以在电脑或者手机浏览器直接控制空调和风扇就很方便。
控制方法。有两种输入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;
    }
}


chenhao189 发表于 2022-9-27 21:51

优秀!太棒了,羡慕!

尺素丶 发表于 2022-9-28 11:24

什么时候我能像你这么优秀;P

chenhao189 发表于 2022-10-2 21:42

库有吗?有些找不到

chenhao189 发表于 2022-10-12 10:13

没有库咋整

chenhao189 发表于 2022-10-12 10:14

能发一份给我吗965153391@qq.com
页: [1]
查看完整版本: 分享一个在局域网红外遥控格力空调与风扇的源码