1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-11 15:47:59 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/Weather.java
José Rebelo 81aef0bf35 Add support for multiple weather locations
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.
2024-03-29 21:10:40 +00:00

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);
}
}
}