OpenWeatherMap.cpp
  1  // SPDX-FileCopyrightText: 2019 Dan Cogliano for Adafruit Industries
  2  //
  3  // SPDX-License-Identifier: MIT
  4  
  5  #include "OpenWeatherMap.h"
  6  
  7  String AirliftOpenWeatherMap::buildUrlCurrent(String appId, String location) {
  8    String units = OWM_METRIC ? "metric" : "imperial";
  9    return "http://api.openweathermap.org/data/2.5/weather?q=" + location + "&appid=" + appId + "&units=" + units + "&lang=" + String(OWM_LANGUAGE);
 10  }
 11  
 12  String AirliftOpenWeatherMap::buildUrlForecast(String appId, String location) {
 13    String units = OWM_METRIC ? "metric" : "imperial";
 14    return "http://api.openweathermap.org/data/2.5/forecast?q=" + location + "&cnt=6&appid=" + appId + "&units=" + units + "&lang=" + String(OWM_LANGUAGE);
 15  }
 16  
 17  String AirliftOpenWeatherMap::getMeteoconIcon(String icon) {
 18    // clear sky
 19    // 01d
 20    if (icon == "01d") 	{
 21      return "B";
 22    }
 23    // 01n
 24    if (icon == "01n") 	{
 25      return "C";
 26    }
 27    // few clouds
 28    // 02d
 29    if (icon == "02d") 	{
 30      return "H";
 31    }
 32    // 02n
 33    if (icon == "02n") 	{
 34      return "4";
 35    }
 36    // scattered clouds
 37    // 03d
 38    if (icon == "03d") 	{
 39      return "N";
 40    }
 41    // 03n
 42    if (icon == "03n") 	{
 43      return "5";
 44    }
 45    // broken clouds
 46    // 04d
 47    if (icon == "04d") 	{
 48      return "Y";
 49    }
 50    // 04n
 51    if (icon == "04n") 	{
 52      return "%";
 53    }
 54    // shower rain
 55    // 09d
 56    if (icon == "09d") 	{
 57      return "R";
 58    }
 59    // 09n
 60    if (icon == "09n") 	{
 61      return "8";
 62    }
 63    // rain
 64    // 10d
 65    if (icon == "10d") 	{
 66      return "Q";
 67    }
 68    // 10n
 69    if (icon == "10n") 	{
 70      return "7";
 71    }
 72    // thunderstorm
 73    // 11d
 74    if (icon == "11d") 	{
 75      return "P";
 76    }
 77    // 11n
 78    if (icon == "11n") 	{
 79      return "6";
 80    }
 81    // snow
 82    // 13d
 83    if (icon == "13d") 	{
 84      return "W";
 85    }
 86    // 13n
 87    if (icon == "13n") 	{
 88      return "#";
 89    }
 90    // mist
 91    // 50d
 92    if (icon == "50d") 	{
 93      return "M";
 94    }
 95    // 50n
 96    if (icon == "50n") 	{
 97      return "M";
 98    }
 99    // Nothing matched: N/A
100    return ")";
101  
102  }
103  
104  bool AirliftOpenWeatherMap::updateCurrent(OpenWeatherMapCurrentData &data, String json)
105  {
106    Serial->println("updateCurrent()");
107    DynamicJsonDocument doc(2000);
108    //StaticJsonDocument<2000> doc;
109  
110    DeserializationError error = deserializeJson(doc, json);
111    if (error) {
112      Serial->println(String("deserializeJson() failed: ") + (const char *)error.c_str());
113      Serial->println(json);
114      setError(String("deserializeJson() failed: ") + error.c_str());
115      return false;
116    }
117  
118    int code = (int) doc["cod"];
119    if(code != 200)
120    {
121      Serial->println(String("OpenWeatherMap error: ") + (const char *)doc["message"]);
122      setError(String("OpenWeatherMap error: ") + (const char *)doc["message"]);
123      return false;
124    }
125    
126    data.lat = (float) doc["coord"]["lat"];
127    data.lon = (float) doc["coord"]["lon"];
128    
129    data.main = (const char*) doc["weather"][0]["main"];  
130    data.description = (const char*) doc["weather"][0]["description"];
131    data.icon = (const char*) doc["weather"][0]["icon"];
132    
133    data.cityName = (const char*) doc["name"];
134    data.visibility = (uint16_t) doc["visibility"];
135    data.timezone = (time_t) doc["timezone"];
136    
137    data.country = (const char*) doc["sys"]["country"];
138    data.observationTime = (time_t) doc["dt"];
139    data.sunrise = (time_t) doc["sys"]["sunrise"];
140    data.sunset = (time_t) doc["sys"]["sunset"];
141    
142    data.temp = (float) doc["main"]["temp"];
143    data.pressure = (uint16_t) doc["main"]["pressure"];
144    data.humidity = (uint8_t) doc["main"]["humidity"];
145    data.tempMin = (float) doc["main"]["temp_min"];
146    data.tempMax = (float) doc["main"]["temp_max"];
147  
148    data.windSpeed = (float) doc["wind"]["speed"];
149    data.windDeg = (float) doc["wind"]["deg"];
150    return true;
151  }
152  
153  bool AirliftOpenWeatherMap::updateForecast(OpenWeatherMapForecastData &data, String json, int day)
154  {
155    Serial->println("updateForecast()");
156    DynamicJsonDocument doc(5000);
157    //StaticJsonDocument<5000> doc;
158  
159    DeserializationError error = deserializeJson(doc, json);
160    if (error) {
161      Serial->println(String("deserializeJson() failed: ") + (const char *)error.c_str());
162      Serial->println(json);
163      setError(String("deserializeJson() failed: ") + error.c_str());
164      return false;
165    }
166  
167    int code = (int) doc["cod"];
168    if(code != 200)
169    {
170      Serial->println(String("OpenWeatherMap error: ") + (const char *)doc["message"]);
171      setError(String("OpenWeatherMap error: ") + (const char *)doc["message"]);
172      return false;
173    }
174  
175    data.observationTime = (time_t) doc["list"][day]["dt"];
176  
177    data.temp = (float) doc["list"][day]["main"]["temp"];
178    data.pressure = (uint16_t) doc["list"][day]["main"]["pressure"];
179    data.humidity = (uint8_t) doc["list"][day]["main"]["humidity"];
180    data.tempMin = (float) doc["list"][day]["main"]["temp_min"];
181    data.tempMax = (float) doc["list"][day]["main"]["temp_max"];
182  
183    data.main = (const char*) doc["list"][day]["weather"][0]["main"];  
184    data.description = (const char*) doc["list"][day]["weather"][0]["description"];
185    data.icon = (const char*) doc["list"][day]["weather"][0]["icon"];
186    return true;
187  }