2022年7月27日 星期三

ESP32 取得氣象網站的天氣開放資料


本實作使用ESP32的無線WiWi模組連上網路,利用HTTP的GET方法進行資料請求,自氣象網站取回天氣資料,故須先取得氣象網站的程式開發API Key,請參考這裡

當設計程式進行Web應用或者是手機應用,若需要秀出天氣數據或者天氣預報數據時,不妨使用 OpenWeatherMap 天氣API服務。
 OpenWeatherMap是OpenWeather Ltd擁有的在線服務,它通過API提供全球天氣數據,包括任何地理位置的當前天氣數據,天氣預報,天氣預報和歷史天氣數據。該公司提供了對任何位置的逐分鐘超局部降雨預報。

OpenWeatherMap  提供當前天氣的地圖,一周預報,降水,風,雲,來自氣象站的其他數據。免費用戶就可以使用絕大部分功能。提供  JSON 、 XML ,、以及  HTML  等多種格式數據。

本實作使用 WeMos LoLin32 開發板,WiFi 802.11b/g/n 進行基地台連線並取得網站資料。直接將 WeMos LoLin32 以 USB 線連接到開發電腦進行程式編譯上傳即可。使用Arduino IDE 編譯 ESP32 程式前請先確認已經正確選定開發板規格。

取得開發API Key後串接取得天氣資料的網址格式如下,詳細網址參數說明請參考這裡
http://api.openweathermap.org/data/2.5/weather?q=天氣地區&appid=開發金鑰
完整程式內容如下:
#include <HTTPClient.h.h>

const char ssid[] = "Wi-Fi站點名稱";
const char password[] = "Wi-Fi連入密碼";
String API_KEY = "你的開發 API Key";
String area = "Taipei,TW"; //欲取得天氣資料的地區名稱

HTTPClient http;

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, psw);

  while (WiFi.status() != WL_CONNECTED) { //WiFi.status()回傳值意義詳見文後
    delay(500);
    Serial.print("無線基地台連線中... \n");
  }
  Serial.print("無線模組當前的IP:");
  Serial.println(WiFi.localIP() );
  
  openWeather();
}

void openWeather() {
  String weatherUrl = "http://api.openweathermap.org/data/2.5/weather?q=" +
               area + "&appid=" + API_KEY; //串接取得天氣資料的網址
               
  if ((WiFi.status() == WL_CONNECTED)) {
    http.begin(weatherUrl); // 指定連結網址
    int httpCode = http.GET();  // 以GET方式主動發出請求

    if (httpCode > 0) { // 伺服器狀態碼(返回數值型別:int類型)
      String weatherData = http.getString();
      Serial.println("取得jason格式的天氣資料如下:");
      Serial.println(weatherData.c_str());
    } else {
      Serial.println("網頁資料請求失敗!!");
    }
    http.end();
  }
}

void loop() {
}
WiFi.status()回傳值意義說明:
 0: WL_IDLE_STATUS – 返回值為0, 正在嘗試連接
 1: WL_NO_SSID_AVAIL – 返回值為1, 沒有找到設定的SSID的網路
 2: WL_SCAN_COMPLETED – 返回值為2, 網路掃描完畢
 3: WL_CONNECTED – 返回值為3, 連接成功
 4: WL_CONNECT_FAILED – 返回值為4, 連接失敗
 5: WL_CONNECTION_LOST – 返回值為5, 連接中斷
 6: WL_DISCONNECTED – 返回值為6, 未連接