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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1097|回复: 5

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

[复制链接]
发表于 2022-8-31 13:38 | 显示全部楼层 |阅读模式
经常坐在电脑面前打游戏工作的时候,打开天猫精灵广告多,步骤麻烦,语音设别率低。所以就打算搞了这么一个东西。
可以在电脑或者手机浏览器直接控制空调和风扇就很方便。
控制方法。有两种输入ESP8266的ip地址就直接跳转到控制面板。
还有就是安装浏览器扩展,设置好ESP8266的ip就可以直接控制

浏览器扩展

浏览器扩展
QQ截图20220831104657.png 完整源码.zip (264.83 KB, 下载次数: 25)
  1. #include "IR-AC-control.h"
  2. #if defined(ESP8266)
  3. #include <ESP8266WiFi.h>
  4. #include <ESP8266mDNS.h>
  5. #include <ESP8266HTTPUpdateServer.h>
  6. #include <ESP8266WebServer.h>
  7. #endif // ESP8266
  8. #if defined(ESP32)
  9. #include <ESPmDNS.h>
  10. #include <WebServer.h>
  11. #include <WiFi.h>
  12. #include <Update.h>
  13. #endif // ESP32
  14. //天气  
  15. #include <Ticker.h>
  16. #include <ESP8266HTTPClient.h>
  17. #include <WiFiClientSecureBearSSL.h>
  18. #include <NTPClient.h>
  19. //天气

  20. #include <WiFiUdp.h>
  21. #include <WiFiManager.h>
  22. #include <ArduinoJson.h>
  23. #include <IRremoteESP8266.h>
  24. #include <IRsend.h>
  25. #include <ArduinoOTA.h>


  26. //空调品牌设置   可以修改成自己空调品牌的.h文件和静态变量,IRremoteESP8266库里面可以找到
  27. #include "ir_Gree.h"
  28. #define AUTO_MODE kGreeAuto
  29. #define COOL_MODE kGreeCool
  30. #define DRY_MODE kGreeDry
  31. #define HEAT_MODE kGreeHeat
  32. #define FAN_MODE kGreeFan
  33. #define FAN_AUTO kGreeFanAuto
  34. #define FAN_MIN kGreeFanMin
  35. #define FAN_MED kGreeFanMed
  36. #define FAN_HI kGreeFanMax
  37. //空调品牌




  38. const uint16_t kIrLed = 4;
  39. IRGreeAC ac(kIrLed);
  40. IRsend irsend(kIrLed);
  41. //天气
  42. Ticker ticker;
  43. int count, old_h;
  44. bool check_temp; //气温检查开关。晚点到一定的气温,会关闭风扇,晚上睡觉经常谁到感冒,要申请高德天气key才可以使用
  45. WiFiUDP ntpUDP;
  46. NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
  47. int temparr[5] = {3, 4, 5, 6, 7};//检查气温的时间
  48. int openTemp;
  49. //天气
  50. struct state
  51. {
  52.     uint8_t Swingmode = 1, temperature = 27, fan = 0, operation = 1;
  53.     bool powerStatus;
  54. };

  55. uint16_t fanPower[191] = {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};
  56. uint16_t fanSleep[143] = {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};
  57. uint16_t fanSwing[143] = {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};
  58. uint16_t fanMode[143] = {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};

  59. File fsUploadFile;
  60. state acState;

  61. char deviceName[] = "AC Remote Control";
  62. #if defined(ESP8266)
  63. ESP8266WebServer server(80);
  64. ESP8266HTTPUpdateServer httpUpdateServer;
  65. #endif // ESP8266
  66. #if defined(ESP32)
  67. WebServer server(80);
  68. #endif // ESP32

  69. //天气
  70. void updateTime()
  71. {
  72.     timeClient.update();
  73.     Serial.print("校准时间");
  74.     Serial.println(timeClient.getFormattedTime());
  75. }

  76. void tickerCount()
  77. {
  78.     count++;
  79. }

  80. void getTemp()
  81. {
  82.     std::unique_ptr<BearSSL::WiFiClientSecure> client(new BearSSL::WiFiClientSecure);
  83.     client->setInsecure();
  84.     HTTPClient https;

  85.     if (https.begin(*client, "https://restapi.amap.com/v3/weather/weatherInfo?city=450105&key=高德天气key"))
  86.     { // HTTPS
  87.         int httpCode = https.GET();
  88.         if (httpCode > 0)
  89.         {
  90.             Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
  91.             if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
  92.             {
  93.                 String payload = https.getString();
  94.                 Serial.println(payload);
  95.                 StaticJsonDocument<512> doc;
  96.                 DeserializationError error = deserializeJson(doc, payload);
  97.                 if (error)
  98.                 {
  99.                     Serial.print(F("deserializeJson() failed: "));
  100.                     Serial.println(error.f_str());
  101.                     return;
  102.                 }
  103.                 JsonObject lives_0 = doc["lives"][0];
  104.                 const char *info_weather = lives_0["weather"]; // "多云"
  105.                 int temperature = lives_0["temperature"].as<int>();

  106.                 if (temperature <= openTemp)
  107.                 {

  108.                     int currentHour = timeClient.getHours();
  109.                     int i = 0;
  110.                     while (i <= 5)
  111.                     {

  112.                         if (temparr[i] == currentHour)
  113.                         {     
  114.                             irsend.sendRaw(fanPower, 191, 38);
  115.                             Serial.println("条件满足");
  116.                         }

  117.                         i++;
  118.                     }
  119.                 }
  120.                 check_temp = true;
  121.             }
  122.         }
  123.         else
  124.         {
  125.             Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
  126.         }
  127.         https.end();
  128.     }
  129.     else
  130.     {
  131.         Serial.printf("[HTTPS] Unable to connect\n");
  132.     }
  133. }

  134. //天气
  135. bool handleFileRead(String path)
  136. {
  137.     if (path.endsWith("/"))
  138.         path += "index.html";
  139.     String contentType = getContentType(path);
  140.     String pathWithGz = path + ".gz";
  141.     if (FILESYSTEM.exists(pathWithGz) || FILESYSTEM.exists(path))
  142.     {
  143.         if (FILESYSTEM.exists(pathWithGz))
  144.             path += ".gz";
  145.         File file = FILESYSTEM.open(path, "r");
  146.         server.streamFile(file, contentType);
  147.         file.close();
  148.         return true;
  149.     }
  150.     return false;
  151. }

  152. String getContentType(String filename)
  153. {
  154.     if (filename.endsWith(".html"))
  155.         return "text/html";
  156.     else if (filename.endsWith(".css"))
  157.         return "text/css";
  158.     else if (filename.endsWith(".js"))
  159.         return "application/javascript";
  160.     else if (filename.endsWith(".ico"))
  161.         return "image/x-icon";
  162.     else if (filename.endsWith(".gz"))
  163.         return "application/x-gzip";
  164.     return "text/plain";
  165. }

  166. void handleFileUpload()
  167. {
  168.     HTTPUpload &upload = server.upload();
  169.     if (upload.status == UPLOAD_FILE_START)
  170.     {
  171.         String filename = upload.filename;
  172.         if (!filename.startsWith("/"))
  173.             filename = "/" + filename;
  174.         fsUploadFile = FILESYSTEM.open(filename, "w");
  175.         filename = String();
  176.     }
  177.     else if (upload.status == UPLOAD_FILE_WRITE)
  178.     {
  179.         if (fsUploadFile)
  180.             fsUploadFile.write(upload.buf, upload.currentSize);
  181.     }
  182.     else if (upload.status == UPLOAD_FILE_END)
  183.     {
  184.         if (fsUploadFile)
  185.         {
  186.             fsUploadFile.close();
  187.             server.sendHeader("Location", "/success.html");
  188.             server.send(303);
  189.         }
  190.         else
  191.         {
  192.             server.send(500, "text/plain", "500: couldn't create file");
  193.         }
  194.     }
  195. }

  196. void handleNotFound()
  197. {
  198.     String message = "File Not Found\n\n";
  199.     message += "URI: ";
  200.     message += server.uri();
  201.     message += "\nMethod: ";
  202.     message += (server.method() == HTTP_GET) ? "GET" : "POST";
  203.     message += "\nArguments: ";
  204.     message += server.args();
  205.     message += "\n";
  206.     for (uint8_t i = 0; i < server.args(); i++)
  207.     {
  208.         message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  209.     }
  210.     server.send(404, "text/plain", message);
  211. }
  212. void setup()
  213. {
  214.      Serial.begin(115200);
  215.      Serial.println();
  216.     ac.begin();
  217.     delay(1000);
  218.     Serial.println("mounting " FILESYSTEMSTR "...");
  219.     if (!FILESYSTEM.begin())
  220.     {
  221.         return;
  222.     }
  223.     WiFiManager wifiManager;
  224.     if (!wifiManager.autoConnect(deviceName))
  225.     {
  226.         delay(3000);
  227.         ESP.restart();
  228.         delay(5000);
  229.     }
  230. #if defined(ESP8266)
  231.     httpUpdateServer.setup(&server);
  232. #endif // ESP8266
  233.     //设置空调
  234.     server.on("/state", HTTP_POST, []()
  235.               {
  236.     DynamicJsonDocument root(1024);
  237.     DeserializationError error = deserializeJson(root, server.arg("plain"));
  238.     if (error) {
  239.       server.send(404, "text/plain", "FAIL. " + server.arg("plain"));
  240.     } else {
  241.       if (root.containsKey("temp")) {
  242.         acState.temperature = (uint8_t) root["temp"];
  243.       }
  244.       if (root.containsKey("fan")) {
  245.         acState.fan = (uint8_t) root["fan"];
  246.       }
  247.       if (root.containsKey("power")) {
  248.         acState.powerStatus = root["power"];
  249.       }
  250.       if (root.containsKey("mode"))  {
  251.       acState.operation = root["mode"];
  252.       }

  253.       if (root.containsKey("Swingmode"))  {
  254.         acState.Swingmode = (uint8_t) root["Swingmode"];
  255.       }




  256.       String output;
  257.       serializeJson(root, output);
  258.       server.send(200, "text/plain", output);
  259.       delay(200);
  260.       if (acState.powerStatus) {
  261.       ac.on();
  262.         ac.setTemp(acState.temperature);
  263.         if (acState.operation == 0) {
  264.           ac.setMode(AUTO_MODE);
  265.           ac.setFan(FAN_AUTO);
  266.           acState.fan = 0;
  267.         } else if (acState.operation == 1) {
  268.           ac.setMode(COOL_MODE);
  269.         } else if (acState.operation == 2) {
  270.           ac.setMode(DRY_MODE);
  271.         } else if (acState.operation == 3) {
  272.           ac.setMode(HEAT_MODE);
  273.         } else if (acState.operation == 4) {
  274.           ac.setMode(FAN_MODE);
  275.         }
  276.         if (acState.operation != 0) {
  277.           if (acState.fan == 0) {
  278.             ac.setFan(FAN_AUTO);
  279.           } else if (acState.fan == 1) {
  280.             ac.setFan(FAN_MIN);
  281.           } else if (acState.fan == 2) {
  282.             ac.setFan(FAN_MED);
  283.           } else if (acState.fan == 3) {
  284.             ac.setFan(FAN_HI);
  285.           }

  286.           if (acState.Swingmode == 1 || acState.Swingmode == 11 || acState.Swingmode == 9 || acState.Swingmode == 7 ) {
  287.             ac.setSwingVertical(true, acState.Swingmode);
  288.           } else  {
  289.             ac.setSwingVertical(false, acState.Swingmode);
  290.           }

  291.         }

  292.       } else {
  293.         ac.off();
  294.       }
  295.       ac.send();
  296.     } });
  297.     //风扇
  298.     server.on("/fan", HTTP_GET, []()
  299.               {
  300.     if (server.arg("state") =="0")
  301.     {
  302.       irsend.sendRaw(fanPower, 191, 38);
  303.     }
  304.     else if (server.arg("state") == "1")
  305.     {
  306.       irsend.sendRaw(fanSwing, 143, 38);
  307.     }
  308.     else if (server.arg("state") == "2")
  309.     {
  310.       irsend.sendRaw(fanMode, 143, 38);
  311.     }
  312.     else if (server.arg("state") == "3")
  313.     {
  314.       irsend.sendRaw(fanSleep, 143, 38);
  315.     }
  316.     server.send(200, "text/html", "ok"); });
  317.     //文件上传
  318.     server.on(
  319.         "/up", HTTP_POST,
  320.         []()
  321.         {
  322.             server.send(200);
  323.         },
  324.         handleFileUpload);
  325.     server.on("/up", HTTP_GET, []()
  326.               {

  327.     String html = "<form method="post" enctype="multipart/form-data">";
  328.     html += "<input type="file" name="name">";
  329.     html += "<input class="button" type="submit" value="Upload">";
  330.     html += "</form>";
  331.     server.send(200, "text/html", html); });

  332.     server.on("/", []()
  333.               {
  334.     server.sendHeader("Location", String("index.html"), true);
  335.     server.send(302, "text/plain", ""); });

  336. server.on("/tq", HTTP_GET, []() {  server.send(200, "text/plain",String(openTemp) +"="+String(check_temp)); });
  337.    
  338. server.on("/tianqi", HTTP_GET, []() {
  339.     String t_tmp =server.arg("opentemp");
  340.     openTemp=t_tmp.toInt();

  341.     if (server.arg("weather")=="true")
  342.     {
  343.         check_temp=true;
  344.     }else{
  345.          check_temp=false;
  346.     }
  347.    

  348.     server.send(200, "text/plain", "ok"); });

  349.     //返回空调设置
  350.     server.on("/state", HTTP_GET, []()
  351.               {
  352.     DynamicJsonDocument root(1024);
  353.     root["mode"] = acState.operation;
  354.     root["fan"] = acState.fan;
  355.     root["temp"] = acState.temperature;
  356.     root["power"] = acState.powerStatus;
  357.     root["Swingmode"] = acState.Swingmode;

  358.     String output;
  359.     serializeJson(root, output);
  360.     server.send(200, "text/plain", output); });
  361.     server.on("/reset", []()
  362.               {
  363.     server.send(200, "text/html", "reset");
  364.     delay(100);
  365.     ESP.restart(); });
  366.     server.serveStatic("/", FILESYSTEM, "/", "max-age=86400");
  367.     server.enableCORS(true);
  368.     server.onNotFound(handleNotFound);
  369.     server.begin();
  370.    ArduinoOTA.setHostname("ESP8266");
  371.    ArduinoOTA.setPassword("12345678");
  372.    ArduinoOTA.begin();
  373.    //天气
  374.     timeClient.begin();
  375.     ticker.attach(1, tickerCount);
  376.     openTemp=27;
  377. }

  378. void loop()
  379. {
  380.     server.handleClient();
  381.     ArduinoOTA.handle();
  382.     if (count >= 1800 && check_temp)
  383.     {

  384.         updateTime();
  385.         delay(1000);
  386.         getTemp();
  387.         count = 0;
  388.     }
  389. }
复制代码


手机浏览器

手机浏览器
发表于 2022-9-27 21:51 来自手机 | 显示全部楼层
优秀!太棒了,羡慕!
发表于 2022-9-28 11:24 | 显示全部楼层
什么时候我能像你这么优秀
发表于 2022-10-2 21:42 来自手机 | 显示全部楼层
库有吗?有些找不到
发表于 2022-10-12 10:13 | 显示全部楼层
没有库咋整
发表于 2022-10-12 10:14 | 显示全部楼层
能发一份给我吗965153391@qq.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 05:51 , Processed in 0.078050 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表