NodeMCU獲取並解析心知天氣信息


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")

天氣實況

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

生活指數

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

三天天氣預報

https://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為例,解析服務器返回的數據並將其打印到串口

https://api.seniverse.com/v3/weather/now.json?key=SZxTn61CIIDoyc1AI&location=ip&language=zh-Hans&unit=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);
}


/*
心知天氣參數

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
英文天氣實況:
https://api.thinkpage.cn/v3/weather/now.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=en&unit=c

中文天氣實況:
https://api.thinkpage.cn/v3/weather/now.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=zh-Hans&unit=c

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

三天英文天氣預報:
https://api.thinkpage.cn/v3/weather/daily.json?key=xxxxxxxxxxxxxxxx&location=beijing&language=en&unit=c&start=0&days=3

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

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

注意:使用時請將以上信息的xxxxxxxxxxxxxxxx更換為自己的心知天氣認證密鑰碼

*/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM