NodeMCU获取并解析心知天气信息

Posted by Dapenson on April 30, 2020

NodeMCU获取并解析心知天气信息

1 注册心知天气并获取私钥

打开心知天气网站,点击注册按钮

image-20200430203940071

填写基本信息注册心知天气账号,登录注册所填写的邮箱点击链接进行账号激活,随后出现如下界面

image-20200430205007808

点击登录按钮进行登录之后来到以下界面

image-20200430204817432

注册登录之后账户下是默认没有API产品的,需要申请免费版天气数据API

image-20200430205145370

image-20200430205355412

免费版申请成功之后,即可在用户控制台界面看到所申请的免费版API产品了,在以下界面获取私钥信息并保存,我们接下来对API发起请求时需要使用到私钥

image-20200430205626938

至此,就已经完成了心知天气的注册和密钥获取,需要说明的是免费版API产品只包含以下几个API获取权限,并且访问频率限制(20次/分钟),以下是几个产品的文档介绍

1.1 免费用户可以获取的API信息

您也可以在浏览器输入以下API并回车查看服务器返回的Json格式的天气信息数据

(使用从心知天气控制台获取的私钥进行替换以下的”xxxxxxxxxxxxxxxxx”)

天气实况

http://api.seniverse.com/v3/weather/now.json?key=xxxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans&unit=c

生活指数

http://api.seniverse.com/v3/life/suggestion.json?key=xxxxxxxxxxxxxxxxx&location=shanghai&language=zh-Hans

三天天气预报

http://api.thinkpage.cn/v3/weather/daily.json?key=xxxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans&unit=c&start=0&days=3

2 使用ArduinoJson解析天气信息

接下来我们会使用NodeMCU对以上申请的API发起请求,服务器响应并返回天气信息的Json数据,对接收到的Json数据使用ArduinoJson库进行解析,期间会用到的工具是ArduinoJson提供的在线解析工具

示例程序将以获取当前IP地区的天气实况API为例,解析服务器返回的数据并将其打印到串口

http://api.seniverse.com/v3/weather/now.json?key=SZxTn61CIIDoyc1AI&location=ip&language=zh-Hans&unit=c
示例程序
/**********************************************************************
  项目名称/Project          : 零基础入门学用物联网
  程序名称/Program name     : xinzhi_api_Get
  团队/Team                : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
  作者/Author              : Dapenson
  日期/Date(YYYYMMDD)     : 20200430
  程序目的/Purpose          :
  此程序用于演示获取心知天气API信息并解析打印
  -----------------------------------------------------------------------
  修订历史/Revision History  
  日期/Date    作者/Author      参考号/Ref    修订说明/Revision Description
    -----------------------------------------------------------------------
  本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
  该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
  http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
***********************************************************************/

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

// 在此处填入您的心知天气API地址,请将xxxxxxxx换成你的心知天气私钥(注意此处应使用http)
#define URL "http://api.seniverse.com/v3/weather/now.json?key=SZxTn61CIIDoyc1AI&location=ip&language=zh-Hans&unit=c"

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
#define WiFi_ID "TaichiMaker"
#define WiFi_PASSWORD "xxxxxxxx"

void setup()
{
    // 初始化
    m_init();
    // 如果ESP8266连接WiFi则发送HTTP请求
    if ((WiFi.status() == WL_CONNECTED))
    {
        esp8266Http();
    }
}

void loop()
{
}

// 初始化
void m_init()
{
    //初始化串口设置
    Serial.begin(9600);

    //设置ESP8266工作模式为无线终端模式
    WiFi.mode(WIFI_STA);

    //开始连接wifi
    WiFi.begin(WiFi_ID, WiFi_PASSWORD);

    //等待WiFi连接,连接成功打印IP
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.print(".");
    }
    Serial.println("");
    Serial.print("WiFi Connected!");
}

// 发送HTTP请求并且将服务器响应通过串口输出
void esp8266Http()
{
    //创建 HTTPClient 对象
    HTTPClient httpClient;

    //配置请求地址。以及请求参数
    httpClient.begin(URL);

    //启动连接并发送HTTP请求
    int httpCode = httpClient.GET();
    Serial.print("Send GET request to URL: ");
    Serial.println(URL);

    //如果服务器响应OK则从服务器获取响应体信息并通过串口输出
    //如果服务器不响应OK则将服务器响应状态码通过串口输出
    if (httpCode == HTTP_CODE_OK)
    {
        String responsePayload = httpClient.getString();
        Serial.println("Server Response Payload: ");
        Serial.println(responsePayload);
        //使用ArduinoJson解析数据并打印到串口
        parseUserData(responsePayload);
    }
    else
    {
        Serial.println("Server Respose Code:");
        Serial.println(httpCode);
    }
    //关闭ESP8266与服务器连接
    httpClient.end();
}

//使用ArduinoJson解析数据并打印到串口
void parseUserData(String userDate)
{
    const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 210;
    DynamicJsonDocument doc(capacity);

    //const char* json = "{\"results\":[{\"location\":{\"id\":\"WK3N92NQV6RQ\",\"name\":\"昆明\",\"country\":\"CN\",\"path\":\"昆明,昆明,云南,中国\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"now\":{\"text\":\"多云\",\"code\":\"4\",\"temperature\":\"17\"},\"last_update\":\"2020-04-30T23:11:00+08:00\"}]}";

    deserializeJson(doc, userDate);

    JsonObject results_0 = doc["results"][0];

    JsonObject results_0_location = results_0["location"];
    const char *results_0_location_id = results_0_location["id"];                           // "WK3N92NQV6RQ"
    const char *results_0_location_name = results_0_location["name"];                       // "昆明"
    const char *results_0_location_country = results_0_location["country"];                 // "CN"
    const char *results_0_location_path = results_0_location["path"];                       // "昆明,昆明,云南,中国"
    const char *results_0_location_timezone = results_0_location["timezone"];               // "Asia/Shanghai"
    const char *results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "+08:00"

    JsonObject results_0_now = results_0["now"];
    const char *results_0_now_text = results_0_now["text"];               // "多云"
    const char *results_0_now_code = results_0_now["code"];               // "4"
    const char *results_0_now_temperature = results_0_now["temperature"]; // "17"

    const char *results_0_last_update = results_0["last_update"]; // "2020-04-30T23:11:00+08:00"

    if (results_0_location_id)
    {
        m_print("id", results_0_location_id);
        m_print("name", results_0_location_name);
        m_print("country", results_0_location_country);
        m_print("path", results_0_location_path);
        m_print("timezone", results_0_location_timezone);
        m_print("timezone_offset", results_0_location_timezone_offset);
        m_print("text", results_0_now_text);
        m_print("code", results_0_now_code);
        m_print("temperature", results_0_now_temperature);
        m_print("last_update", results_0_last_update);
    }
    else
    {
        Serial.println("API请求错误,请检查您的心知天气账户");
    }
}

void m_print(const char *name, const char *value)
{
    Serial.print(name);
    Serial.print("   :   ");
    Serial.println(value);
}

/*
心知天气参数

location
所查询的位置
参数值范围:
城市拼音/英文名 例如:location=beijing
城市中文名 例如:location=北京 (ESP8266不支持中文)
城市ID 例如:location=WX4FBXXFKE4F
经纬度 例如:location=39.93:116.40 (注意纬度前经度在后,冒号分隔)
IP地址 例如:location=220.181.111.86
“ip”两个字母 自动识别请求IP地址,例如:location=ip

language
语言 (可选)
参数值范围:
en 英文 
zh-Hans 简体中文 
zh-Hant 繁体中文
ja 日语
de 德语
fr 法语
hi 印地语(印度官方语言之一)
id 印度尼西亚语
ru 俄语
th 泰语
默认值:zh-Hans

unit
单位 (可选)
参数值范围:
c 当参数为c时,温度c、风速km/h、能见度km、气压mb
f 当参数为f时,温度f、风速mph、能见度mile、气压inch
默认值:c

天气代码
代码   中文    英文    图标
0     晴    Sunny    晴
1     晴    Clear    晴
2     晴    Fair    晴
3     晴    Fair    晴
4     多云    Cloudy    多云
5     晴间多云    Partly Cloudy    晴间多云
6     晴间多云    Partly Cloudy    晴间多云
7     大部多云    Mostly Cloudy    大部多云
8     大部多云    Mostly Cloudy    大部多云
9     阴    Overcast    阴
10    阵雨    Shower    阵雨
11    雷阵雨    Thundershower    雷阵雨
12    雷阵雨伴有冰雹    Thundershower with Hail    雷阵雨伴有冰雹
13    小雨    Light Rain    小雨
14    中雨    Moderate Rain    中雨
15    大雨    Heavy Rain    大雨
16    暴雨    Storm    暴雨
17    大暴雨    Heavy Storm    大暴雨
18    特大暴雨    Severe Storm    特大暴雨
19    冻雨    Ice Rain    冻雨
20    雨夹雪    Sleet    雨夹雪
21    阵雪    Snow Flurry    阵雪
22    小雪    Light Snow    小雪
23    中雪    Moderate Snow    中雪
24    大雪    Heavy Snow    大雪
25    暴雪    Snowstorm    暴雪
26    浮尘    Dust    浮尘
27    扬沙    Sand    扬沙
28    沙尘暴    Duststorm    沙尘暴
29    强沙尘暴    Sandstorm    强沙尘暴
30    雾    Foggy    雾
31    霾    Haze    霾
32    风    Windy    风
33    大风    Blustery    大风
34    飓风    Hurricane    飓风
35    热带风暴    Tropical Storm    热带风暴
36    龙卷风    Tornado    龙卷风
37    冷    Cold    冷
38    热    Hot    热
99    未知    Unknown

常用心知天气API
英文天气实况:
http://api.thinkpage.cn/v3/weather/now.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=en&unit=c

中文天气实况:
http://api.thinkpage.cn/v3/weather/now.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans&unit=c

天气预报
三日中文天气预报:
http://api.thinkpage.cn/v3/weather/daily.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans&unit=c&start=0&days=3

三天英文天气预报:
http://api.thinkpage.cn/v3/weather/daily.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=en&unit=c&start=0&days=3

http://api.thinkpage.cn/v3/weather/daily.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=en&unit=c&start=1&days=1

中文生活指数:
http://api.thinkpage.cn/v3/life/suggestion.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans

注意:使用时请将以上信息的xxxxxxxxxxxxxxxx更换为自己的心知天气认证密钥码

*/

效果截图

image-20200430234159929