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

说明

本章节需要先学习之前(三)中获取当前时间方法,本文基于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.mzph.cn/news/819169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

密码学 | 椭圆曲线 ECC 密码学入门(四)

目录 正文 1 曲线方程 2 点的运算 3 求解过程 4 补充&#xff1a;有限域 ⚠️ 知乎&#xff1a;【密码专栏】动手计算双线性对&#xff08;中&#xff09; - 知乎 ⚠️ 写在前面&#xff1a;本文属搬运博客&#xff0c;自己留着学习。注意&#xff0c;这篇博客与前三…

代码随想录算法训练营Day56|LC583 两个字符串的删除操作LC72 编辑距离

一句话总结&#xff1a;看起来复杂&#xff0c;动规分析以后就比较简单。 原题链接&#xff1a;583 两个字符串的删除操作 本质就是求两个字符串的最短子序列的长度。已经做过&#xff0c;不再详解。 class Solution {public int minDistance(String word1, String word2) {/…

Day13-Java基础之运算符和表达式

运算符和表达式 运算符&#xff1a; 就是对常量或者变量进行操作的符号。 比如&#xff1a; - * / 表达式&#xff1a; 用运算符把常量或者变量连接起来的&#xff0c;符合Java语法的式子就是表达式。 比如&#xff1a;a b 这个整体就是表达式。 而其中是算术运算符的…

Python(11):网络编程

文章目录 一、一些基本概念二、软件的开发架构&#xff08;c/s架构和b/s架构&#xff09;三、OSI模型四、socket套接字编程1.socket编程过程2.python中的socket编程 一、一些基本概念 来了解一些网络的基本概念 名词解释IP&#xff08;互联网协议地址&#xff09;IP用来标识网…

【华为OD机试C++】统计字符

《最新华为OD机试题目带答案解析》:最新华为OD机试题目带答案解析,语言包括C、C++、Python、Java、JavaScript等。订阅专栏,获取专栏内所有文章阅读权限,持续同步更新! 文章目录 描述输入描述输出描述示例代码描述 输入一行字符,分别统计出包含英文字母、空格、数字和其它…

linux设置程序在开机时自启动

​常见的有三种方式&#xff1a;1、/etc/rc.local文件中添加自启动命令 对于某些没有使用systemd的Linux发行版&#xff0c;可以在/etc/rc.local文件中添加自启动命令。请确保该文件具有可执行权限。例如&#xff0c;在/etc/rc.local文件中添加以下内容&#xff1a; /…

PCB基础介绍

一&#xff0c;单层板&#xff1a; 1&#xff0c;铜皮 和导线类似&#xff0c;提供电路板上的电信号传导路径。 因为铜具有良好的导热性能&#xff0c;因此铜皮还可以用于散热。在高功率电子设备中&#xff0c;通过在PCB上增加铜皮面积和散热片&#xff0c;可以提高散热效果…

【洛谷题解】 P6995 [NEERC2014] Knockout Racing

分析 按照题意模拟即可。 我们只需要依次找到第 i i i&#xff08; 1 ≤ i ≤ N 1\le i\le N 1≤i≤N&#xff09;辆车在 t j t_j tj​ 时刻时所在的位置&#xff0c;看这个位置是不是在区间 [ x j , y j ] [x_j,y_j] [xj​,yj​] 之中&#xff0c;如果是&#xff0c;答案…

数字晶体管数字三极管

数字晶体管 指内部集成了电阻的三极管&#xff0c;有PNP和NPN型&#xff0c;也有双管&#xff0c;双管有3种形式&#xff0c;其中一种是PNPNPN。下面以双NPN示例&#xff0c;好处是外面没有电阻&#xff0c;批量应用时&#xff0c;焊点费用就可省下不少。双NPN的用在串口自动下…

Flutter知识点 --- key

Flutter 中的 Key 对象在Widget树的构建、更新和状态管理中扮演着重要角色。它主要用于帮助Flutter框架在Widget树发生变动时正确地识别和保留Widget的对应关系&#xff0c;以及在某些情况下维护状态。下面是Key的作用与原理的详细阐述&#xff1a; Key的作用 标识Widget的唯一…

开源相机管理库Aravis例程学习(二)——连续采集multiple-acquisition-main-thread

开源相机管理库Aravis例程学习&#xff08;二&#xff09;——连续采集multiple-acquisition-main-thread 简介例程代码函数说明arv_camera_set_acquisition_modearv_camera_create_streamarv_camera_get_payloadarv_buffer_newarv_stream_push_bufferarv_camera_start_acquisi…

目标检测YOLO实战应用案例100讲-基于轻量化神经网络的目标检测算法研究与应用(续)

目录 轻量化目标检测模型的参数量化 4.1引言 4.2模型量化的原理及过程 4.3实验结果及分析

如何看待2023年图灵奖

目录 1.概述 2.计算复杂性理论 3.随机性和伪随机性 4.学术生涯和领导力 1.概述 图灵奖&#xff08;Turing Award&#xff09;&#xff0c;全称A.M.图灵奖&#xff08;ACM A.M Turing Award&#xff09;&#xff0c;是由计算机领域的最高学术机构——美国计算机协会&#xf…

ElasticSearch 集群添加用户安全认证功能(设置访问密码)

前言 在6.8之前免费版本并不包含安全认证功能&#xff0c;之后版本有开放一些基础认证功能&#xff1b;为了防止各种事故&#xff0c;一般都会设置es集群的访问密码&#xff1b;但是在我尝试设置访问密码的时候发现&#xff0c;设置访问密码的前提必须要设置集群证书&#xff0…

java:多线程

多线程 在java程序中同时执行多个线程,每个线程独立执行不同的任务. 可以提高程序的性能和资源利用率,增加程序的并发性. 多线程的作用 1,提高程序性能 可以将一个任务分解成多个子任务并行处理,从而提高程序的运行速度 2,提高资源利用率 可以更好地利用CPU资源,提高CPU…

如何实现Windows RDP 远程桌面异地跨网连接

Windows RDP远程桌面的应用非常广泛。远程桌面协议(RDP)是一个多通道(multi-channel)的协议&#xff0c;让使用者(所在计算机称为用户端或本地计算机)连上提供微软终端机服务的计算机(称为服务端或远程计算机)。大部分的Windows版本都有用户端所需软件&#xff0c;有些其他操作…

Python Flask Web 框架-API接口开发_4

一、1、安装 Falsk 当前用户安装 pip3 install --user Flask 确认安装成功&#xff1a; 进入python交互模式看下Flask的介绍和版本&#xff1a; $ python3>>> import flask >>> print(flask.__doc__)flask~~~~~A microframework based on Werkzeug. Its …

病毒繁殖-第12届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第52讲。 病毒繁殖&#xf…

Linux userdel命令教程:如何删除用户账户及其相关文件(附实例详解和注意事项)

Linux userdel命令介绍 userdel命令在Linux系统中用于删除用户账户及其相关文件。这个命令主要修改系统账户文件&#xff0c;删除所有引用到用户名的条目。 Linux userdel命令适用的Linux版本 userdel命令在大多数Linux发行版中都可以使用&#xff0c;包括但不限于Debian、U…

数据结构与算法——23.哈希冲突及其解决方法

这篇文章我们主要讲一下哈希冲突及其解决方法。 目录 1.哈希冲突的介绍 2.解决哈希冲突的方法 2.1 开放地址法 2.1.1 线性探测法 2.1.2 平方探测法&#xff08;二次探测法&#xff09; 2.2再哈希法 2.3链地址法 2.4建立公共溢出区 3.总结 1.哈希冲突的介绍 首先&…