当前位置:   article > 正文

esp32联网获取时间和天气(四)_platformio esp32获取时间和天气

platformio esp32获取时间和天气

说明

本章节需要先学习之前(三)中获取当前时间方法,本文基于platformIO,需提前安装timelib库,可以参考之前(三)

代码

代码如下,需要一点http知识,可以自行百度

  1. #include <WiFi.h>
  2. #include <HTTPClient.h>
  3. #include <Arduino.h>
  4. #include <TimeLib.h>
  5. #include <WiFiUdp.h>
  6. void getCityCode(); // 发送HTTP请求并且将服务器响应通过串口输出
  7. void getCityWeater();
  8. time_t getNtpTime();
  9. void sendNTPpacket(IPAddress &address);
  10. /* *****************************************************************
  11. * 参数设置
  12. * *****************************************************************/
  13. // NTP Servers:
  14. static const char ntpServerName[] = "ntp6.aliyun.com"; // 阿里云的时间服务器
  15. /* NTP设置 */
  16. const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
  17. byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming & outgoing packets
  18. const int timeZone = 8; // 时区
  19. WiFiUDP Udp;
  20. unsigned int localPort = 8888; // local port to listen for UDP packets
  21. struct config_type
  22. {
  23. char stassid[32]; // 定义配网得到的WIFI名长度(最大32字节)
  24. char stapsw[64]; // 定义配网得到的WIFI密码长度(最大64字节)
  25. };
  26. config_type wificonf = {{"PDCN"}, {"1234567890"}};
  27. unsigned int updateweater_time = 30000;
  28. struct Weather_Msg
  29. {
  30. String cityDZ;
  31. String dataSK;
  32. String dataFC;
  33. };
  34. Weather_Msg weather_msg = {{""}, {""}, {""}};
  35. uint32_t targetTime = 0;
  36. String cityCode = "101190402"; // 天气城市代码
  37. WiFiClient wificlient;
  38. // 发送HTTP请求并且将服务器响应通过串口输出
  39. void getCityCode()
  40. {
  41. String URL = "http://wgeo.weather.com.cn/ip/?_=" + String(now());
  42. // 创建 HTTPClient 对象
  43. HTTPClient httpClient;
  44. // 配置请求地址。此处也可以不使用端口号和PATH而单纯的
  45. httpClient.begin(wificlient, URL);
  46. // 设置请求头中的User-Agent
  47. httpClient.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");
  48. httpClient.addHeader("Referer", "http://www.weather.com.cn/");
  49. // 启动连接并发送HTTP请求
  50. int httpCode = httpClient.GET();
  51. Serial.print("Send GET request to URL: ");
  52. Serial.println(URL);
  53. // 如果服务器响应OK则从服务器获取响应体信息并通过串口输出
  54. if (httpCode == HTTP_CODE_OK)
  55. {
  56. String str = httpClient.getString();
  57. Serial.println("getCityCode中返回值:\n");
  58. Serial.println(str);
  59. int aa = str.indexOf("id=");
  60. if (aa > -1)
  61. {
  62. // cityCode = str.substring(aa+4,aa+4+9).toInt();
  63. cityCode = str.substring(aa + 4, aa + 4 + 9);
  64. Serial.println(cityCode);
  65. }
  66. else
  67. {
  68. Serial.println("获取城市代码失败");
  69. }
  70. }
  71. else
  72. {
  73. Serial.println("请求城市代码错误:");
  74. Serial.println(httpCode);
  75. }
  76. // 关闭ESP8266与服务器连接
  77. httpClient.end();
  78. }
  79. // 获取城市天气
  80. void getCityWeater()
  81. {
  82. // String URL = "http://d1.weather.com.cn/dingzhi/" + cityCode + ".html?_="+String(now());//新
  83. String URL = "http://d1.weather.com.cn/weather_index/" + cityCode + ".html?_=" + String(now()); // 原来
  84. // 创建 HTTPClient 对象
  85. HTTPClient httpClient;
  86. // httpClient.begin(URL);
  87. httpClient.begin(wificlient, URL); // 使用新方法
  88. // 设置请求头中的User-Agent
  89. httpClient.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");
  90. httpClient.addHeader("Referer", "http://www.weather.com.cn/");
  91. // 启动连接并发送HTTP请求
  92. int httpCode = httpClient.GET();
  93. Serial.println("正在获取天气数据");
  94. Serial.println(URL);
  95. // 如果服务器响应OK则从服务器获取响应体信息并通过串口输出
  96. if (httpCode == HTTP_CODE_OK)
  97. {
  98. String str = httpClient.getString();
  99. Serial.println(str);
  100. // Serial.println("httpdata=" + str);
  101. int indexStart = str.indexOf("weatherinfo\":");
  102. int indexEnd = str.indexOf("};var alarmDZ");
  103. weather_msg.cityDZ = str.substring(indexStart + 13, indexEnd);
  104. // Serial.println(jsonCityDZ);
  105. indexStart = str.indexOf("dataSK =");
  106. indexEnd = str.indexOf(";var dataZS");
  107. weather_msg.dataSK = str.substring(indexStart + 8, indexEnd);
  108. // Serial.println(jsonDataSK);
  109. indexStart = str.indexOf("\"f\":[");
  110. indexEnd = str.indexOf(",{\"fa");
  111. weather_msg.dataFC = str.substring(indexStart + 5, indexEnd);
  112. // Serial.println(jsonFC);
  113. // weaterData(&jsonCityDZ, &jsonDataSK, &jsonFC);
  114. Serial.println("获取成功");
  115. Serial.println(weather_msg.cityDZ);
  116. Serial.println(weather_msg.dataSK);
  117. Serial.println(weather_msg.dataFC);
  118. }
  119. else
  120. {
  121. Serial.println("请求城市天气错误:");
  122. Serial.print(httpCode);
  123. }
  124. // 关闭ESP8266与服务器连接
  125. httpClient.end();
  126. }
  127. void setup()
  128. {
  129. Serial.begin(115200);
  130. Serial.print("正在连接WIFI ");
  131. Serial.println(wificonf.stassid);
  132. WiFi.begin(wificonf.stassid, wificonf.stapsw);
  133. while (WiFi.status() != WL_CONNECTED)
  134. {
  135. delay(500);
  136. Serial.print(".");
  137. }
  138. Serial.print("本地IP: ");
  139. Serial.println(WiFi.localIP());
  140. Serial.println(Udp.remotePort());
  141. Serial.println("waiting for sync");
  142. setSyncProvider(getNtpTime);
  143. setSyncInterval(300);
  144. }
  145. void loop()
  146. {
  147. getCityCode();
  148. getCityWeater();
  149. delay(60000);
  150. }
  151. time_t getNtpTime()
  152. {
  153. IPAddress ntpServerIP; // NTP server's ip address
  154. while (Udp.parsePacket() > 0)
  155. ; // discard any previously received packets
  156. Serial.println("Transmit NTP Request");
  157. // get a random server from the pool
  158. WiFi.hostByName(ntpServerName, ntpServerIP);
  159. Serial.print(ntpServerName);
  160. Serial.print(": ");
  161. Serial.println(ntpServerIP);
  162. sendNTPpacket(ntpServerIP);
  163. uint32_t beginWait = millis();
  164. while (millis() - beginWait < 1500)
  165. {
  166. int size = Udp.parsePacket();
  167. if (size >= NTP_PACKET_SIZE)
  168. {
  169. Serial.println("Receive NTP Response");
  170. Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
  171. unsigned long secsSince1900;
  172. // convert four bytes starting at location 40 to a long integer
  173. secsSince1900 = (unsigned long)packetBuffer[40] << 24;
  174. secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
  175. secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
  176. secsSince1900 |= (unsigned long)packetBuffer[43];
  177. return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
  178. }
  179. }
  180. Serial.println("No NTP Response :-(");
  181. return 0; // return 0 if unable to get the time
  182. }
  183. // send an NTP request to the time server at the given address
  184. void sendNTPpacket(IPAddress &address)
  185. {
  186. // set all bytes in the buffer to 0
  187. memset(packetBuffer, 0, NTP_PACKET_SIZE);
  188. // Initialize values needed to form NTP request
  189. // (see URL above for details on the packets)
  190. packetBuffer[0] = 0b11100011; // LI, Version, Mode
  191. packetBuffer[1] = 0; // Stratum, or type of clock
  192. packetBuffer[2] = 6; // Polling Interval
  193. packetBuffer[3] = 0xEC; // Peer Clock Precision
  194. // 8 bytes of zero for Root Delay & Root Dispersion
  195. packetBuffer[12] = 49;
  196. packetBuffer[13] = 0x4E;
  197. packetBuffer[14] = 49;
  198. packetBuffer[15] = 52;
  199. // all NTP fields have been given values, now
  200. // you can send a packet requesting a timestamp:
  201. Udp.beginPacket(address, 123); // NTP requests are to port 123
  202. Udp.write(packetBuffer, NTP_PACKET_SIZE);
  203. Udp.endPacket();
  204. }

实验结果如下,返回json格式,之后可以通过ArduinoJson库来解析需要的键值对。

  1. 获取成功
  2. {"city":"常熟","cityname":"changshu","temp":"999","tempn":"18","weather":"阴","wd":"北风转东南风","ws":"3-4级转<3级","weathercode":"d2","weathercoden":"n2","fctime":"202404150800"}
  3. {"nameen":"changshu","cityname":"常熟","city":"101190402","temp":"21.4","tempf":"70.5","WD":"东风","wde":"E","WS":"2级","wse":"8km\/h","SD":"73%","sd":"73%","qy":"1011","njd":"10km","time":"20:05","rain":"0","rain24h":"0","aqi":"53","aqi_pm25":"53","weather":"多云","weathere":"Cloudy","weathercode":"d01","limitnumber":"","date":"04月15日(星期一)"}
  4. {"fa":"02","fb":"02","fc":"26","fd":"16","fe":"北风","ff":"东南风","fg":"3-4级","fh":"<3级","fk":"8","fl":"3","fm":"999.9","fn":"82.5","fi":"4\/15","fj":"今天"}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/461203
推荐阅读
相关标签
  

闽ICP备14008679号