| 今天是第五专题内容,主要是介绍如何从心知天气官网,获取包含当前天气实况和未来 3 天天气预报的JSON数据信息。
在学习获取及显示天气信息前,我们务必要对JSON数据格式有个深入的了解。
如您需要了解其它专题的内容,请点击下面的链接。
第一专题内容,请参考:连接点亮SPI-TFT屏幕和UI布局设计
第二专题内容,请参考:WIFI模式设置及连接
第三专题内容,请参考:连接SHT30传感器,获取并显示当前环境温湿度数据(I2C)
第四专题内容,请参考:通过NTPClient库获取实时网络时间并显示在TFT屏幕上
一、什么是JSON?
JSON,是JavaScript Object Notation单词首字母的缩写,是一种轻量级的数据交换格式。它以易于阅读和编写的文本格式来存储和表示数据,通常用于在不同的系统之间进行数据交换。JSON数据以键值对或名值对的形式出现,可以包含对象、数组、字符串、数字等基本数据类型。它经常在Web开发、API通信等领域被广泛使用。
通过NodeMCU的WiFi模块,我们可以很容易地从【心知天气】网站获取气象信息,包括天气实况和天气预报等各类数据,这些天气数据是未经压缩的JSON格式数据。关于JSON格式数据,网上有大量文章对其作用、语法规则和应用场景进行详细介绍,请大家自行查询了解。比如,JSON 基本使用_json怎么用-CSDN博客。
二、天气实况数据
1. 天气实况。获取指定城市的天气实况,付费用户可获取全部数据,免费用户只返回天气现象文字、天气现象代码和气温 3 项数据。数据更新频率,国内城市在 15 分钟左右,国际城市在 20 分钟左右。
2. 接口地址
https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c
3. 请求参数说明
4. 返回结果示例 (免费用户仅返回 ”now" 的前三项数值)
{"results": [{"location": {"id": "C23NB62W20TF","name": "西雅图","country": "US","path": "西雅图,华盛顿州,美国","timezone": "America/Los_Angeles","timezone_offset": "-07:00"},"now": {"text": "多云", //天气现象文字"code": "4", //天气现象代码"temperature": "14", //温度,单位为c摄氏度或f华氏度"feels_like": "14", //体感温度,单位为c摄氏度或f华氏度"pressure": "1018", //气压,单位为mb百帕或in英寸"humidity": "76", //相对湿度,0~100,单位为百分比"visibility": "16.09", //能见度,单位为km公里或mi英里"wind_direction": "西北", //风向文字"wind_direction_degree": "340", //风向角度,范围0~360,0为正北,90为正东,180为正南,270为正西"wind_speed": "8.05", //风速,单位为km/h公里每小时或mph英里每小时"wind_scale": "2", //风力等级,请参考:http://baike.baidu.com/view/465076.htm"clouds": "90", //云量,单位%,范围0~100,天空被云覆盖的百分比 #目前不支持中国城市#"dew_point": "-12" //露点温度,请参考:http://baike.baidu.com/view/118348.htm #目前不支持中国城市#},"last_update": "2015-09-25T22:45:00-07:00" //数据更新时间(该城市的本地时间)}]
}
三、未来15天逐日天气预报
1. 天气预报。获取指定城市未来最多 15 天每天的白天和夜间预报。一般每天更新 3-4 次。付费用户可获取全部数据,免费用户只返回 3 天天气预报。降水预报目前只支持国内城市。
2. 接口地址及示例:北京今天和未来 4 天的预报。
https://api.seniverse.com/v3/weather/daily.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c&start=0&days=5
3. 请求参数说明
4. 返回结果示例
{"results": [{"location": {"id": "WX4FBXXFKE4F","name": "北京","country": "CN","path": "北京,北京,中国","timezone": "Asia/Shanghai","timezone_offset": "+08:00"},"daily": [{ //返回指定days天数的结果"date": "2015-09-20", //日期(该城市的本地时间)"text_day": "多云", //白天天气现象文字"code_day": "4", //白天天气现象代码"text_night": "晴", //晚间天气现象文字"code_night": "0", //晚间天气现象代码"high": "26", //当天最高温度"low": "17", //当天最低温度"precip": "0", //降水概率,范围0~1,单位百分比(目前仅支持国外城市)"wind_direction": "", //风向文字"wind_direction_degree": "255", //风向角度,范围0~360"wind_speed": "9.66", //风速,单位km/h(当unit=c时)、mph(当unit=f时)"wind_scale": "", //风力等级"rainfall": "0.0", //降水量,单位mm"humidity": "76" //相对湿度,0~100,单位为百分比}, {"date": "2015-09-21","text_day": "晴","code_day": "0","text_night": "晴","code_night": "0","high": "27","low": "17","precip": "0","wind_direction": "","wind_direction_degree": "157","wind_speed": "17.7","wind_scale": "3","rainfall": "0.0","humidity": "76"}, {... //更多返回结果}],"last_update": "2015-09-20T18:00:00+08:00" //数据更新时间(该城市的本地时间)}]
}
四、编程实现获取天气实况和未来 3 天天气预报信息
【编程环境】VSCode + PlatformIO,Platforms:Espressif 8266,Framework: Arduino
以下是具体实现代码,可以复制到 main.cpp 中,修改个别信息后,直接编译上传即可。需要修改的项目,在第五部分详细说明。
#include <ESP8266WiFi.h>const char* host = "api.seniverse.com"; // 心知天气 API 接口地址
const int httpPort = 80; // http端口80// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "xcb940";
const char* password = "87589940abc";void wifiClientRequest();void setup() {//初始化串口设置Serial.begin(9600);Serial.println("");//设置ESP8266工作模式为无线终端模式WiFi.mode(WIFI_STA);//开始连接wifiWiFi.begin(ssid, password);//等待WiFi连接,连接成功打印IPwhile (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.print(".");}Serial.println("");Serial.println("WiFi Connected!");wifiClientRequest();
}void loop(){}// 向服务器发送HTTP请求,在串口监视器打印 HTTP请示内容,HTTP响应头信息和请求的数据,包括天气实况和未来3天的天气预报(免费用户只返回3天的)
void wifiClientRequest(){// 建立WiFi客户端对象,对象名称clientWiFiClient client; //以下代码,请求返回天气实况信息// 建立字符串,用于HTTP请求String httpRequest = String("GET /v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c") + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" +"Connection: close\r\n" +"\r\n";// 通过串口输出连接服务器名称以便查阅连接服务器的网址 Serial.print("Connecting to "); Serial.print(host); // 连接网络服务器,请求并返回信息if (client.connect(host, httpPort)){ Serial.println(" Success!"); // 连接成功后串口输出“Success”信息 client.print(httpRequest); // 向服务器发送HTTP请求Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅Serial.println(httpRequest); // 通过串口输出网络服务器响应信息Serial.println("Web Server Response:"); while (client.connected() || client.available()){ if (client.available()){String line = client.readStringUntil('\n');Serial.println(line);}} client.stop(); // 断开与服务器的连接Serial.print("Disconnected from "); // 并且通过串口输出断开连接信息Serial.print(host);} else{ // 如果连接不成功则通过串口输出“连接失败”信息Serial.println(" connection failed!");client.stop();} Serial.println("");Serial.println("");//以下代码,请求返回未来3天天气预报(免费用户只返回3天的数据)// 建立字符串,用于HTTP请求 httpRequest = String("GET /v3/weather/daily.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c&start=0&days=3") + " HTTP/1.1\r\n" +"Host: " + host + "\r\n" +"Connection: close\r\n" +"\r\n";// 通过串口输出连接服务器名称以便查阅连接服务器的网址 Serial.print("Connecting to "); Serial.print(host); // 连接网络服务器,if (client.connect(host, httpPort)){ Serial.println(" Success!"); // 连接成功后串口输出“Success”信息client.print(httpRequest); // 向服务器发送HTTP请求Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅Serial.println(httpRequest); // 通过串口输出网络服务器响应信息Serial.println("Web Server Response:"); while (client.connected() || client.available()){ if (client.available()){String line = client.readStringUntil('\n');Serial.println(line);}} client.stop(); // 断开与服务器的连接Serial.print("Disconnected from "); // 并且通过串口输出断开连接信息Serial.print(host);} else{ // 如果连接不成功则通过串口输出“连接失败”信息Serial.println(" connection failed!");client.stop();}
}
五、特别提醒需要修改的部分信息
(1)修改WiFi连接信息
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "xcb940";
const char* password = "87589940abc";
(2)修改第 43 行http请求:“key = your_api_key” ------->> 修改为您自己的密钥, “location = beijing” ------->> 修改为您所希望的所在地区
//第43行
String httpRequest = String("GET /v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c") + " HTTP/1.1\r\n" +
(3)修改第 82行http请求:“key = your_api_key”------->> 修改为您自己的密钥, “location = beijing” ------->> 修改为您所希望的所在地区
//第 82行
httpRequest = String("GET /v3/weather/daily.json?key=your_api_keyu&location=beijing&language=zh-Hans&unit=c&start=0&days=3") + " HTTP/1.1\r\n" +
六、运行结果分析
程序编译上传成功执行后,如果在串口监视器找到以下包含天气信息的两个JSON数据,一个是包含天气实况的信息,另一个是包含未来 3 天天气预报的信息。那么,恭喜您:现在可以正常从心知天气官网获取天气数据信息了。
项目源代码下载:
百度网盘:https://pan.baidu.com/s/11ggPQdj9rzYP3Av97Z85Kg?pwd=aira,提取码:aira
//以下返回的天气实况{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"北京","country":"CN","path":"北京,北京,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"晴","code":"0","temperature":"29"},"last_update":"2024-05-08T15:44:15+08:00"}]}//以下返回的是未来 3 天的天气预报
{"results":[{"location":{"id":"WX4FBXXFKE4F","name":"北京","country":"CN","path":"北京,北京,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[{"date":"2024-05-08","text_day":"晴","code_day":"0","text_night":"晴","code_night":"1","high":"30","low":"14","rainfall":"0.00","precip":"0.00","wind_direction":"西南","wind_direction_degree":"225","wind_speed":"23.4","wind_scale":"4","humidity":"56"},{"date":"2024-05-09","text_day":"晴","code_day":"0","text_night":"多云","code_night":"4","high":"30","low":"16","rainfall":"0.00","precip":"0.00","wind_direction":"
南","wind_direction_degree":"180","wind_speed":"8.4","wind_scale":"2","humidity":"48"},{"date":"2024-05-10","text_day":"多云","code_day":"4","text_night":"多云","code_night":"4","high":"29","low":"17","rainfall":"0.00","precip":"0.00","wind_direction":"西南","wind_direction_degree":"225","wind_speed":"3.0","wind_scale":"1","humidity":"71"}],"last_update":"2024-05-07T08:00:00+08:00"}]}
下一个专题,我们将解析从心知天气官网获取到的JSON数据,并把它们显示到 TFT 液晶显示屏上。敬请关注。
参考文档
1. JSON 基本使用_json怎么用-CSDN博客