mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-09-07 15:05:25 +02:00
Introduce the concept of primary and secondary weathers: * Primary weather keeps the same behavior as previously across all weather providers, so it's non-breaking. This location is not necessarily the current location, just the primary weather location set by the user. * The GenericWeatherReceiver now has a new extra WeatherSecondaryJson, that receives a json list with secondary weather locations. It's guaranteed that the primary weather always exists, so the list of WeatherSpecs provided to devices is never empty. Update all support classes accordingly.
1214 lines
42 KiB
Java
1214 lines
42 KiB
Java
/* Copyright (C) 2016-2024 Andreas Shimokawa, Daniele Gobbetti, José Rebelo,
|
|
Petr Vaněk, Sebastian Kranz
|
|
|
|
This file is part of Gadgetbridge.
|
|
|
|
Gadgetbridge is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Gadgetbridge is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import org.json.JSONArray;
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.ObjectOutputStream;
|
|
import java.io.ObjectStreamException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
public class Weather {
|
|
private static final Logger LOG = LoggerFactory.getLogger(Weather.class);
|
|
|
|
private final ArrayList<WeatherSpec> weatherSpecs = new ArrayList<>();
|
|
|
|
private JSONObject reconstructedOWMForecast = null;
|
|
|
|
private File cacheFile;
|
|
|
|
private Weather() {
|
|
// Use getInstance
|
|
}
|
|
|
|
@Nullable
|
|
public WeatherSpec getWeatherSpec() {
|
|
if (weatherSpecs.isEmpty()) {
|
|
return null;
|
|
}
|
|
|
|
return weatherSpecs.get(0);
|
|
}
|
|
|
|
public List<WeatherSpec> getWeatherSpecs() {
|
|
return weatherSpecs;
|
|
}
|
|
|
|
public void setWeatherSpec(final List<WeatherSpec> newWeatherSpecs) {
|
|
weatherSpecs.clear();
|
|
weatherSpecs.addAll(newWeatherSpecs);
|
|
saveToCache();
|
|
}
|
|
|
|
public JSONObject createReconstructedOWMWeatherReply() {
|
|
final WeatherSpec weatherSpec = getWeatherSpec();
|
|
if (weatherSpec == null) {
|
|
return null;
|
|
}
|
|
JSONObject reconstructedOWMWeather = new JSONObject();
|
|
JSONArray weather = new JSONArray();
|
|
JSONObject condition = new JSONObject();
|
|
JSONObject main = new JSONObject();
|
|
JSONObject wind = new JSONObject();
|
|
|
|
try {
|
|
condition.put("id", weatherSpec.currentConditionCode);
|
|
condition.put("main", weatherSpec.currentCondition);
|
|
condition.put("description", weatherSpec.currentCondition);
|
|
condition.put("icon", Weather.mapToOpenWeatherMapIcon(weatherSpec.currentConditionCode));
|
|
weather.put(condition);
|
|
|
|
|
|
main.put("temp", weatherSpec.currentTemp);
|
|
main.put("humidity", weatherSpec.currentHumidity);
|
|
main.put("temp_min", weatherSpec.todayMinTemp);
|
|
main.put("temp_max", weatherSpec.todayMaxTemp);
|
|
|
|
wind.put("speed", (weatherSpec.windSpeed / 3.6f)); //meter per second
|
|
wind.put("deg", weatherSpec.windDirection);
|
|
|
|
reconstructedOWMWeather.put("weather", weather);
|
|
reconstructedOWMWeather.put("main", main);
|
|
reconstructedOWMWeather.put("name", weatherSpec.location);
|
|
reconstructedOWMWeather.put("wind", wind);
|
|
|
|
} catch (JSONException e) {
|
|
LOG.error("Error while reconstructing OWM weather reply");
|
|
return null;
|
|
}
|
|
LOG.debug("Weather JSON for WEBVIEW: " + reconstructedOWMWeather.toString());
|
|
return reconstructedOWMWeather;
|
|
}
|
|
|
|
public JSONObject getReconstructedOWMForecast() {
|
|
return reconstructedOWMForecast;
|
|
}
|
|
|
|
public void setReconstructedOWMForecast(JSONObject reconstructedOWMForecast) {
|
|
this.reconstructedOWMForecast = reconstructedOWMForecast;
|
|
}
|
|
|
|
private static final Weather weather = new Weather();
|
|
public static Weather getInstance() { return weather; }
|
|
|
|
public static byte mapToPebbleCondition(int openWeatherMapCondition) {
|
|
/* deducted values:
|
|
0 = sun + cloud
|
|
1 = clouds
|
|
2 = some snow
|
|
3 = some rain
|
|
4 = heavy rain
|
|
5 = heavy snow
|
|
6 = sun + cloud + rain (default icon?)
|
|
7 = sun
|
|
8 = rain + snow
|
|
9 = 6
|
|
10, 11, ... = empty icon
|
|
*/
|
|
switch (openWeatherMapCondition) {
|
|
//Group 2xx: Thunderstorm
|
|
case 200: //thunderstorm with light rain: //11d
|
|
case 201: //thunderstorm with rain: //11d
|
|
case 202: //thunderstorm with heavy rain: //11d
|
|
case 210: //light thunderstorm:: //11d
|
|
case 211: //thunderstorm: //11d
|
|
case 230: //thunderstorm with light drizzle: //11d
|
|
case 231: //thunderstorm with drizzle: //11d
|
|
case 232: //thunderstorm with heavy drizzle: //11d
|
|
case 212: //heavy thunderstorm: //11d
|
|
case 221: //ragged thunderstorm: //11d
|
|
return 4;
|
|
//Group 3xx: Drizzle
|
|
case 300: //light intensity drizzle: //09d
|
|
case 301: //drizzle: //09d
|
|
case 302: //heavy intensity drizzle: //09d
|
|
case 310: //light intensity drizzle rain: //09d
|
|
case 311: //drizzle rain: //09d
|
|
case 312: //heavy intensity drizzle rain: //09d
|
|
case 313: //shower rain and drizzle: //09d
|
|
case 314: //heavy shower rain and drizzle: //09d
|
|
case 321: //shower drizzle: //09d
|
|
case 500: //light rain: //10d
|
|
case 501: //moderate rain: //10d
|
|
return 3;
|
|
//Group 5xx: Rain
|
|
case 502: //heavy intensity rain: //10d
|
|
case 503: //very heavy rain: //10d
|
|
case 504: //extreme rain: //10d
|
|
case 511: //freezing rain: //13d
|
|
case 520: //light intensity shower rain: //09d
|
|
case 521: //shower rain: //09d
|
|
case 522: //heavy intensity shower rain: //09d
|
|
case 531: //ragged shower rain: //09d
|
|
return 4;
|
|
//Group 6xx: Snow
|
|
case 600: //light snow: //[[file:13d.png]]
|
|
case 601: //snow: //[[file:13d.png]]
|
|
case 620: //light shower snow: //[[file:13d.png]]
|
|
return 2;
|
|
case 602: //heavy snow: //[[file:13d.png]]
|
|
case 611: //sleet: //[[file:13d.png]]
|
|
case 612: //shower sleet: //[[file:13d.png]]
|
|
case 621: //shower snow: //[[file:13d.png]]
|
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
|
return 5;
|
|
case 615: //light rain and snow: //[[file:13d.png]]
|
|
case 616: //rain and snow: //[[file:13d.png]]
|
|
return 8;
|
|
//Group 7xx: Atmosphere
|
|
case 701: //mist: //[[file:50d.png]]
|
|
case 711: //smoke: //[[file:50d.png]]
|
|
case 721: //haze: //[[file:50d.png]]
|
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
|
case 741: //fog: //[[file:50d.png]]
|
|
case 751: //sand: //[[file:50d.png]]
|
|
case 761: //dust: //[[file:50d.png]]
|
|
case 762: //volcanic ash: //[[file:50d.png]]
|
|
case 771: //squalls: //[[file:50d.png]]
|
|
case 781: //tornado: //[[file:50d.png]]
|
|
case 900: //tornado
|
|
return 6;
|
|
//Group 800: Clear
|
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
|
return 7;
|
|
//Group 80x: Clouds
|
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
|
return 0;
|
|
//Group 90x: Extreme
|
|
case 901: //tropical storm
|
|
case 903: //cold
|
|
case 904: //hot
|
|
case 905: //windy
|
|
case 906: //hail
|
|
//Group 9xx: Additional
|
|
case 951: //calm
|
|
case 952: //light breeze
|
|
case 953: //gentle breeze
|
|
case 954: //moderate breeze
|
|
case 955: //fresh breeze
|
|
case 956: //strong breeze
|
|
case 957: //high windcase near gale
|
|
case 958: //gale
|
|
case 959: //severe gale
|
|
case 960: //storm
|
|
case 961: //violent storm
|
|
case 902: //hurricane
|
|
case 962: //hurricane
|
|
default:
|
|
return 6;
|
|
|
|
}
|
|
}
|
|
|
|
public static int mapToYahooCondition(int openWeatherMapCondition) {
|
|
// openweathermap.org conditions:
|
|
// http://openweathermap.org/weather-conditions
|
|
switch (openWeatherMapCondition) {
|
|
//Group 2xx: Thunderstorm
|
|
case 200: //thunderstorm with light rain: //11d
|
|
case 201: //thunderstorm with rain: //11d
|
|
case 202: //thunderstorm with heavy rain: //11d
|
|
case 210: //light thunderstorm:: //11d
|
|
case 211: //thunderstorm: //11d
|
|
case 230: //thunderstorm with light drizzle: //11d
|
|
case 231: //thunderstorm with drizzle: //11d
|
|
case 232: //thunderstorm with heavy drizzle: //11d
|
|
return 4;
|
|
case 212: //heavy thunderstorm: //11d
|
|
case 221: //ragged thunderstorm: //11d
|
|
return 3;
|
|
//Group 3xx: Drizzle
|
|
case 300: //light intensity drizzle: //09d
|
|
case 301: //drizzle: //09d
|
|
case 302: //heavy intensity drizzle: //09d
|
|
case 310: //light intensity drizzle rain: //09d
|
|
case 311: //drizzle rain: //09d
|
|
case 312: //heavy intensity drizzle rain: //09d
|
|
return 9;
|
|
case 313: //shower rain and drizzle: //09d
|
|
case 314: //heavy shower rain and drizzle: //09d
|
|
case 321: //shower drizzle: //09d
|
|
return 11;
|
|
//Group 5xx: Rain
|
|
case 500: //light rain: //10d
|
|
case 501: //moderate rain: //10d
|
|
case 502: //heavy intensity rain: //10d
|
|
case 503: //very heavy rain: //10d
|
|
case 504: //extreme rain: //10d
|
|
case 511: //freezing rain: //13d
|
|
return 10;
|
|
case 520: //light intensity shower rain: //09d
|
|
return 40;
|
|
case 521: //shower rain: //09d
|
|
case 522: //heavy intensity shower rain: //09d
|
|
case 531: //ragged shower rain: //09d
|
|
return 12;
|
|
//Group 6xx: Snow
|
|
case 600: //light snow: //[[file:13d.png]]
|
|
return 7;
|
|
case 601: //snow: //[[file:13d.png]]
|
|
return 16;
|
|
case 602: //heavy snow: //[[file:13d.png]]
|
|
return 15;
|
|
case 611: //sleet: //[[file:13d.png]]
|
|
case 612: //shower sleet: //[[file:13d.png]]
|
|
return 18;
|
|
case 615: //light rain and snow: //[[file:13d.png]]
|
|
case 616: //rain and snow: //[[file:13d.png]]
|
|
return 5;
|
|
case 620: //light shower snow: //[[file:13d.png]]
|
|
return 14;
|
|
case 621: //shower snow: //[[file:13d.png]]
|
|
return 46;
|
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
|
//Group 7xx: Atmosphere
|
|
case 701: //mist: //[[file:50d.png]]
|
|
case 711: //smoke: //[[file:50d.png]]
|
|
return 22;
|
|
case 721: //haze: //[[file:50d.png]]
|
|
return 21;
|
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
|
return 3200;
|
|
case 741: //fog: //[[file:50d.png]]
|
|
return 20;
|
|
case 751: //sand: //[[file:50d.png]]
|
|
case 761: //dust: //[[file:50d.png]]
|
|
return 19;
|
|
case 762: //volcanic ash: //[[file:50d.png]]
|
|
case 771: //squalls: //[[file:50d.png]]
|
|
return 3200;
|
|
case 781: //tornado: //[[file:50d.png]]
|
|
case 900: //tornado
|
|
return 0;
|
|
//Group 800: Clear
|
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
|
return 32;
|
|
//Group 80x: Clouds
|
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
|
return 34;
|
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
|
return 44;
|
|
//Group 90x: Extreme
|
|
case 901: //tropical storm
|
|
return 1;
|
|
case 903: //cold
|
|
return 25;
|
|
case 904: //hot
|
|
return 36;
|
|
case 905: //windy
|
|
return 24;
|
|
case 906: //hail
|
|
return 17;
|
|
//Group 9xx: Additional
|
|
case 951: //calm
|
|
case 952: //light breeze
|
|
case 953: //gentle breeze
|
|
case 954: //moderate breeze
|
|
case 955: //fresh breeze
|
|
return 34;
|
|
case 956: //strong breeze
|
|
case 957: //high windcase near gale
|
|
return 24;
|
|
case 958: //gale
|
|
case 959: //severe gale
|
|
case 960: //storm
|
|
case 961: //violent storm
|
|
return 3200;
|
|
case 902: //hurricane
|
|
case 962: //hurricane
|
|
return 2;
|
|
default:
|
|
return 3200;
|
|
|
|
}
|
|
}
|
|
|
|
public static String mapToOpenWeatherMapIcon(int openWeatherMapCondition) {
|
|
//see https://openweathermap.org/weather-conditions
|
|
String condition = "02d"; //generic "variable" icon
|
|
|
|
if (openWeatherMapCondition >= 200 && openWeatherMapCondition < 300) {
|
|
condition = "11d";
|
|
} else if (openWeatherMapCondition >= 300 && openWeatherMapCondition < 500) {
|
|
condition = "09d";
|
|
} else if (openWeatherMapCondition >= 500 && openWeatherMapCondition < 510) {
|
|
condition = "10d";
|
|
} else if (openWeatherMapCondition >= 511 && openWeatherMapCondition < 600) {
|
|
condition = "09d";
|
|
} else if (openWeatherMapCondition >= 600 && openWeatherMapCondition < 700) {
|
|
condition = "13d";
|
|
} else if (openWeatherMapCondition >= 700 && openWeatherMapCondition < 800) {
|
|
condition = "50d";
|
|
} else if (openWeatherMapCondition == 800) {
|
|
condition = "01d"; //TODO: night?
|
|
} else if (openWeatherMapCondition == 801) {
|
|
condition = "02d"; //TODO: night?
|
|
} else if (openWeatherMapCondition == 802) {
|
|
condition = "03d"; //TODO: night?
|
|
} else if (openWeatherMapCondition == 803 || openWeatherMapCondition == 804) {
|
|
condition = "04d"; //TODO: night?
|
|
}
|
|
|
|
return condition;
|
|
}
|
|
|
|
public static int mapToOpenWeatherMapCondition(int yahooCondition) {
|
|
switch (yahooCondition) {
|
|
//yahoo weather conditions:
|
|
//https://developer.yahoo.com/weather/documentation.html
|
|
case 0: //tornado
|
|
return 900;
|
|
case 1: //tropical storm
|
|
return 901;
|
|
case 2: //hurricane
|
|
return 962;
|
|
case 3: //severe thunderstorms
|
|
return 212;
|
|
case 4: //thunderstorms
|
|
return 211;
|
|
case 5: //mixed rain and snow
|
|
case 6: //mixed rain and sleet
|
|
return 616;
|
|
case 7: //mixed snow and sleet
|
|
return 600;
|
|
case 8: //freezing drizzle
|
|
case 9: //drizzle
|
|
return 301;
|
|
case 10: //freezing rain
|
|
return 511;
|
|
case 11: //showers
|
|
case 12: //showers
|
|
return 521;
|
|
case 13: //snow flurries
|
|
case 14: //light snow showers
|
|
return 620;
|
|
case 15: //blowing snow
|
|
case 41: //heavy snow
|
|
case 42: //scattered snow showers
|
|
case 43: //heavy snow
|
|
case 46: //snow showers
|
|
return 602;
|
|
case 16: //snow
|
|
return 601;
|
|
case 17: //hail
|
|
case 35: //mixed rain and hail
|
|
return 906;
|
|
case 18: //sleet
|
|
return 611;
|
|
case 19: //dust
|
|
return 761;
|
|
case 20: //foggy
|
|
return 741;
|
|
case 21: //haze
|
|
return 721;
|
|
case 22: //smoky
|
|
return 711;
|
|
case 23: //blustery
|
|
case 24: //windy
|
|
return 905;
|
|
case 25: //cold
|
|
return 903;
|
|
case 26: //cloudy
|
|
case 27: //mostly cloudy (night)
|
|
case 28: //mostly cloudy (day)
|
|
return 804;
|
|
case 29: //partly cloudy (night)
|
|
case 30: //partly cloudy (day)
|
|
return 801;
|
|
case 31: //clear (night)
|
|
case 32: //sunny
|
|
return 800;
|
|
case 33: //fair (night)
|
|
case 34: //fair (day)
|
|
return 801;
|
|
case 36: //hot
|
|
return 904;
|
|
case 37: //isolated thunderstorms
|
|
case 38: //scattered thunderstorms
|
|
case 39: //scattered thunderstorms
|
|
return 210;
|
|
case 40: //scattered showers
|
|
return 520;
|
|
case 44: //partly cloudy
|
|
return 801;
|
|
case 45: //thundershowers
|
|
case 47: //isolated thundershowers
|
|
return 211;
|
|
case 3200: //not available
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public static String getConditionString(int openWeatherMapCondition) {
|
|
switch (openWeatherMapCondition) {
|
|
case 200:
|
|
return "thunderstorm with light rain";
|
|
case 201:
|
|
return "thunderstorm with rain";
|
|
case 202:
|
|
return "thunderstorm with heavy rain";
|
|
case 210:
|
|
return "light thunderstorm:";
|
|
case 211:
|
|
return "thunderstorm";
|
|
case 230:
|
|
return "thunderstorm with light drizzle";
|
|
case 231:
|
|
return "thunderstorm with drizzle";
|
|
case 232:
|
|
return "thunderstorm with heavy drizzle";
|
|
case 212:
|
|
return "heavy thunderstorm";
|
|
case 221:
|
|
return "ragged thunderstorm";
|
|
//Group 3xx: Drizzle
|
|
case 300:
|
|
return "light intensity drizzle";
|
|
case 301:
|
|
return "drizzle";
|
|
case 302:
|
|
return "heavy intensity drizzle";
|
|
case 310:
|
|
return "light intensity drizzle rain";
|
|
case 311:
|
|
return "drizzle rain";
|
|
case 312:
|
|
return "heavy intensity drizzle rain";
|
|
case 313:
|
|
return "shower rain and drizzle";
|
|
case 314:
|
|
return "heavy shower rain and drizzle";
|
|
case 321:
|
|
return "shower drizzle";
|
|
//Group 5xx: Rain
|
|
case 500:
|
|
return "light rain";
|
|
case 501:
|
|
return "moderate rain";
|
|
case 502:
|
|
return "heavy intensity rain";
|
|
case 503:
|
|
return "very heavy rain";
|
|
case 504:
|
|
return "extreme rain";
|
|
case 511:
|
|
return "freezing rain";
|
|
case 520:
|
|
return "light intensity shower rain";
|
|
case 521:
|
|
return "shower rain";
|
|
case 522:
|
|
return "heavy intensity shower rain";
|
|
case 531:
|
|
return "ragged shower rain";
|
|
//Group 6xx: Snow
|
|
case 600:
|
|
return "light snow";
|
|
case 601:
|
|
return "snow";
|
|
case 620:
|
|
return "light shower snow";
|
|
case 602:
|
|
return "heavy snow";
|
|
case 611:
|
|
return "sleet";
|
|
case 612:
|
|
return "shower sleet";
|
|
case 621:
|
|
return "shower snow";
|
|
case 622:
|
|
return "heavy shower snow";
|
|
case 615:
|
|
return "light rain and snow";
|
|
case 616:
|
|
return "rain and snow";
|
|
//Group 7xx: Atmosphere
|
|
case 701:
|
|
return "mist";
|
|
case 711:
|
|
return "smoke";
|
|
case 721:
|
|
return "haze";
|
|
case 731:
|
|
return "sandcase dust whirls";
|
|
case 741:
|
|
return "fog";
|
|
case 751:
|
|
return "sand";
|
|
case 761:
|
|
return "dust";
|
|
case 762:
|
|
return "volcanic ash";
|
|
case 771:
|
|
return "squalls";
|
|
case 781:
|
|
return "tornado";
|
|
case 900:
|
|
return "tornado";
|
|
case 800:
|
|
return "clear sky";
|
|
//Group 80x: Clouds
|
|
case 801:
|
|
return "few clouds";
|
|
case 802:
|
|
return "scattered clouds";
|
|
case 803:
|
|
return "broken clouds";
|
|
case 804:
|
|
return "overcast clouds";
|
|
//Group 90x: Extreme
|
|
case 901:
|
|
return "tropical storm";
|
|
case 903:
|
|
return "cold";
|
|
case 904:
|
|
return "hot";
|
|
case 905:
|
|
return "windy";
|
|
case 906:
|
|
return "hail";
|
|
//Group 9xx: Additional
|
|
case 951:
|
|
return "calm";
|
|
case 952:
|
|
return "light breeze";
|
|
case 953:
|
|
return "gentle breeze";
|
|
case 954:
|
|
return "moderate breeze";
|
|
case 955:
|
|
return "fresh breeze";
|
|
case 956:
|
|
return "strong breeze";
|
|
case 957:
|
|
return "high windcase near gale";
|
|
case 958:
|
|
return "gale";
|
|
case 959:
|
|
return "severe gale";
|
|
case 960:
|
|
return "storm";
|
|
case 961:
|
|
return "violent storm";
|
|
case 902:
|
|
return "hurricane";
|
|
case 962:
|
|
return "hurricane";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
public static byte mapToZeTimeConditionOld(int openWeatherMapCondition) {
|
|
/* deducted values:
|
|
0 = partly cloudy
|
|
1 = cloudy
|
|
2 = sunny
|
|
3 = windy/gale
|
|
4 = heavy rain
|
|
5 = snowy
|
|
6 = storm
|
|
*/
|
|
switch (openWeatherMapCondition) {
|
|
//Group 2xx: Thunderstorm
|
|
case 200: //thunderstorm with light rain: //11d
|
|
case 201: //thunderstorm with rain: //11d
|
|
case 202: //thunderstorm with heavy rain: //11d
|
|
case 210: //light thunderstorm:: //11d
|
|
case 211: //thunderstorm: //11d
|
|
case 230: //thunderstorm with light drizzle: //11d
|
|
case 231: //thunderstorm with drizzle: //11d
|
|
case 232: //thunderstorm with heavy drizzle: //11d
|
|
case 212: //heavy thunderstorm: //11d
|
|
case 221: //ragged thunderstorm: //11d
|
|
//Group 7xx: Atmosphere
|
|
case 771: //squalls: //[[file:50d.png]]
|
|
case 781: //tornado: //[[file:50d.png]]
|
|
//Group 90x: Extreme
|
|
case 900: //tornado
|
|
case 901: //tropical storm
|
|
//Group 9xx: Additional
|
|
case 960: //storm
|
|
case 961: //violent storm
|
|
case 902: //hurricane
|
|
case 962: //hurricane
|
|
return 6;
|
|
//Group 3xx: Drizzle
|
|
case 300: //light intensity drizzle: //09d
|
|
case 301: //drizzle: //09d
|
|
case 302: //heavy intensity drizzle: //09d
|
|
case 310: //light intensity drizzle rain: //09d
|
|
case 311: //drizzle rain: //09d
|
|
case 312: //heavy intensity drizzle rain: //09d
|
|
case 313: //shower rain and drizzle: //09d
|
|
case 314: //heavy shower rain and drizzle: //09d
|
|
case 321: //shower drizzle: //09d
|
|
//Group 5xx: Rain
|
|
case 500: //light rain: //10d
|
|
case 501: //moderate rain: //10d
|
|
case 502: //heavy intensity rain: //10d
|
|
case 503: //very heavy rain: //10d
|
|
case 504: //extreme rain: //10d
|
|
case 511: //freezing rain: //13d
|
|
case 520: //light intensity shower rain: //09d
|
|
case 521: //shower rain: //09d
|
|
case 522: //heavy intensity shower rain: //09d
|
|
case 531: //ragged shower rain: //09d
|
|
//Group 90x: Extreme
|
|
case 906: //hail
|
|
return 4;
|
|
//Group 6xx: Snow
|
|
case 600: //light snow: //[[file:13d.png]]
|
|
case 601: //snow: //[[file:13d.png]]
|
|
case 620: //light shower snow: //[[file:13d.png]]
|
|
case 602: //heavy snow: //[[file:13d.png]]
|
|
case 611: //sleet: //[[file:13d.png]]
|
|
case 612: //shower sleet: //[[file:13d.png]]
|
|
case 621: //shower snow: //[[file:13d.png]]
|
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
|
case 615: //light rain and snow: //[[file:13d.png]]
|
|
case 616: //rain and snow: //[[file:13d.png]]
|
|
//Group 90x: Extreme
|
|
case 903: //cold
|
|
return 5;
|
|
//Group 7xx: Atmosphere
|
|
case 701: //mist: //[[file:50d.png]]
|
|
case 711: //smoke: //[[file:50d.png]]
|
|
case 721: //haze: //[[file:50d.png]]
|
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
|
case 741: //fog: //[[file:50d.png]]
|
|
case 751: //sand: //[[file:50d.png]]
|
|
case 761: //dust: //[[file:50d.png]]
|
|
case 762: //volcanic ash: //[[file:50d.png]]
|
|
return 1;
|
|
//Group 800: Clear
|
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
|
//Group 90x: Extreme
|
|
case 904: //hot
|
|
return 2;
|
|
//Group 80x: Clouds
|
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
|
default:
|
|
return 0;
|
|
|
|
//Group 9xx: Additional
|
|
case 905: //windy
|
|
case 951: //calm
|
|
case 952: //light breeze
|
|
case 953: //gentle breeze
|
|
case 954: //moderate breeze
|
|
case 955: //fresh breeze
|
|
case 956: //strong breeze
|
|
case 957: //high windcase near gale
|
|
case 958: //gale
|
|
case 959: //severe gale
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
public static byte mapToZeTimeCondition(int openWeatherMapCondition) {
|
|
/* deducted values:
|
|
0 = tornado
|
|
1 = typhoon
|
|
2 = hurricane
|
|
3 = thunderstorm
|
|
4 = rain and snow
|
|
5 = unavailable
|
|
6 = freezing rain
|
|
7 = drizzle
|
|
8 = showers
|
|
9 = snow flurries
|
|
10 = blowing snow
|
|
11 = snow
|
|
12 = sleet
|
|
13 = foggy
|
|
14 = windy
|
|
15 = cloudy
|
|
16 = partly cloudy (night)
|
|
17 = partly cloudy (day)
|
|
18 = clear night
|
|
19 = sunny
|
|
20 = thundershower
|
|
21 = hot
|
|
22 = scattered thunders
|
|
23 = snow showers
|
|
24 = heavy snow
|
|
*/
|
|
switch (openWeatherMapCondition) {
|
|
//Group 2xx: Thunderstorm
|
|
case 210: //light thunderstorm:: //11d
|
|
return 22;
|
|
|
|
//Group 2xx: Thunderstorm
|
|
case 200: //thunderstorm with light rain: //11d
|
|
case 201: //thunderstorm with rain: //11d
|
|
case 202: //thunderstorm with heavy rain: //11d
|
|
case 230: //thunderstorm with light drizzle: //11d
|
|
case 231: //thunderstorm with drizzle: //11d
|
|
case 232: //thunderstorm with heavy drizzle: //11d
|
|
return 20;
|
|
|
|
//Group 2xx: Thunderstorm
|
|
case 211: //thunderstorm: //11d
|
|
case 212: //heavy thunderstorm: //11d
|
|
case 221: //ragged thunderstorm: //11d
|
|
return 3;
|
|
|
|
//Group 7xx: Atmosphere
|
|
case 781: //tornado: //[[file:50d.png]]
|
|
//Group 90x: Extreme
|
|
case 900: //tornado
|
|
return 0;
|
|
|
|
//Group 90x: Extreme
|
|
case 901: //tropical storm
|
|
return 1;
|
|
|
|
// Group 7xx: Atmosphere
|
|
case 771: //squalls: //[[file:50d.png]]
|
|
//Group 9xx: Additional
|
|
case 960: //storm
|
|
case 961: //violent storm
|
|
case 902: //hurricane
|
|
case 962: //hurricane
|
|
return 2;
|
|
|
|
//Group 3xx: Drizzle
|
|
case 300: //light intensity drizzle: //09d
|
|
case 301: //drizzle: //09d
|
|
case 302: //heavy intensity drizzle: //09d
|
|
case 310: //light intensity drizzle rain: //09d
|
|
case 311: //drizzle rain: //09d
|
|
case 312: //heavy intensity drizzle rain: //09d
|
|
case 313: //shower rain and drizzle: //09d
|
|
case 314: //heavy shower rain and drizzle: //09d
|
|
case 321: //shower drizzle: //09d
|
|
return 7;
|
|
|
|
//Group 5xx: Rain
|
|
case 500: //light rain: //10d
|
|
case 501: //moderate rain: //10d
|
|
case 502: //heavy intensity rain: //10d
|
|
case 503: //very heavy rain: //10d
|
|
case 504: //extreme rain: //10d
|
|
case 520: //light intensity shower rain: //09d
|
|
case 521: //shower rain: //09d
|
|
case 522: //heavy intensity shower rain: //09d
|
|
case 531: //ragged shower rain: //09d
|
|
//Group 90x: Extreme
|
|
case 906: //hail
|
|
return 8;
|
|
|
|
//Group 5xx: Rain
|
|
case 511: //freezing rain: //13d
|
|
return 6;
|
|
|
|
//Group 6xx: Snow
|
|
case 620: //light shower snow: //[[file:13d.png]]
|
|
case 621: //shower snow: //[[file:13d.png]]
|
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
|
return 23;
|
|
|
|
//Group 6xx: Snow
|
|
case 615: //light rain and snow: //[[file:13d.png]]
|
|
case 616: //rain and snow: //[[file:13d.png]]
|
|
return 4;
|
|
|
|
//Group 6xx: Snow
|
|
case 611: //sleet: //[[file:13d.png]]
|
|
case 612: //shower sleet: //[[file:13d.png]]
|
|
return 12;
|
|
|
|
//Group 6xx: Snow
|
|
case 600: //light snow: //[[file:13d.png]]
|
|
case 601: //snow: //[[file:13d.png]]
|
|
return 11;
|
|
//Group 6xx: Snow
|
|
case 602: //heavy snow: //[[file:13d.png]]
|
|
return 24;
|
|
|
|
//Group 7xx: Atmosphere
|
|
case 701: //mist: //[[file:50d.png]]
|
|
case 711: //smoke: //[[file:50d.png]]
|
|
case 721: //haze: //[[file:50d.png]]
|
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
|
case 741: //fog: //[[file:50d.png]]
|
|
case 751: //sand: //[[file:50d.png]]
|
|
case 761: //dust: //[[file:50d.png]]
|
|
case 762: //volcanic ash: //[[file:50d.png]]
|
|
return 13;
|
|
|
|
//Group 800: Clear
|
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
|
return 19;
|
|
|
|
//Group 90x: Extreme
|
|
case 904: //hot
|
|
return 21;
|
|
|
|
//Group 80x: Clouds
|
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
|
return 17;
|
|
|
|
//Group 80x: Clouds
|
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
|
return 15;
|
|
|
|
//Group 9xx: Additional
|
|
case 905: //windy
|
|
case 951: //calm
|
|
case 952: //light breeze
|
|
case 953: //gentle breeze
|
|
case 954: //moderate breeze
|
|
case 955: //fresh breeze
|
|
case 956: //strong breeze
|
|
case 957: //high windcase near gale
|
|
case 958: //gale
|
|
case 959: //severe gale
|
|
return 14;
|
|
|
|
default:
|
|
//Group 90x: Extreme
|
|
case 903: //cold
|
|
return 5;
|
|
}
|
|
}
|
|
public static byte mapToCmfCondition(int openWeatherMapCondition) {
|
|
/* deducted values:
|
|
1 = sunny
|
|
2 = cloudy
|
|
3 = overcast
|
|
4 = showers
|
|
5 = snow showers
|
|
6 = fog
|
|
|
|
9 = thunder showers
|
|
|
|
14 = sleet
|
|
|
|
19 = hot (extreme)
|
|
20 = cold (extreme)
|
|
|
|
21 = strong wind
|
|
22 = (night) sunny - with moon
|
|
23 = (night) sunny with stars
|
|
24 = (night) cloudy - with moon
|
|
25 = sun with haze
|
|
26 = cloudy (sun with cloud)
|
|
*/
|
|
switch (openWeatherMapCondition) {
|
|
//Group 2xx: Thunderstorm
|
|
case 210: //light thunderstorm:: //11d
|
|
case 200: //thunderstorm with light rain: //11d
|
|
case 201: //thunderstorm with rain: //11d
|
|
case 202: //thunderstorm with heavy rain: //11d
|
|
case 230: //thunderstorm with light drizzle: //11d
|
|
case 231: //thunderstorm with drizzle: //11d
|
|
case 232: //thunderstorm with heavy drizzle: //11d
|
|
case 211: //thunderstorm: //11d
|
|
case 212: //heavy thunderstorm: //11d
|
|
case 221: //ragged thunderstorm: //11d
|
|
return 9;
|
|
|
|
//Group 90x: Extreme
|
|
case 901: //tropical storm
|
|
//Group 7xx: Atmosphere
|
|
case 781: //tornado: //[[file:50d.png]]
|
|
//Group 90x: Extreme
|
|
case 900: //tornado
|
|
// Group 7xx: Atmosphere
|
|
case 771: //squalls: //[[file:50d.png]]
|
|
//Group 9xx: Additional
|
|
case 960: //storm
|
|
case 961: //violent storm
|
|
case 902: //hurricane
|
|
case 962: //hurricane
|
|
return 21;
|
|
|
|
//Group 3xx: Drizzle
|
|
case 300: //light intensity drizzle: //09d
|
|
case 301: //drizzle: //09d
|
|
case 302: //heavy intensity drizzle: //09d
|
|
case 310: //light intensity drizzle rain: //09d
|
|
case 311: //drizzle rain: //09d
|
|
case 312: //heavy intensity drizzle rain: //09d
|
|
case 313: //shower rain and drizzle: //09d
|
|
case 314: //heavy shower rain and drizzle: //09d
|
|
case 321: //shower drizzle: //09d
|
|
//Group 5xx: Rain
|
|
case 500: //light rain: //10d
|
|
case 501: //moderate rain: //10d
|
|
case 502: //heavy intensity rain: //10d
|
|
case 503: //very heavy rain: //10d
|
|
case 504: //extreme rain: //10d
|
|
case 520: //light intensity shower rain: //09d
|
|
case 521: //shower rain: //09d
|
|
case 522: //heavy intensity shower rain: //09d
|
|
case 531: //ragged shower rain: //09d
|
|
return 4;
|
|
|
|
//Group 90x: Extreme
|
|
case 906: //hail
|
|
case 615: //light rain and snow: //[[file:13d.png]]
|
|
case 616: //rain and snow: //[[file:13d.png]]
|
|
case 511: //freezing rain: //13d
|
|
return 14;
|
|
|
|
//Group 6xx: Snow
|
|
case 611: //sleet: //[[file:13d.png]]
|
|
case 612: //shower sleet: //[[file:13d.png]]
|
|
//Group 6xx: Snow
|
|
case 600: //light snow: //[[file:13d.png]]
|
|
case 601: //snow: //[[file:13d.png]]
|
|
//Group 6xx: Snow
|
|
case 602: //heavy snow: //[[file:13d.png]]
|
|
//Group 6xx: Snow
|
|
case 620: //light shower snow: //[[file:13d.png]]
|
|
case 621: //shower snow: //[[file:13d.png]]
|
|
case 622: //heavy shower snow: //[[file:13d.png]]
|
|
return 5;
|
|
|
|
|
|
//Group 7xx: Atmosphere
|
|
case 701: //mist: //[[file:50d.png]]
|
|
case 711: //smoke: //[[file:50d.png]]
|
|
case 721: //haze: //[[file:50d.png]]
|
|
case 731: //sandcase dust whirls: //[[file:50d.png]]
|
|
case 741: //fog: //[[file:50d.png]]
|
|
case 751: //sand: //[[file:50d.png]]
|
|
case 761: //dust: //[[file:50d.png]]
|
|
case 762: //volcanic ash: //[[file:50d.png]]
|
|
return 6;
|
|
|
|
//Group 800: Clear
|
|
case 800: //clear sky: //[[file:01d.png]] [[file:01n.png]]
|
|
return 1;
|
|
|
|
//Group 90x: Extreme
|
|
case 904: //hot
|
|
return 19;
|
|
|
|
//Group 80x: Clouds
|
|
case 801: //few clouds: //[[file:02d.png]] [[file:02n.png]]
|
|
case 802: //scattered clouds: //[[file:03d.png]] [[file:03d.png]]
|
|
return 26;
|
|
case 803: //broken clouds: //[[file:04d.png]] [[file:03d.png]]
|
|
return 2;
|
|
|
|
//Group 80x: Clouds
|
|
case 804: //overcast clouds: //[[file:04d.png]] [[file:04d.png]]
|
|
return 3;
|
|
|
|
//Group 9xx: Additional
|
|
case 905: //windy
|
|
case 951: //calm
|
|
case 952: //light breeze
|
|
case 953: //gentle breeze
|
|
case 954: //moderate breeze
|
|
case 955: //fresh breeze
|
|
case 956: //strong breeze
|
|
case 957: //high windcase near gale
|
|
case 958: //gale
|
|
case 959: //severe gale
|
|
return 21;
|
|
|
|
default:
|
|
//Group 90x: Extreme
|
|
case 903: //cold
|
|
return 20;
|
|
}
|
|
}
|
|
|
|
public static byte mapToFitProCondition(int openWeatherMapCondition) {
|
|
switch (openWeatherMapCondition) {
|
|
case 100:
|
|
return 1;
|
|
case 104:
|
|
return 2;
|
|
case 101:
|
|
case 102:
|
|
case 103:
|
|
return 3;
|
|
case 305:
|
|
case 309:
|
|
return 4;
|
|
case 306:
|
|
case 314:
|
|
case 399:
|
|
return 5;
|
|
case 307:
|
|
case 308:
|
|
case 310:
|
|
case 311:
|
|
case 312:
|
|
case 315:
|
|
case 316:
|
|
case 317:
|
|
case 318:
|
|
return 6;
|
|
case 300:
|
|
case 301:
|
|
case 302:
|
|
case 303:
|
|
return 7;
|
|
case 400:
|
|
case 407:
|
|
return 8;
|
|
case 401:
|
|
case 408:
|
|
case 499:
|
|
return 9;
|
|
case 402:
|
|
case 403:
|
|
case 409:
|
|
case 410:
|
|
return 10;
|
|
case 404:
|
|
case 405:
|
|
case 406:
|
|
return 11;
|
|
case 500:
|
|
case 501:
|
|
case 502:
|
|
case 509:
|
|
case 510:
|
|
case 511:
|
|
case 512:
|
|
case 513:
|
|
case 514:
|
|
case 515:
|
|
return 12;
|
|
case 304:
|
|
case 313:
|
|
return 13;
|
|
case 503:
|
|
case 504:
|
|
case 507:
|
|
case 508:
|
|
return 14;
|
|
case 200:
|
|
case 201:
|
|
case 202:
|
|
case 203:
|
|
case 204:
|
|
return 15;
|
|
case 205:
|
|
case 206:
|
|
case 207:
|
|
case 208:
|
|
return 16;
|
|
case 209:
|
|
case 210:
|
|
case 211:
|
|
return 17;
|
|
case 212:
|
|
return 18;
|
|
case 231:
|
|
return 19;
|
|
default:
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the weather cache file. If enabled and the current weather is null, load the cache file.
|
|
*
|
|
* @param cacheDir the cache directory, where the cache file will be created
|
|
* @param enabled whether caching is enabled
|
|
*/
|
|
public void setCacheFile(final File cacheDir, final boolean enabled) {
|
|
// FIXME: Do not use serializable for this
|
|
|
|
cacheFile = new File(cacheDir, "weatherCache.bin");
|
|
|
|
if (enabled) {
|
|
LOG.info("Setting weather cache file to {}", cacheFile.getPath());
|
|
|
|
if (cacheFile.isFile() && weatherSpecs.isEmpty()) {
|
|
try (final ObjectInputStream o = new ObjectInputStream(new FileInputStream(cacheFile))) {
|
|
final ArrayList<WeatherSpec> cachedSpecs = (ArrayList<WeatherSpec>) o.readObject();
|
|
weatherSpecs.addAll(cachedSpecs);
|
|
} catch (final ObjectStreamException e) {
|
|
LOG.error("Failed to deserialize weather from cache", e);
|
|
// keep cacheFile set - it's most likely an older version
|
|
} catch (final IOException e) {
|
|
LOG.error("Failed to read weather cache file", e);
|
|
// Something is wrong with the file
|
|
cacheFile = null;
|
|
} catch (final Throwable e) {
|
|
LOG.error("Failed to read weather from cache", e);
|
|
// keep cacheFile set - it's most likely an older version
|
|
}
|
|
} else if (!weatherSpecs.isEmpty()) {
|
|
saveToCache();
|
|
}
|
|
} else {
|
|
if (cacheFile.isFile()) {
|
|
LOG.info("Deleting weather cache file {}", cacheFile.getPath());
|
|
|
|
try {
|
|
cacheFile.delete();
|
|
} catch (final Throwable e) {
|
|
LOG.error("Failed to delete cache file", e);
|
|
cacheFile = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save the current weather to cache, if a cache file is enabled and the weather is not null.
|
|
*/
|
|
public void saveToCache() {
|
|
if (weatherSpecs.isEmpty() || cacheFile == null) {
|
|
return;
|
|
}
|
|
|
|
LOG.info("Loading weather from cache {}", cacheFile.getPath());
|
|
|
|
try (ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(cacheFile))) {
|
|
o.writeObject(weatherSpecs);
|
|
} catch (final Throwable e) {
|
|
LOG.error("Failed to save weather to cache", e);
|
|
}
|
|
}
|
|
}
|