검색해 보면 날씨정보를 받아오는 방법은 여러 가지입니다.
기상청이나 여타 날씨관련 사이트 등에서도 가능하지만 여러 모로 알아본 결과 openweathermap 이 편리할 것 같더군요
1. 오픈웨더맵 가입 - api 를 생성합니다.
이후
http://api.openweathermap.org/data/2.5/weather?q=yourCityName,yourCountryCode&APPID=yourUniqueAPIkey |
위 텍스트에서 yourCityName / yourCountryCode / yourUniqueAPIkey를 수정해야 하는데요.
서울을 예로 들면
검색하면 이렇게 나오는데 yourCityName 은 Seoul, yourCountryCode 은 KR 을 넣으면 됩니다
그리고 마지막 yourUniqueAPIkey 를 처음 발급받은 API 를 복사해서 수정하면 전체 주소가 완성됩니다.
그 주소를 인터넷 창에 입력해보면 다음과 같이 날씨 데이터가 표시되는 것을 알 수 있습니다
이제 이 API 주소를 이용해 ESP32C3 에서 날씨 데이터를 받아와 보겠습니다.
맨 먼저 날씨 데이터가 JSON 형식으로 나오기 때문에 이를 처리할 Arduino_JSON 라이브러리를 설치해 줬습니다.
이번에는 초기 코드를 99% 이상 ChapGPT 4.0에게 맡겼습니다.
예전보다 훨씬 뛰어나져서 원하는 대로 코드를 깔끔하게 짜 주네요.
저는 세부 사항 몇가지를 조정하고 두세번 다시 물어보는 정도로 코드를 완성할 수 있었습니다.
전체 코드는 아래와 같습니다.
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>
const char* ssid = "YourWifiID";
const char* password = "YourWifiPassword";
// Your Domain name with URL path or IP address with path
String openWeatherMapApiKey = "YourAPI";
// Replace with your country code and city
String city = "Seoul";
String countryCode = "KR";
// Timer set to 15 seconds for demonstration
unsigned long lastTime = 0;
unsigned long timerDelay = 15000;
String jsonBuffer;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer set to 15 seconds (timerDelay variable), it will take 15 seconds before publishing the first reading.");
}
void loop() {
if ((millis() - lastTime) > timerDelay) {
if (WiFi.status() == WL_CONNECTED) {
String serverPath = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "," + countryCode + "&APPID=" + openWeatherMapApiKey;
jsonBuffer = httpGETRequest(serverPath.c_str());
JSONVar myObject = JSON.parse(jsonBuffer);
if (JSON.typeof(myObject) == "undefined") {
Serial.println("Parsing input failed!");
return;
}
Serial.print("Latitude: ");
Serial.println(myObject["coord"]["lat"]);
Serial.print("Longitude: ");
Serial.println(myObject["coord"]["lon"]);
Serial.println("Weather Details:");
for (int i = 0; i < myObject["weather"].length(); i++) {
Serial.print(" Weather ID: ");
Serial.println(myObject["weather"][i]["id"]);
Serial.print(" Main: ");
Serial.println(myObject["weather"][i]["main"]);
Serial.print(" Description: ");
Serial.println(myObject["weather"][i]["description"]);
Serial.print(" Icon: ");
Serial.println(myObject["weather"][i]["icon"]);
}
Serial.print("Temperature: ");
Serial.println(myObject["main"]["temp"]);
Serial.print("Feels Like: ");
Serial.println(myObject["main"]["feels_like"]);
Serial.print("Minimum Temperature: ");
Serial.println(myObject["main"]["temp_min"]);
Serial.print("Maximum Temperature: ");
Serial.println(myObject["main"]["temp_max"]);
Serial.print("Pressure: ");
Serial.println(myObject["main"]["pressure"]);
Serial.print("Humidity: ");
Serial.println(myObject["main"]["humidity"]);
Serial.print("Wind Speed: ");
Serial.println(myObject["wind"]["speed"]);
Serial.print("Wind Direction (Degrees): ");
Serial.println(myObject["wind"]["deg"]);
if (myObject["wind"].hasOwnProperty("gust")) {
Serial.print("Wind Gust: ");
Serial.println(myObject["wind"]["gust"]);
}
if (myObject.hasOwnProperty("rain")) {
Serial.print("Rain Volume for last hour: ");
Serial.println(myObject["rain"]["1h"]);
}
if (myObject.hasOwnProperty("snow")) {
Serial.print("Snow Volume for last hour: ");
Serial.println(myObject["snow"]["1h"]);
}
Serial.print("Visibility: ");
Serial.println(myObject["visibility"]);
Serial.print("Cloudiness (%): ");
Serial.println(myObject["clouds"]["all"]);
lastTime = millis();
} else {
Serial.println("WiFi Disconnected");
}
}
}
String httpGETRequest(const char* serverName) {
WiFiClient client;
HTTPClient http;
http.begin(client, serverName);
int httpResponseCode = http.GET();
String payload = "{}";
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
} else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
return payload;
}
아래가 출력 결과입니다.
완벽합니다.
여담이지만 재미있던 것은 제가 출력 반복 간격을 늦추려고 10000(10초)를 15000(15초)로 변경했더니
바로 다음 질답에서 시리얼 출력의 'Timer set to 10 seconds...' 부분을 'Timer set to 15 seconds...' 로 바꾸더군요
이런 센스(?)까지 발휘하는 모습에 다소 놀랐습니다.
'Making > ESP32 날씨 표시기' 카테고리의 다른 글
ESP32 날씨 표시기 #5 - ChatGPT 코드 정리. (0) | 2024.05.29 |
---|---|
ESP32 날씨 표시기 #4 - 공공 데이터 포털. (0) | 2024.05.29 |
ESP32 날씨 표시기 #3 - openweathermap 데이터 분류와 정리. (0) | 2024.05.12 |
ESP32 날씨 표시기 #1 (2) | 2024.05.06 |