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

devtools/2024/9/24 21:09:58/

说明

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

代码

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

#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino.h>
#include <TimeLib.h>
#include <WiFiUdp.h>void getCityCode(); // 发送HTTP请求并且将服务器响应通过串口输出
void getCityWeater();
time_t getNtpTime();
void sendNTPpacket(IPAddress &address);
/* ******************************************************************  参数设置* *****************************************************************/
// NTP Servers:
static const char ntpServerName[] = "ntp6.aliyun.com"; // 阿里云的时间服务器
/*              NTP设置                 */
const int NTP_PACKET_SIZE = 48;     // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming & outgoing packets
const int timeZone = 8;             // 时区WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
struct config_type
{char stassid[32]; // 定义配网得到的WIFI名长度(最大32字节)char stapsw[64];  // 定义配网得到的WIFI密码长度(最大64字节)
};
config_type wificonf = {{"PDCN"}, {"1234567890"}};unsigned int updateweater_time = 30000;
struct Weather_Msg
{String cityDZ;String dataSK;String dataFC;
};
Weather_Msg weather_msg = {{""}, {""}, {""}};uint32_t targetTime = 0;
String cityCode = "101190402"; // 天气城市代码
WiFiClient wificlient;
// 发送HTTP请求并且将服务器响应通过串口输出
void getCityCode()
{String URL = "http://wgeo.weather.com.cn/ip/?_=" + String(now());// 创建 HTTPClient 对象HTTPClient httpClient;// 配置请求地址。此处也可以不使用端口号和PATH而单纯的httpClient.begin(wificlient, URL);// 设置请求头中的User-AgenthttpClient.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");httpClient.addHeader("Referer", "http://www.weather.com.cn/");// 启动连接并发送HTTP请求int httpCode = httpClient.GET();Serial.print("Send GET request to URL: ");Serial.println(URL);// 如果服务器响应OK则从服务器获取响应体信息并通过串口输出if (httpCode == HTTP_CODE_OK){String str = httpClient.getString();Serial.println("getCityCode中返回值:\n");Serial.println(str);int aa = str.indexOf("id=");if (aa > -1){// cityCode = str.substring(aa+4,aa+4+9).toInt();cityCode = str.substring(aa + 4, aa + 4 + 9);Serial.println(cityCode);}else{Serial.println("获取城市代码失败");}}else{Serial.println("请求城市代码错误:");Serial.println(httpCode);}// 关闭ESP8266与服务器连接httpClient.end();
}// 获取城市天气
void getCityWeater()
{// String URL = "http://d1.weather.com.cn/dingzhi/" + cityCode + ".html?_="+String(now());//新String URL = "http://d1.weather.com.cn/weather_index/" + cityCode + ".html?_=" + String(now()); // 原来// 创建 HTTPClient 对象HTTPClient httpClient;// httpClient.begin(URL);httpClient.begin(wificlient, URL); // 使用新方法// 设置请求头中的User-AgenthttpClient.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");httpClient.addHeader("Referer", "http://www.weather.com.cn/");// 启动连接并发送HTTP请求int httpCode = httpClient.GET();Serial.println("正在获取天气数据");Serial.println(URL);// 如果服务器响应OK则从服务器获取响应体信息并通过串口输出if (httpCode == HTTP_CODE_OK){String str = httpClient.getString();Serial.println(str);// Serial.println("httpdata=" + str);int indexStart = str.indexOf("weatherinfo\":");int indexEnd = str.indexOf("};var alarmDZ");weather_msg.cityDZ = str.substring(indexStart + 13, indexEnd);// Serial.println(jsonCityDZ);indexStart = str.indexOf("dataSK =");indexEnd = str.indexOf(";var dataZS");weather_msg.dataSK = str.substring(indexStart + 8, indexEnd);// Serial.println(jsonDataSK);indexStart = str.indexOf("\"f\":[");indexEnd = str.indexOf(",{\"fa");weather_msg.dataFC = str.substring(indexStart + 5, indexEnd);// Serial.println(jsonFC);// weaterData(&jsonCityDZ, &jsonDataSK, &jsonFC);Serial.println("获取成功");Serial.println(weather_msg.cityDZ);Serial.println(weather_msg.dataSK);Serial.println(weather_msg.dataFC);}else{Serial.println("请求城市天气错误:");Serial.print(httpCode);}// 关闭ESP8266与服务器连接httpClient.end();
}
void setup()
{Serial.begin(115200);Serial.print("正在连接WIFI ");Serial.println(wificonf.stassid);WiFi.begin(wificonf.stassid, wificonf.stapsw);while (WiFi.status() != WL_CONNECTED){delay(500);Serial.print(".");}Serial.print("本地IP: ");Serial.println(WiFi.localIP());Serial.println(Udp.remotePort());Serial.println("waiting for sync");setSyncProvider(getNtpTime);setSyncInterval(300);
}
void loop()
{getCityCode();getCityWeater();delay(60000);
}time_t getNtpTime()
{IPAddress ntpServerIP; // NTP server's ip addresswhile (Udp.parsePacket() > 0); // discard any previously received packetsSerial.println("Transmit NTP Request");// get a random server from the poolWiFi.hostByName(ntpServerName, ntpServerIP);Serial.print(ntpServerName);Serial.print(": ");Serial.println(ntpServerIP);sendNTPpacket(ntpServerIP);uint32_t beginWait = millis();while (millis() - beginWait < 1500){int size = Udp.parsePacket();if (size >= NTP_PACKET_SIZE){Serial.println("Receive NTP Response");Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the bufferunsigned long secsSince1900;// convert four bytes starting at location 40 to a long integersecsSince1900 = (unsigned long)packetBuffer[40] << 24;secsSince1900 |= (unsigned long)packetBuffer[41] << 16;secsSince1900 |= (unsigned long)packetBuffer[42] << 8;secsSince1900 |= (unsigned long)packetBuffer[43];return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;}}Serial.println("No NTP Response :-(");return 0; // return 0 if unable to get the time
}// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{// set all bytes in the buffer to 0memset(packetBuffer, 0, NTP_PACKET_SIZE);// Initialize values needed to form NTP request// (see URL above for details on the packets)packetBuffer[0] = 0b11100011; // LI, Version, ModepacketBuffer[1] = 0;          // Stratum, or type of clockpacketBuffer[2] = 6;          // Polling IntervalpacketBuffer[3] = 0xEC;       // Peer Clock Precision// 8 bytes of zero for Root Delay & Root DispersionpacketBuffer[12] = 49;packetBuffer[13] = 0x4E;packetBuffer[14] = 49;packetBuffer[15] = 52;// all NTP fields have been given values, now// you can send a packet requesting a timestamp:Udp.beginPacket(address, 123); // NTP requests are to port 123Udp.write(packetBuffer, NTP_PACKET_SIZE);Udp.endPacket();
}

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

获取成功
{"city":"常熟","cityname":"changshu","temp":"999","tempn":"18","weather":"阴","wd":"北风转东南风","ws":"3-4级转<3级","weathercode":"d2","weathercoden":"n2","fctime":"202404150800"}
{"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日(星期一)"}
{"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":"今天"}


http://www.ppmy.cn/devtools/8720.html

相关文章

Tesseract OCR 的使用

目录 前言一、简介二、下载与安装2.1 下载2.2 安装2.3 配置环境变量 三、基本使用四、Java 整合4.1 导入依赖4.2 添加语言库4.3 代码示例 五、训练字库5.1 为什么要训练字库5.2 jTessBoxEditor 前言 如果想要通过代码的方式去识别图片中的文字&#xff0c;通常有以下几种方法&…

钉钉OA审批评论接口,如何@ 人并发送通知

钉钉OA审批评论接口&#xff0c;如何 人并发送通 问题描述&#xff1a; 相关接口&#xff1a;https://oapi.dingtalk.com/topapi/process/instance/comment/add 我希望在钉钉oa审批流程中&#xff0c;添加评论的同时通过“”或者其他方式提醒流程发起人去跟进审批工作。 但我…

2024五一杯数学建模A题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

SpringCloud +UniApp技术开发saas模式的智慧工地云平台源码,支持可视化大屏端、手机端、平板端、PC端

基于微服务架构JavaSpring Cloud UniApp MySql技术开发saas模式的一套智慧工地云平台源码&#xff0c;支持多端展示&#xff1a;可视化大屏端、手机端、平板端、PC端。 智慧工地平台支持项目级、公司级、集团级多级权限划分&#xff0c;可根据企业的组织架构进行项目权限、功能…

线程池的核心参数有哪些???

线程池的核心参数包括以下七个&#xff1a; corePoolSize&#xff1a; 这是线程池中的核心线程数&#xff0c;即池中会保留的最少线程数。当提交任务时&#xff0c;如果当前线程数小于核心线程数&#xff0c;线程池会创建新的线程来执行任务。如果当前线程数等于或大于核心线程…

给sample_gpt 增加 lisa 微调

论文 地址 概述 该论文提出了一种名为LISA的层重要性采样优化算法&#xff0c;旨在解决大规模语言模型训练中的内存瓶颈问题。其主要内容和贡献包括&#xff1a; 通过分析LoRA训练中各层权重范数的分布&#xff0c;发现了权重更新在底层和顶层更为集中的现象&#xff0c;揭…

Vue3+Vant开发:个人信息管理

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

OJ:寻找独一无二的数

目录 &#x1f3dd;1.问题描述&#xff1a; &#x1f3dd;2.分析问题&#xff1a; &#x1f3dd;3.最终代码&#xff1a; &#x1f3dd;1.问题描述&#xff1a; &#x1f3dd;2.分析问题&#xff1a; 先看看下面的代码的结果是多少&#xff1f; #include<stdio.h> in…