签到天数: 867 天 [LV.10]以坛为家III
|
ESP8266连接到互联网并通过免费的API接口获取天气JSON数据并解析!
选择免费开放的信息平台:
上知乎看了一下:免费开放天气API接口 ,还是有很多的!
1、中国气象局开放平台网址:smartWeatherAPI(应该比较权威平台),但表示打开网址错误,大家可以看下这个:有道云笔记保存网页 (看这不舒服总比看不了强)。查看网页你会发现,需要填写申请表并发送至邮箱:smartweatherapi@weather.com.cn进行审核,审核通过会回复,我已经填写并发出了,没反应,不知道什么时候可以有回应!只能放弃(网上有人说现在不支持了)。
2、和风天气,注册账号即可免费使用部分数据(一天免费访问量3000,提供的数据也比较多)!最后测试国内城市天气数据中有中文,无法处理!放弃。
api 文档说明:http://www.heweather.com/documents/api
city id list:http://www.heweather.com/documents/cn-city-list
3、心知天气:支持多语言,免费账户可以使用:国内369个地级市+天气实况(温度、天气现象)+3天天气预报+生活指数(6项)+400次访问/小时!OK,就选这个了。
4、OpenWeatherMap、YaHoo天气 等等,不做介绍合适自己用的就行!
心知天气更改新IP - api.seniverse.com,原api - api.thinkpage.cn也可用(最好用新的),使用本文中的程序时,请保证你的ID是付费版 付费版 付费版(第一次注册会有免费试用)!
测试API接口(在浏览器中打开测试网址即可):
上文提到使用心知天气,我们看下心知天气API接口说明:心知天气API;支持城市列表:下载地址(包含收费城市)。当然首先你需要注册,对于我们来说免费即可,学习用途,不做商业用途!如果你需要商用,也可以付费。
我注册了免费账号(也可以自行注册): API密钥:24qbvr1mjsnukavo(仅供学习,每小时400次访问)
● 示例1:获取指定城市的实况天气 -- GET /weather/now.json
请求地址 - https://api.thinkpage.cn/v3/weather/now.json?key=24qbvr1mjsnukavo&location=beijing&language=zh-Hans&unit=c
具体参数:key - API密钥 location - 位置 language - 语言(可选,默认zh-Hans简体中文)unit - 单位(可选,默认c)
返回结果:
{ "results":[{
"location": {
"id": "C23NB62W20TF",
"name": "西雅图",
"country": "US",
"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" //数据更新时间(该城市的本地时间)
}]
}
● 示例2:逐日预报和你是 -- GET /weather/daily.json
请求地址示例 -
北京今天和未来4天的预报
https://api.thinkpage.cn/v3/weather/daily.json?key=24qbvr1mjsnukavo&location=beijing&language=zh-Hans&unit=c&start=0&days=5
北京昨天天气、今天和未来3天的预报(仅旗舰会员和大客户支持昨天天气)
https://api.thinkpage.cn/v3/weather/daily.json?key=24qbvr1mjsnukavo&location=beijing&language=zh-Hans&unit=c&start=-1&days=5
具体参数:key - API密钥 location - 位置 language - 语言(可选,默认zh-Hans简体中文)unit - 单位(可选,默认c) start - 起始时间(可选,默认0) days - 天数(可选)
返回结果:
{ "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~100,单位百分比
"wind_direction": "", //风向文字
"wind_direction_degree": "255", //风向角度,范围0~360
"wind_speed": "9.66", //风速,单位km/h(当unit=c时)、mph(当unit=f时)
"wind_scale": "" //风力等级
}, {
"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"
}, {
... //更多返回结果
}],
"last_update": "2015-09-20T18:00:00+08:00" //数据更新时间(该城市的本地时间)
}]
}
更多这里不介绍,直接访问天气数据API文档!
ESP8266 获取天气数据(使用nodemcu测试,无需电路,需要网络):
需要使用的库:JSON库
实时天气情况,测试网址:
https://api.thinkpage.cn/v3/weather/now.json?key=24qbvr1mjsnukavo&location=huaian&language=en
在浏览器中打开网址,分析数据:
分析得到的哪些数据是你需要的,然后在程序中打印出来......
nodemcu通过USB数据线连接到电脑,下载例程:
[C] 纯文本查看 复制代码 /**
Get the Weather from intenet with esp8266
get data from 心知天气:[url=http://www.thinkpage.cn/]http://www.thinkpage.cn/[/url]
api 文档说明:[url=http://www.thinkpage.cn/doc]http://www.thinkpage.cn/doc[/url]
city id list download :[url=http://www.thinkpage.cn/data/thinkpage_cities.zip]http://www.thinkpage.cn/data/thinkpage_cities.zip[/url]
Created by yfrobot, 2016.8.23
This example is in public domain.
*/
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
WiFiClient client;
const char* ssid = "YFROBOT"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
const char* password = "yfrobot2016"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
const char* host = "api.thinkpage.cn";
const char* APIKEY = "24qbvr1mjsnukavo"; //API KEY
const char* city = "huaian";
const char* language = "en";
//心知天气获取连接:[url=https://api.thinkpage.cn/v3/weather/daily.json?key=KEY&location=]https://api.thinkpage.cn/v3/weather/daily.json?key=KEY&location=[/url]城市&language=zh-Hans&unit=c&start=-1&days=5
const unsigned long BAUD_RATE = 115200; // serial connection speed
const unsigned long HTTP_TIMEOUT = 2100; // max respone time from server
const size_t MAX_CONTENT_SIZE = 2048; // max size of the HTTP response
// Skip HTTP headers so that we are at the beginning of the response's body
// -- 跳过 HTTP 头,使我们在响应正文的开头
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// 发送请求指令
bool sendRequest(const char* host, const char* cityid, const char* apiKey) {
// We now create a URI for the request
//心知天气
String GetUrl = "/v3/weather/now.json?key=";
GetUrl += apiKey;
GetUrl += "&location=";
GetUrl += city;
GetUrl += "&language=";
GetUrl += language;
// This will send the request to the server
client.print(String("GET ") + GetUrl + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
return true;
}
// Read the body of the response from the HTTP server -- 从HTTP服务器响应中读取正文
void readReponseContent(char* content, size_t maxSize) {
size_t length = client.peekBytes(content, maxSize);
delay(100);
Serial.println("Get the data from Internet!");
content[length] = 0;
Serial.println(content);
Serial.println("Read Over!");
}
// The type of data that we want to extract from the page -- 我们要从此网页中提取的数据的类型
struct UserData {
char city[16];
char cnty[16];
char weather[32];
char temp[16];
char feel[16];
char hum[16];
char visi[16];
char udate[32];
};
// 解析数据
bool parseUserData(char* content, struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// -- 根据我们需要解析的数据来计算JSON缓冲区最佳大小
// This is only required if you use StaticJsonBuffer. -- 如果你使用StaticJsonBuffer时才需要
// const size_t BUFFER_SIZE = 1024;
// Allocate a temporary memory pool on the stack -- 在堆栈上分配一个临时内存池
// StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// -- 如果堆栈的内存池太大,使用 DynamicJsonBuffer jsonBuffer 代替
// If the memory pool is too big for the stack, use this instead:
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(content);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// const char* x = root["results"][0]["location"]["name"];//
// Serial.println(x);
// Here were copy the strings we're interested in -- 复制我们感兴趣的字符串
strcpy(userData->city, root["results"][0]["location"]["name"]);
strcpy(userData->cnty, root["results"][0]["location"]["country"]);
strcpy(userData->weather, root["results"][0]["now"]["text"]);
strcpy(userData->temp, root["results"][0]["now"]["temperature"]);
strcpy(userData->feel, root["results"][0]["now"]["feels_like"]);
strcpy(userData->hum, root["results"][0]["now"]["humidity"]);
strcpy(userData->visi, root["results"][0]["now"]["visibility"]);
strcpy(userData->udate, root["results"][0]["last_update"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
// -- 这不是强制复制,你可以使用指针,因为他们是指向“内容”缓冲区内,所以你需要确保
// 当你读取字符串时它仍在内存中
return true;
}
// Print the data extracted from the JSON -- 打印从JSON中提取的数据
void printUserData(const struct UserData* userData) {
Serial.println("Print parsed data :");
Serial.print("City : ");
Serial.print(userData->city);
Serial.print(", \t");
Serial.print("Country : ");
Serial.println(userData->cnty);
Serial.print("Weather : ");
Serial.print(userData->weather);
Serial.print(",\t");
Serial.print("Temp : ");
Serial.print(userData->temp);
Serial.print(" C");
Serial.print(",\t");
Serial.print("Feel : ");
Serial.print(userData->feel);
Serial.print(" C");
Serial.print(",\t");
Serial.print("Humidity : ");
Serial.print(userData->hum);
Serial.print(" %");
Serial.print(",\t");
Serial.print("visibility : ");
Serial.print(userData->visi);
Serial.println(" km");
Serial.print("Last Updata : ");
Serial.print(userData->udate);
Serial.println("");
}
// Close the connection with the HTTP server -- 关闭与HTTP服务器连接
void stopConnect() {
Serial.println("Disconnect");
client.stop();
}
void setup(){
WiFi.mode(WIFI_STA); //设置esp8266 工作模式
Serial.begin(BAUD_RATE ); //设置波特率
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password); //连接wifi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
delay(500);
// Check if a client has connected
if (!client.connect(host, 80)) {
Serial.println("connection failed");
return;
}
if (sendRequest(host, city, APIKEY) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
UserData userData;
if (parseUserData(response, &userData)) {
printUserData(&userData);
}
}
stopConnect();
}
void loop(){
delay(3000);
}
直接下载:
WeatherESP8266.zip
(2.97 KB, 下载次数: 266, 售价: 2 )
|
|