mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-18 05:17:08 +01:00
Introduce WeatherSpec v4
New fields for current weather: - dewPoint - pressure - cloudCover - visibility - sunRise - sunSet - moonRise - moonSet - moonPhase - airQuality - latitude - longitude - feelsLikeTemp - isCurrentLocation New fields for daily forecast: Deprecate the old "Forecast" class, which was not versioned, but keep it for backwards compatibility with old apps. Old WeatherSpec forecasts are de-serialized into the new Daily class. New fields: - windSpeed - windDirection - uvIndex - precipProbability - sunRise - sunSet - moonRise - moonSet - moonPhase - airQuality Add hourly values: - timestamp - temp - conditionCode - humidity - windSpeed - windDirection - uvIndex - precipProbability Air Quality: - aqi (plume) - co - no2 - o3 - pm10 - pm25 - so2 - coAqi - no2Aqi - o3Aqi - pm10Aqi - pm25Aqi - so2Aqi
This commit is contained in:
parent
b7e6a39ec1
commit
564cb1bfcc
@ -31,6 +31,8 @@ import android.companion.AssociationRequest;
|
|||||||
import android.companion.BluetoothDeviceFilter;
|
import android.companion.BluetoothDeviceFilter;
|
||||||
import android.companion.CompanionDeviceManager;
|
import android.companion.CompanionDeviceManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@ -77,9 +79,11 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -361,7 +365,7 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
weatherSpec.todayMaxTemp = 25 + 273;
|
weatherSpec.todayMaxTemp = 25 + 273;
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
final WeatherSpec.Forecast gbForecast = new WeatherSpec.Forecast();
|
final WeatherSpec.Daily gbForecast = new WeatherSpec.Daily();
|
||||||
gbForecast.minTemp = 10 + i + 273;
|
gbForecast.minTemp = 10 + i + 273;
|
||||||
gbForecast.maxTemp = 25 + i + 273;
|
gbForecast.maxTemp = 25 + i + 273;
|
||||||
|
|
||||||
@ -380,7 +384,7 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
showCachedWeatherButton.setOnClickListener(new View.OnClickListener(){
|
showCachedWeatherButton.setOnClickListener(new View.OnClickListener(){
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
String weatherInfo = getWeatherInfo();
|
final String weatherInfo = getWeatherInfo();
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(DebugActivity.this)
|
new MaterialAlertDialogBuilder(DebugActivity.this)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
@ -388,6 +392,11 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
.setMessage(weatherInfo)
|
.setMessage(weatherInfo)
|
||||||
.setPositiveButton(R.string.ok, (dialog, which) -> {
|
.setPositiveButton(R.string.ok, (dialog, which) -> {
|
||||||
})
|
})
|
||||||
|
.setNeutralButton(android.R.string.copy, (dialog, which) -> {
|
||||||
|
final ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText("Weather Info", weatherInfo);
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
})
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1032,34 +1041,110 @@ public class DebugActivity extends AbstractGBActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getWeatherInfo() {
|
private String getWeatherInfo() {
|
||||||
String info = "";
|
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ROOT);
|
||||||
|
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec();
|
WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec();
|
||||||
|
|
||||||
if (weatherSpec == null)
|
if (weatherSpec == null)
|
||||||
return "Weather cache is empty...";
|
return "Weather cache is empty...";
|
||||||
|
|
||||||
info += "Location: " + weatherSpec.location + "\n";
|
builder.append("Location: ").append(weatherSpec.location).append("\n");
|
||||||
info += "Timestamp: " + weatherSpec.timestamp + "\n";
|
builder.append("Timestamp: ").append(weatherSpec.timestamp).append("\n");
|
||||||
info += "Current Temp: " + weatherSpec.currentTemp + " K\n";
|
builder.append("Current Temp: ").append(weatherSpec.currentTemp).append(" K\n");
|
||||||
info += "Max Temp: " + weatherSpec.todayMaxTemp + " K\n";
|
builder.append("Max Temp: ").append(weatherSpec.todayMaxTemp).append(" K\n");
|
||||||
info += "Min Temp: " + weatherSpec.todayMinTemp + " K\n";
|
builder.append("Min Temp: ").append(weatherSpec.todayMinTemp).append(" K\n");
|
||||||
info += "Condition: " + weatherSpec.currentCondition + "\n";
|
builder.append("Condition: ").append(weatherSpec.currentCondition).append("\n");
|
||||||
info += "Condition Code: " + weatherSpec.currentConditionCode + "\n";
|
builder.append("Condition Code: ").append(weatherSpec.currentConditionCode).append("\n");
|
||||||
info += "Humidity: " + weatherSpec.currentHumidity + "\n";
|
builder.append("Humidity: ").append(weatherSpec.currentHumidity).append("\n");
|
||||||
info += "Wind Speed: " + weatherSpec.windSpeed + " kmph\n";
|
builder.append("Wind Speed: ").append(weatherSpec.windSpeed).append(" kmph\n");
|
||||||
info += "Wind Direction: " + weatherSpec.windDirection + " deg\n";
|
builder.append("Wind Direction: ").append(weatherSpec.windDirection).append(" deg\n");
|
||||||
info += "UV Index: " + weatherSpec.uvIndex + "\n";
|
builder.append("UV Index: ").append(weatherSpec.uvIndex).append("\n");
|
||||||
info += "Precip Probability: " + weatherSpec.precipProbability + " %\n";
|
builder.append("Precip Probability: ").append(weatherSpec.precipProbability).append(" %\n");
|
||||||
for (int i=0;i<weatherSpec.forecasts.size();i++) {
|
builder.append("Dew Point: ").append(weatherSpec.dewPoint).append(" K\n");
|
||||||
info += "-------------\n";
|
builder.append("Pressure: ").append(weatherSpec.pressure).append(" mb\n");
|
||||||
info += "-->Day " + i +"\n";
|
builder.append("Cloud Cover: ").append(weatherSpec.cloudCover).append(" %\n");
|
||||||
info += "Max Temp: " + weatherSpec.forecasts.get(i).maxTemp + " K\n";
|
builder.append("Visibility: ").append(weatherSpec.visibility).append(" m\n");
|
||||||
info += "Min Temp: " + weatherSpec.forecasts.get(i).minTemp + " K\n";
|
builder.append("Sun Rise: ").append(sdf.format(new Date(weatherSpec.sunRise * 1000L))).append("\n");
|
||||||
info += "Condition Code: " + weatherSpec.forecasts.get(i).conditionCode + "\n";
|
builder.append("Sun Set: ").append(sdf.format(new Date(weatherSpec.sunSet * 1000L))).append("\n");
|
||||||
info += "Humidity: " + weatherSpec.forecasts.get(i).humidity + "\n";
|
builder.append("Moon Rise: ").append(sdf.format(new Date(weatherSpec.moonRise * 1000L))).append("\n");
|
||||||
|
builder.append("Moon Set: ").append(sdf.format(new Date(weatherSpec.moonSet * 1000L))).append("\n");
|
||||||
|
builder.append("Moon Phase: ").append(weatherSpec.moonPhase).append(" deg\n");
|
||||||
|
builder.append("Latitude: ").append(weatherSpec.latitude).append("\n");
|
||||||
|
builder.append("Longitude: ").append(weatherSpec.longitude).append("\n");
|
||||||
|
builder.append("Feels Like Temp: ").append(weatherSpec.feelsLikeTemp).append(" K\n");
|
||||||
|
builder.append("Is Current Location: ").append(weatherSpec.isCurrentLocation).append("\n");
|
||||||
|
|
||||||
|
if (weatherSpec.airQuality != null) {
|
||||||
|
builder.append("Air Quality aqi: ").append(weatherSpec.airQuality.aqi).append("\n");
|
||||||
|
builder.append("Air Quality co: ").append(weatherSpec.airQuality.co).append("\n");
|
||||||
|
builder.append("Air Quality no2: ").append(weatherSpec.airQuality.no2).append("\n");
|
||||||
|
builder.append("Air Quality o3: ").append(weatherSpec.airQuality.o3).append("\n");
|
||||||
|
builder.append("Air Quality pm10: ").append(weatherSpec.airQuality.pm10).append("\n");
|
||||||
|
builder.append("Air Quality pm25: ").append(weatherSpec.airQuality.pm25).append("\n");
|
||||||
|
builder.append("Air Quality so2: ").append(weatherSpec.airQuality.so2).append("\n");
|
||||||
|
builder.append("Air Quality coAqi: ").append(weatherSpec.airQuality.coAqi).append("\n");
|
||||||
|
builder.append("Air Quality no2Aqi: ").append(weatherSpec.airQuality.no2Aqi).append("\n");
|
||||||
|
builder.append("Air Quality o3Aqi: ").append(weatherSpec.airQuality.o3Aqi).append("\n");
|
||||||
|
builder.append("Air Quality pm10Aqi: ").append(weatherSpec.airQuality.pm10Aqi).append("\n");
|
||||||
|
builder.append("Air Quality pm25Aqi: ").append(weatherSpec.airQuality.pm25Aqi).append("\n");
|
||||||
|
builder.append("Air Quality so2Aqi: ").append(weatherSpec.airQuality.so2Aqi).append("\n");
|
||||||
|
} else {
|
||||||
|
builder.append("Air Quality: null\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
int i = 0;
|
||||||
|
for (final WeatherSpec.Daily daily : weatherSpec.forecasts) {
|
||||||
|
builder.append("-------------\n");
|
||||||
|
builder.append("-->Day ").append(i++).append("\n");
|
||||||
|
builder.append("Max Temp: ").append(daily.maxTemp).append(" K\n");
|
||||||
|
builder.append("Min Temp: ").append(daily.minTemp).append(" K\n");
|
||||||
|
builder.append("Condition Code: ").append(daily.conditionCode).append("\n");
|
||||||
|
builder.append("Humidity: ").append(daily.humidity).append("\n");
|
||||||
|
builder.append("Wind Speed: ").append(daily.windSpeed).append(" kmph\n");
|
||||||
|
builder.append("Wind Direction: ").append(daily.windDirection).append(" deg\n");
|
||||||
|
builder.append("UV Index: ").append(daily.uvIndex).append("\n");
|
||||||
|
builder.append("Precip Probability: ").append(daily.precipProbability).append(" %\n");
|
||||||
|
builder.append("Sun Rise: ").append(sdf.format(new Date(daily.sunRise * 1000L))).append("\n");
|
||||||
|
builder.append("Sun Set: ").append(sdf.format(new Date(daily.sunSet * 1000L))).append("\n");
|
||||||
|
builder.append("Moon Rise: ").append(sdf.format(new Date(daily.moonRise * 1000L))).append("\n");
|
||||||
|
builder.append("Moon Set: ").append(sdf.format(new Date(daily.moonSet * 1000L))).append("\n");
|
||||||
|
builder.append("Moon Phase: ").append(daily.moonPhase).append(" deg\n");
|
||||||
|
|
||||||
|
if (daily.airQuality != null) {
|
||||||
|
builder.append("Air Quality aqi: ").append(daily.airQuality.aqi).append("\n");
|
||||||
|
builder.append("Air Quality co: ").append(daily.airQuality.co).append("\n");
|
||||||
|
builder.append("Air Quality no2: ").append(daily.airQuality.no2).append("\n");
|
||||||
|
builder.append("Air Quality o3: ").append(daily.airQuality.o3).append("\n");
|
||||||
|
builder.append("Air Quality pm10: ").append(daily.airQuality.pm10).append("\n");
|
||||||
|
builder.append("Air Quality pm25: ").append(daily.airQuality.pm25).append("\n");
|
||||||
|
builder.append("Air Quality so2: ").append(daily.airQuality.so2).append("\n");
|
||||||
|
builder.append("Air Quality coAqi: ").append(daily.airQuality.coAqi).append("\n");
|
||||||
|
builder.append("Air Quality no2Aqi: ").append(daily.airQuality.no2Aqi).append("\n");
|
||||||
|
builder.append("Air Quality o3Aqi: ").append(daily.airQuality.o3Aqi).append("\n");
|
||||||
|
builder.append("Air Quality pm10Aqi: ").append(daily.airQuality.pm10Aqi).append("\n");
|
||||||
|
builder.append("Air Quality pm25Aqi: ").append(daily.airQuality.pm25Aqi).append("\n");
|
||||||
|
builder.append("Air Quality so2Aqi: ").append(daily.airQuality.so2Aqi).append("\n");
|
||||||
|
} else {
|
||||||
|
builder.append("Air Quality: null\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("=============\n");
|
||||||
|
|
||||||
|
for (final WeatherSpec.Hourly hourly : weatherSpec.hourly) {
|
||||||
|
builder.append("-------------\n");
|
||||||
|
builder.append("-->Hour: ").append(sdf.format(new Date(hourly.timestamp * 1000L))).append("\n");
|
||||||
|
builder.append("Max Temp: ").append(hourly.temp).append(" K\n");
|
||||||
|
builder.append("Condition Code: ").append(hourly.conditionCode).append("\n");
|
||||||
|
builder.append("Humidity: ").append(hourly.humidity).append("\n");
|
||||||
|
builder.append("Wind Speed: ").append(hourly.windSpeed).append(" kmph\n");
|
||||||
|
builder.append("Wind Direction: ").append(hourly.windDirection).append(" deg\n");
|
||||||
|
builder.append("UV Index: ").append(hourly.uvIndex).append("\n");
|
||||||
|
builder.append("Precip Probability: ").append(hourly.precipProbability).append(" %\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LinkedHashMap getAllSupportedDevices(Context appContext) {
|
public static LinkedHashMap getAllSupportedDevices(Context appContext) {
|
||||||
|
@ -32,7 +32,7 @@ public class AsteroidOSWeather {
|
|||||||
* Creates a Day from the forecast given
|
* Creates a Day from the forecast given
|
||||||
* @param forecast
|
* @param forecast
|
||||||
*/
|
*/
|
||||||
public Day(WeatherSpec.Forecast forecast) {
|
public Day(WeatherSpec.Daily forecast) {
|
||||||
minTemp = forecast.minTemp;
|
minTemp = forecast.minTemp;
|
||||||
maxTemp = forecast.maxTemp;
|
maxTemp = forecast.maxTemp;
|
||||||
condition = forecast.conditionCode;
|
condition = forecast.conditionCode;
|
||||||
|
@ -258,7 +258,7 @@ public class SMAQ2OSSSupport extends AbstractBTLEDeviceSupport {
|
|||||||
setWeather.setTemperatureMax(weatherSpec.todayMaxTemp-273);
|
setWeather.setTemperatureMax(weatherSpec.todayMaxTemp-273);
|
||||||
setWeather.setHumidity(weatherSpec.currentHumidity);
|
setWeather.setHumidity(weatherSpec.currentHumidity);
|
||||||
|
|
||||||
for (WeatherSpec.Forecast f:weatherSpec.forecasts) {
|
for (WeatherSpec.Daily f:weatherSpec.forecasts) {
|
||||||
|
|
||||||
SMAQ2OSSProtos.Forecast.Builder fproto = SMAQ2OSSProtos.Forecast.newBuilder();
|
SMAQ2OSSProtos.Forecast.Builder fproto = SMAQ2OSSProtos.Forecast.newBuilder();
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ public class CMWeatherReceiver extends BroadcastReceiver implements CMWeatherMan
|
|||||||
List<WeatherInfo.DayForecast> forecasts = weatherInfo.getForecasts();
|
List<WeatherInfo.DayForecast> forecasts = weatherInfo.getForecasts();
|
||||||
for (int i = 1; i < forecasts.size(); i++) {
|
for (int i = 1; i < forecasts.size(); i++) {
|
||||||
WeatherInfo.DayForecast cmForecast = forecasts.get(i);
|
WeatherInfo.DayForecast cmForecast = forecasts.get(i);
|
||||||
WeatherSpec.Forecast gbForecast = new WeatherSpec.Forecast();
|
WeatherSpec.Daily gbForecast = new WeatherSpec.Daily();
|
||||||
if (weatherInfo.getTemperatureUnit() == FAHRENHEIT) {
|
if (weatherInfo.getTemperatureUnit() == FAHRENHEIT) {
|
||||||
gbForecast.maxTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getHigh()) + 273;
|
gbForecast.maxTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getHigh()) + 273;
|
||||||
gbForecast.minTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getLow()) + 273;
|
gbForecast.minTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getLow()) + 273;
|
||||||
|
@ -63,6 +63,23 @@ public class GenericWeatherReceiver extends BroadcastReceiver {
|
|||||||
weatherSpec.windDirection = safelyGet(weatherJson, Integer.class, "windDirection", 0);
|
weatherSpec.windDirection = safelyGet(weatherJson, Integer.class, "windDirection", 0);
|
||||||
weatherSpec.uvIndex = safelyGet(weatherJson, Number.class, "uvIndex", 0d).floatValue();
|
weatherSpec.uvIndex = safelyGet(weatherJson, Number.class, "uvIndex", 0d).floatValue();
|
||||||
weatherSpec.precipProbability = safelyGet(weatherJson, Integer.class, "precipProbability", 0);
|
weatherSpec.precipProbability = safelyGet(weatherJson, Integer.class, "precipProbability", 0);
|
||||||
|
weatherSpec.dewPoint = safelyGet(weatherJson, Integer.class, "dewPoint", 0);
|
||||||
|
weatherSpec.pressure = safelyGet(weatherJson, Number.class, "pressure", 0).floatValue();
|
||||||
|
weatherSpec.cloudCover = safelyGet(weatherJson, Integer.class, "cloudCover", 0);
|
||||||
|
weatherSpec.visibility = safelyGet(weatherJson, Number.class, "visibility", 0).floatValue();
|
||||||
|
weatherSpec.sunRise = safelyGet(weatherJson, Integer.class, "sunRise", 0);
|
||||||
|
weatherSpec.sunSet = safelyGet(weatherJson, Integer.class, "sunSet", 0);
|
||||||
|
weatherSpec.moonRise = safelyGet(weatherJson, Integer.class, "moonRise", 0);
|
||||||
|
weatherSpec.moonSet = safelyGet(weatherJson, Integer.class, "moonSet", 0);
|
||||||
|
weatherSpec.moonPhase = safelyGet(weatherJson, Integer.class, "moonPhase", 0);
|
||||||
|
weatherSpec.latitude = safelyGet(weatherJson, Number.class, "latitude", 0).floatValue();
|
||||||
|
weatherSpec.longitude = safelyGet(weatherJson, Number.class, "longitude", 0).floatValue();
|
||||||
|
weatherSpec.feelsLikeTemp = safelyGet(weatherJson, Integer.class, "feelsLikeTemp", 0);
|
||||||
|
weatherSpec.isCurrentLocation = safelyGet(weatherJson, Integer.class, "isCurrentLocation", -1);
|
||||||
|
|
||||||
|
if (weatherJson.has("airQuality")) {
|
||||||
|
weatherSpec.airQuality = toAirQuality(weatherJson.getJSONObject("airQuality"));
|
||||||
|
}
|
||||||
|
|
||||||
if (weatherJson.has("forecasts")) {
|
if (weatherJson.has("forecasts")) {
|
||||||
JSONArray forecastArray = weatherJson.getJSONArray("forecasts");
|
JSONArray forecastArray = weatherJson.getJSONArray("forecasts");
|
||||||
@ -71,17 +88,52 @@ public class GenericWeatherReceiver extends BroadcastReceiver {
|
|||||||
for (int i = 0, l = forecastArray.length(); i < l; i++) {
|
for (int i = 0, l = forecastArray.length(); i < l; i++) {
|
||||||
JSONObject forecastJson = forecastArray.getJSONObject(i);
|
JSONObject forecastJson = forecastArray.getJSONObject(i);
|
||||||
|
|
||||||
WeatherSpec.Forecast forecast = new WeatherSpec.Forecast();
|
WeatherSpec.Daily forecast = new WeatherSpec.Daily();
|
||||||
|
|
||||||
forecast.conditionCode = safelyGet(forecastJson, Integer.class, "conditionCode", 0);
|
forecast.conditionCode = safelyGet(forecastJson, Integer.class, "conditionCode", 0);
|
||||||
forecast.humidity = safelyGet(forecastJson, Integer.class, "humidity", 0);
|
forecast.humidity = safelyGet(forecastJson, Integer.class, "humidity", 0);
|
||||||
forecast.maxTemp = safelyGet(forecastJson, Integer.class, "maxTemp", 0);
|
forecast.maxTemp = safelyGet(forecastJson, Integer.class, "maxTemp", 0);
|
||||||
forecast.minTemp = safelyGet(forecastJson, Integer.class, "minTemp", 0);
|
forecast.minTemp = safelyGet(forecastJson, Integer.class, "minTemp", 0);
|
||||||
|
forecast.windSpeed = safelyGet(forecastJson, Number.class, "windSpeed", 0).floatValue();
|
||||||
|
forecast.windDirection = safelyGet(forecastJson, Integer.class, "windDirection", 0);
|
||||||
|
forecast.uvIndex = safelyGet(weatherJson, Number.class, "uvIndex", 0d).floatValue();
|
||||||
|
forecast.precipProbability = safelyGet(weatherJson, Integer.class, "precipProbability", 0);
|
||||||
|
forecast.sunRise = safelyGet(forecastJson, Integer.class, "sunRise", 0);
|
||||||
|
forecast.sunSet = safelyGet(forecastJson, Integer.class, "sunSet", 0);
|
||||||
|
forecast.moonRise = safelyGet(forecastJson, Integer.class, "moonRise", 0);
|
||||||
|
forecast.moonSet = safelyGet(forecastJson, Integer.class, "moonSet", 0);
|
||||||
|
forecast.moonPhase = safelyGet(forecastJson, Integer.class, "moonPhase", 0);
|
||||||
|
|
||||||
|
if (forecastJson.has("airQuality")) {
|
||||||
|
forecast.airQuality = toAirQuality(forecastJson.getJSONObject("airQuality"));
|
||||||
|
}
|
||||||
|
|
||||||
weatherSpec.forecasts.add(forecast);
|
weatherSpec.forecasts.add(forecast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (weatherJson.has("hourly")) {
|
||||||
|
JSONArray forecastArray = weatherJson.getJSONArray("hourly");
|
||||||
|
weatherSpec.hourly = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0, l = forecastArray.length(); i < l; i++) {
|
||||||
|
JSONObject forecastJson = forecastArray.getJSONObject(i);
|
||||||
|
|
||||||
|
WeatherSpec.Hourly forecast = new WeatherSpec.Hourly();
|
||||||
|
|
||||||
|
forecast.timestamp = safelyGet(forecastJson, Integer.class, "timestamp", 0);
|
||||||
|
forecast.temp = safelyGet(forecastJson, Integer.class, "temp", 0);
|
||||||
|
forecast.conditionCode = safelyGet(forecastJson, Integer.class, "conditionCode", 0);
|
||||||
|
forecast.humidity = safelyGet(forecastJson, Integer.class, "humidity", 0);
|
||||||
|
forecast.windSpeed = safelyGet(forecastJson, Number.class, "windSpeed", 0).floatValue();
|
||||||
|
forecast.windDirection = safelyGet(forecastJson, Integer.class, "windDirection", 0);
|
||||||
|
forecast.uvIndex = safelyGet(weatherJson, Number.class, "uvIndex", 0d).floatValue();
|
||||||
|
forecast.precipProbability = safelyGet(weatherJson, Integer.class, "precipProbability", 0);
|
||||||
|
|
||||||
|
weatherSpec.hourly.add(forecast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG.info("Got generic weather for {}", weatherSpec.location);
|
LOG.info("Got generic weather for {}", weatherSpec.location);
|
||||||
|
|
||||||
Weather.getInstance().setWeatherSpec(weatherSpec);
|
Weather.getInstance().setWeatherSpec(weatherSpec);
|
||||||
@ -93,6 +145,25 @@ public class GenericWeatherReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private WeatherSpec.AirQuality toAirQuality(final JSONObject jsonObject) {
|
||||||
|
final WeatherSpec.AirQuality airQuality = new WeatherSpec.AirQuality();
|
||||||
|
airQuality.aqi = safelyGet(jsonObject, Integer.class, "aqi", -1);
|
||||||
|
airQuality.co = safelyGet(jsonObject, Number.class, "co", -1).floatValue();
|
||||||
|
airQuality.no2 = safelyGet(jsonObject, Number.class, "no2", -1).floatValue();
|
||||||
|
airQuality.o3 = safelyGet(jsonObject, Number.class, "o3", -1).floatValue();
|
||||||
|
airQuality.pm10 = safelyGet(jsonObject, Number.class, "pm10", -1).floatValue();
|
||||||
|
airQuality.pm25 = safelyGet(jsonObject, Number.class, "pm25", -1).floatValue();
|
||||||
|
airQuality.so2 = safelyGet(jsonObject, Number.class, "so2", -1).floatValue();
|
||||||
|
airQuality.coAqi = safelyGet(jsonObject, Integer.class, "coAqi", -1);
|
||||||
|
airQuality.no2Aqi = safelyGet(jsonObject, Integer.class, "no2Aqi", -1);
|
||||||
|
airQuality.o3Aqi = safelyGet(jsonObject, Integer.class, "o3Aqi", -1);
|
||||||
|
airQuality.pm10Aqi = safelyGet(jsonObject, Integer.class, "pm10Aqi", -1);
|
||||||
|
airQuality.pm25Aqi = safelyGet(jsonObject, Integer.class, "pm25Aqi", -1);
|
||||||
|
airQuality.so2Aqi = safelyGet(jsonObject, Integer.class, "so2Aqi", -1);
|
||||||
|
|
||||||
|
return airQuality;
|
||||||
|
}
|
||||||
|
|
||||||
private <T> T safelyGet(JSONObject jsonObject, Class<T> tClass, String name, T defaultValue) {
|
private <T> T safelyGet(JSONObject jsonObject, Class<T> tClass, String name, T defaultValue) {
|
||||||
try {
|
try {
|
||||||
if (jsonObject.has(name)) {
|
if (jsonObject.has(name)) {
|
||||||
|
@ -189,7 +189,7 @@ public class LineageOsWeatherReceiver extends BroadcastReceiver implements Linea
|
|||||||
List<WeatherInfo.DayForecast> forecasts = weatherInfo.getForecasts();
|
List<WeatherInfo.DayForecast> forecasts = weatherInfo.getForecasts();
|
||||||
for (int i = 1; i < forecasts.size(); i++) {
|
for (int i = 1; i < forecasts.size(); i++) {
|
||||||
WeatherInfo.DayForecast cmForecast = forecasts.get(i);
|
WeatherInfo.DayForecast cmForecast = forecasts.get(i);
|
||||||
WeatherSpec.Forecast gbForecast = new WeatherSpec.Forecast();
|
WeatherSpec.Daily gbForecast = new WeatherSpec.Daily();
|
||||||
if (weatherInfo.getTemperatureUnit() == FAHRENHEIT) {
|
if (weatherInfo.getTemperatureUnit() == FAHRENHEIT) {
|
||||||
gbForecast.maxTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getHigh()) + 273;
|
gbForecast.maxTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getHigh()) + 273;
|
||||||
gbForecast.minTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getLow()) + 273;
|
gbForecast.minTemp = (int) WeatherUtils.fahrenheitToCelsius(cmForecast.getLow()) + 273;
|
||||||
|
@ -127,7 +127,7 @@ public class OmniJawsObserver extends ContentObserver {
|
|||||||
weatherSpec.todayMaxTemp = toKelvin(c.getFloat(6));
|
weatherSpec.todayMaxTemp = toKelvin(c.getFloat(6));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
WeatherSpec.Forecast gbForecast = new WeatherSpec.Forecast();
|
WeatherSpec.Daily gbForecast = new WeatherSpec.Daily();
|
||||||
gbForecast.minTemp = toKelvin(c.getFloat(5));
|
gbForecast.minTemp = toKelvin(c.getFloat(5));
|
||||||
gbForecast.maxTemp = toKelvin(c.getFloat(6));
|
gbForecast.maxTemp = toKelvin(c.getFloat(6));
|
||||||
gbForecast.conditionCode = Weather.mapToOpenWeatherMapCondition(c.getInt(8));
|
gbForecast.conditionCode = Weather.mapToOpenWeatherMapCondition(c.getInt(8));
|
||||||
|
@ -38,7 +38,7 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
return new WeatherSpec[size];
|
return new WeatherSpec[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public static final int VERSION = 3;
|
public static final int VERSION = 4;
|
||||||
private static final long serialVersionUID = VERSION;
|
private static final long serialVersionUID = VERSION;
|
||||||
public int timestamp; // unix epoch timestamp, in seconds
|
public int timestamp; // unix epoch timestamp, in seconds
|
||||||
public String location;
|
public String location;
|
||||||
@ -52,10 +52,27 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
public int windDirection; // deg
|
public int windDirection; // deg
|
||||||
public float uvIndex;
|
public float uvIndex;
|
||||||
public int precipProbability; // %
|
public int precipProbability; // %
|
||||||
|
public int dewPoint; // kelvin
|
||||||
|
public float pressure; // mb
|
||||||
|
public int cloudCover; // %
|
||||||
|
public float visibility; // m
|
||||||
|
public int sunRise; // unix epoch timestamp, in seconds
|
||||||
|
public int sunSet; // unix epoch timestamp, in seconds
|
||||||
|
public int moonRise; // unix epoch timestamp, in seconds
|
||||||
|
public int moonSet; // unix epoch timestamp, in seconds
|
||||||
|
public int moonPhase; // deg
|
||||||
|
public float latitude;
|
||||||
|
public float longitude;
|
||||||
|
public int feelsLikeTemp; // kelvin
|
||||||
|
public int isCurrentLocation = -1; // 0 for false, 1 for true, -1 for unknown
|
||||||
|
public AirQuality airQuality;
|
||||||
|
|
||||||
// Forecasts from the next day onward, in chronological order, one entry per day.
|
// Forecasts from the next day onward, in chronological order, one entry per day.
|
||||||
// It should not include the current or previous days
|
// It should not include the current or previous days
|
||||||
public ArrayList<Forecast> forecasts = new ArrayList<>();
|
public ArrayList<Daily> forecasts = new ArrayList<>();
|
||||||
|
|
||||||
|
// Hourly forecasts
|
||||||
|
public ArrayList<Hourly> hourly = new ArrayList<>();
|
||||||
|
|
||||||
public WeatherSpec() {
|
public WeatherSpec() {
|
||||||
|
|
||||||
@ -66,14 +83,18 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
static final float[] beaufort = new float[] { 2, 6, 12, 20, 29, 39, 50, 62, 75, 89, 103, 118 };
|
static final float[] beaufort = new float[] { 2, 6, 12, 20, 29, 39, 50, 62, 75, 89, 103, 118 };
|
||||||
// level: 0 1 2 3 4 5 6 7 8 9 10 11 12
|
// level: 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||||
|
|
||||||
public int windSpeedAsBeaufort() {
|
public static int toBeaufort(final float speed) {
|
||||||
int l = 0;
|
int l = 0;
|
||||||
while (l < beaufort.length && beaufort[l] < this.windSpeed) {
|
while (l < beaufort.length && beaufort[l] < speed) {
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int windSpeedAsBeaufort() {
|
||||||
|
return toBeaufort(this.windSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
protected WeatherSpec(Parcel in) {
|
protected WeatherSpec(Parcel in) {
|
||||||
int version = in.readInt();
|
int version = in.readInt();
|
||||||
if (version >= 2) {
|
if (version >= 2) {
|
||||||
@ -87,12 +108,43 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
todayMinTemp = in.readInt();
|
todayMinTemp = in.readInt();
|
||||||
windSpeed = in.readFloat();
|
windSpeed = in.readFloat();
|
||||||
windDirection = in.readInt();
|
windDirection = in.readInt();
|
||||||
in.readList(forecasts, Forecast.class.getClassLoader());
|
if (version < 4) {
|
||||||
|
// Deserialize the old Forecast list and convert them to Daily
|
||||||
|
final ArrayList<Forecast> oldForecasts = new ArrayList<>();
|
||||||
|
in.readList(oldForecasts, Forecast.class.getClassLoader());
|
||||||
|
for (final Forecast forecast : oldForecasts) {
|
||||||
|
final Daily d = new Daily();
|
||||||
|
d.minTemp = forecast.minTemp;
|
||||||
|
d.maxTemp = forecast.maxTemp;
|
||||||
|
d.conditionCode = forecast.conditionCode;
|
||||||
|
d.humidity = forecast.humidity;
|
||||||
|
forecasts.add(d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in.readList(forecasts, Daily.class.getClassLoader());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (version >= 3) {
|
if (version >= 3) {
|
||||||
uvIndex = in.readFloat();
|
uvIndex = in.readFloat();
|
||||||
precipProbability = in.readInt();
|
precipProbability = in.readInt();
|
||||||
}
|
}
|
||||||
|
if (version >= 4) {
|
||||||
|
dewPoint = in.readInt();
|
||||||
|
pressure = in.readFloat();
|
||||||
|
cloudCover = in.readInt();
|
||||||
|
visibility = in.readFloat();
|
||||||
|
sunRise = in.readInt();
|
||||||
|
sunSet = in.readInt();
|
||||||
|
moonRise = in.readInt();
|
||||||
|
moonSet = in.readInt();
|
||||||
|
moonPhase = in.readInt();
|
||||||
|
latitude = in.readFloat();
|
||||||
|
longitude = in.readFloat();
|
||||||
|
feelsLikeTemp = in.readInt();
|
||||||
|
isCurrentLocation = in.readInt();
|
||||||
|
airQuality = in.readParcelable(AirQuality.class.getClassLoader());
|
||||||
|
in.readList(hourly, Hourly.class.getClassLoader());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -116,8 +168,24 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
dest.writeList(forecasts);
|
dest.writeList(forecasts);
|
||||||
dest.writeFloat(uvIndex);
|
dest.writeFloat(uvIndex);
|
||||||
dest.writeInt(precipProbability);
|
dest.writeInt(precipProbability);
|
||||||
|
dest.writeInt(dewPoint);
|
||||||
|
dest.writeFloat(pressure);
|
||||||
|
dest.writeInt(cloudCover);
|
||||||
|
dest.writeFloat(visibility);
|
||||||
|
dest.writeInt(sunRise);
|
||||||
|
dest.writeInt(sunSet);
|
||||||
|
dest.writeInt(moonRise);
|
||||||
|
dest.writeInt(moonSet);
|
||||||
|
dest.writeInt(moonPhase);
|
||||||
|
dest.writeFloat(latitude);
|
||||||
|
dest.writeFloat(longitude);
|
||||||
|
dest.writeInt(feelsLikeTemp);
|
||||||
|
dest.writeInt(isCurrentLocation);
|
||||||
|
dest.writeParcelable(airQuality, 0);
|
||||||
|
dest.writeList(hourly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated // kept for backwards compatibility with old weather apps
|
||||||
public static class Forecast implements Parcelable, Serializable {
|
public static class Forecast implements Parcelable, Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@ -167,4 +235,221 @@ public class WeatherSpec implements Parcelable, Serializable {
|
|||||||
dest.writeInt(humidity);
|
dest.writeInt(humidity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AirQuality implements Parcelable, Serializable {
|
||||||
|
public static final int VERSION = 1;
|
||||||
|
private static final long serialVersionUID = VERSION;
|
||||||
|
|
||||||
|
public static final Creator<AirQuality> CREATOR = new Creator<AirQuality>() {
|
||||||
|
@Override
|
||||||
|
public AirQuality createFromParcel(final Parcel in) {
|
||||||
|
return new AirQuality(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AirQuality[] newArray(final int size) {
|
||||||
|
return new AirQuality[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public int aqi = -1; // plume AQI
|
||||||
|
public float co = -1; // mg/m^3
|
||||||
|
public float no2 = -1; // ug/m^3
|
||||||
|
public float o3 = -1; // ug/m^3
|
||||||
|
public float pm10 = -1; // ug/m^3
|
||||||
|
public float pm25 = -1; // ug/m^3
|
||||||
|
public float so2 = -1; // ug/m^3
|
||||||
|
public int coAqi = -1;
|
||||||
|
public int no2Aqi = -1;
|
||||||
|
public int o3Aqi = -1;
|
||||||
|
public int pm10Aqi = -1;
|
||||||
|
public int pm25Aqi = -1;
|
||||||
|
public int so2Aqi = -1;
|
||||||
|
|
||||||
|
public AirQuality() {
|
||||||
|
}
|
||||||
|
|
||||||
|
AirQuality(final Parcel in) {
|
||||||
|
in.readInt(); // version
|
||||||
|
aqi = in.readInt();
|
||||||
|
co = in.readFloat();
|
||||||
|
no2 = in.readFloat();
|
||||||
|
o3 = in.readFloat();
|
||||||
|
pm10 = in.readFloat();
|
||||||
|
pm25 = in.readFloat();
|
||||||
|
so2 = in.readFloat();
|
||||||
|
coAqi = in.readInt();
|
||||||
|
no2Aqi = in.readInt();
|
||||||
|
o3Aqi = in.readInt();
|
||||||
|
pm10Aqi = in.readInt();
|
||||||
|
pm25Aqi = in.readInt();
|
||||||
|
so2Aqi = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(final Parcel dest, final int flags) {
|
||||||
|
dest.writeInt(VERSION);
|
||||||
|
dest.writeInt(aqi);
|
||||||
|
dest.writeFloat(co);
|
||||||
|
dest.writeFloat(no2);
|
||||||
|
dest.writeFloat(o3);
|
||||||
|
dest.writeFloat(pm10);
|
||||||
|
dest.writeFloat(pm25);
|
||||||
|
dest.writeFloat(so2);
|
||||||
|
dest.writeInt(coAqi);
|
||||||
|
dest.writeInt(no2Aqi);
|
||||||
|
dest.writeInt(o3Aqi);
|
||||||
|
dest.writeInt(pm10Aqi);
|
||||||
|
dest.writeInt(pm25Aqi);
|
||||||
|
dest.writeInt(so2Aqi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Daily implements Parcelable, Serializable {
|
||||||
|
public static final int VERSION = 1;
|
||||||
|
private static final long serialVersionUID = VERSION;
|
||||||
|
|
||||||
|
public static final Creator<Daily> CREATOR = new Creator<Daily>() {
|
||||||
|
@Override
|
||||||
|
public Daily createFromParcel(final Parcel in) {
|
||||||
|
return new Daily(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Daily[] newArray(final int size) {
|
||||||
|
return new Daily[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
public int minTemp; // Kelvin
|
||||||
|
public int maxTemp; // Kelvin
|
||||||
|
public int conditionCode; // OpenWeatherMap condition code
|
||||||
|
public int humidity;
|
||||||
|
public float windSpeed; // km per hour
|
||||||
|
public int windDirection; // deg
|
||||||
|
public float uvIndex;
|
||||||
|
public int precipProbability; // %
|
||||||
|
public int sunRise;
|
||||||
|
public int sunSet;
|
||||||
|
public int moonRise;
|
||||||
|
public int moonSet;
|
||||||
|
public int moonPhase;
|
||||||
|
public AirQuality airQuality;
|
||||||
|
|
||||||
|
public Daily() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Daily(final Parcel in) {
|
||||||
|
in.readInt(); // version
|
||||||
|
minTemp = in.readInt();
|
||||||
|
maxTemp = in.readInt();
|
||||||
|
conditionCode = in.readInt();
|
||||||
|
humidity = in.readInt();
|
||||||
|
windSpeed = in.readFloat();
|
||||||
|
windDirection = in.readInt();
|
||||||
|
uvIndex = in.readFloat();
|
||||||
|
precipProbability = in.readInt();
|
||||||
|
sunRise = in.readInt();
|
||||||
|
sunSet = in.readInt();
|
||||||
|
moonRise = in.readInt();
|
||||||
|
moonSet = in.readInt();
|
||||||
|
moonPhase = in.readInt();
|
||||||
|
airQuality = in.readParcelable(AirQuality.class.getClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(final Parcel dest, final int flags) {
|
||||||
|
dest.writeInt(VERSION);
|
||||||
|
dest.writeInt(minTemp);
|
||||||
|
dest.writeInt(maxTemp);
|
||||||
|
dest.writeInt(conditionCode);
|
||||||
|
dest.writeInt(humidity);
|
||||||
|
dest.writeFloat(windSpeed);
|
||||||
|
dest.writeInt(windDirection);
|
||||||
|
dest.writeFloat(uvIndex);
|
||||||
|
dest.writeInt(precipProbability);
|
||||||
|
dest.writeInt(sunRise);
|
||||||
|
dest.writeInt(sunSet);
|
||||||
|
dest.writeInt(moonRise);
|
||||||
|
dest.writeInt(moonSet);
|
||||||
|
dest.writeInt(moonPhase);
|
||||||
|
dest.writeParcelable(airQuality, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int windSpeedAsBeaufort() {
|
||||||
|
return toBeaufort(this.windSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Hourly implements Parcelable, Serializable {
|
||||||
|
public static final int VERSION = 1;
|
||||||
|
private static final long serialVersionUID = VERSION;
|
||||||
|
|
||||||
|
public static final Creator<Hourly> CREATOR = new Creator<Hourly>() {
|
||||||
|
@Override
|
||||||
|
public Hourly createFromParcel(final Parcel in) {
|
||||||
|
return new Hourly(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hourly[] newArray(final int size) {
|
||||||
|
return new Hourly[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public int timestamp; // unix epoch timestamp, in seconds
|
||||||
|
public int temp; // Kelvin
|
||||||
|
public int conditionCode; // OpenWeatherMap condition code
|
||||||
|
public int humidity;
|
||||||
|
public float windSpeed; // km per hour
|
||||||
|
public int windDirection; // deg
|
||||||
|
public float uvIndex;
|
||||||
|
public int precipProbability; // %
|
||||||
|
|
||||||
|
public Hourly() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Hourly(final Parcel in) {
|
||||||
|
in.readInt(); // version
|
||||||
|
timestamp = in.readInt();
|
||||||
|
temp = in.readInt();
|
||||||
|
conditionCode = in.readInt();
|
||||||
|
humidity = in.readInt();
|
||||||
|
windSpeed = in.readFloat();
|
||||||
|
windDirection = in.readInt();
|
||||||
|
uvIndex = in.readFloat();
|
||||||
|
precipProbability = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(final Parcel dest, final int flags) {
|
||||||
|
dest.writeInt(VERSION);
|
||||||
|
dest.writeInt(timestamp);
|
||||||
|
dest.writeInt(temp);
|
||||||
|
dest.writeInt(conditionCode);
|
||||||
|
dest.writeInt(humidity);
|
||||||
|
dest.writeFloat(windSpeed);
|
||||||
|
dest.writeInt(windDirection);
|
||||||
|
dest.writeFloat(uvIndex);
|
||||||
|
dest.writeInt(precipProbability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int windSpeedAsBeaufort() {
|
||||||
|
return toBeaufort(this.windSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ public class Huami2021Weather {
|
|||||||
windSpeed.add(new Range(0, 0));
|
windSpeed.add(new Range(0, 0));
|
||||||
|
|
||||||
for (int i = 0; i < actualDays; i++) {
|
for (int i = 0; i < actualDays; i++) {
|
||||||
final WeatherSpec.Forecast forecast = weatherSpec.forecasts.get(i);
|
final WeatherSpec.Daily forecast = weatherSpec.forecasts.get(i);
|
||||||
temperature.add(new Range(forecast.minTemp - 273, forecast.maxTemp - 273));
|
temperature.add(new Range(forecast.minTemp - 273, forecast.maxTemp - 273));
|
||||||
final String weatherCode = String.valueOf(mapToZeppOsWeatherCode(forecast.conditionCode));
|
final String weatherCode = String.valueOf(mapToZeppOsWeatherCode(forecast.conditionCode));
|
||||||
weather.add(new Range(weatherCode, weatherCode));
|
weather.add(new Range(weatherCode, weatherCode));
|
||||||
|
@ -3192,7 +3192,7 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
if (supportsConditionString) {
|
if (supportsConditionString) {
|
||||||
bytesPerDay = 5;
|
bytesPerDay = 5;
|
||||||
conditionsLength = weatherSpec.currentCondition.getBytes().length;
|
conditionsLength = weatherSpec.currentCondition.getBytes().length;
|
||||||
for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) {
|
for (WeatherSpec.Daily forecast : weatherSpec.forecasts) {
|
||||||
conditionsLength += Weather.getConditionString(forecast.conditionCode).getBytes().length;
|
conditionsLength += Weather.getConditionString(forecast.conditionCode).getBytes().length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3225,7 +3225,7 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
buf.put((byte) 0);
|
buf.put((byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) {
|
for (WeatherSpec.Daily forecast : weatherSpec.forecasts) {
|
||||||
condition = HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode);
|
condition = HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode);
|
||||||
buf.put(condition);
|
buf.put(condition);
|
||||||
buf.put(condition);
|
buf.put(condition);
|
||||||
|
@ -234,7 +234,7 @@ public class ZeppOsAlexaService extends AbstractZeppOsService {
|
|||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
baos.write(weather.forecasts.size());
|
baos.write(weather.forecasts.size());
|
||||||
for (final WeatherSpec.Forecast forecast : weather.forecasts) {
|
for (final WeatherSpec.Daily forecast : weather.forecasts) {
|
||||||
// FIXME
|
// FIXME
|
||||||
}
|
}
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
|
@ -143,7 +143,7 @@ class AppMessageHandlerTimeStylePebble extends AppMessageHandler {
|
|||||||
pairs.add(new Pair<>(messageKeys.get("WeatherCondition"), (Object) (getIconForConditionCode(weatherSpec.currentConditionCode, isNight))));
|
pairs.add(new Pair<>(messageKeys.get("WeatherCondition"), (Object) (getIconForConditionCode(weatherSpec.currentConditionCode, isNight))));
|
||||||
|
|
||||||
if (weatherSpec.forecasts.size() > 0) {
|
if (weatherSpec.forecasts.size() > 0) {
|
||||||
WeatherSpec.Forecast tomorrow = weatherSpec.forecasts.get(0);
|
WeatherSpec.Daily tomorrow = weatherSpec.forecasts.get(0);
|
||||||
pairs.add(new Pair<>(messageKeys.get("WeatherForecastCondition"), (Object) (getIconForConditionCode(tomorrow.conditionCode, isNight))));
|
pairs.add(new Pair<>(messageKeys.get("WeatherForecastCondition"), (Object) (getIconForConditionCode(tomorrow.conditionCode, isNight))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,19 +200,19 @@ class AppMessageHandlerYWeather extends AppMessageHandler {
|
|||||||
pairs.add(new Pair<>(KEY_WEATHER_WIND_SPEED, (Object) (String.format(Locale.ENGLISH, "%.0f", weatherSpec.windSpeed))));
|
pairs.add(new Pair<>(KEY_WEATHER_WIND_SPEED, (Object) (String.format(Locale.ENGLISH, "%.0f", weatherSpec.windSpeed))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_WIND_DIRECTION, (Object) (formatWindDirection(weatherSpec.windDirection))));
|
pairs.add(new Pair<>(KEY_WEATHER_WIND_DIRECTION, (Object) (formatWindDirection(weatherSpec.windDirection))));
|
||||||
if (weatherSpec.forecasts.size() > 0) {
|
if (weatherSpec.forecasts.size() > 0) {
|
||||||
WeatherSpec.Forecast day1 = weatherSpec.forecasts.get(0);
|
WeatherSpec.Daily day1 = weatherSpec.forecasts.get(0);
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D1_ICON, (Object) (getIconForConditionCode(day1.conditionCode, false))));
|
pairs.add(new Pair<>(KEY_WEATHER_D1_ICON, (Object) (getIconForConditionCode(day1.conditionCode, false))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D1_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day1.minTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D1_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day1.minTemp - 273.15))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D1_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day1.maxTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D1_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day1.maxTemp - 273.15))));
|
||||||
}
|
}
|
||||||
if (weatherSpec.forecasts.size() > 1) {
|
if (weatherSpec.forecasts.size() > 1) {
|
||||||
WeatherSpec.Forecast day2 = weatherSpec.forecasts.get(1);
|
WeatherSpec.Daily day2 = weatherSpec.forecasts.get(1);
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D2_ICON, (Object) (getIconForConditionCode(day2.conditionCode, false))));
|
pairs.add(new Pair<>(KEY_WEATHER_D2_ICON, (Object) (getIconForConditionCode(day2.conditionCode, false))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D2_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day2.minTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D2_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day2.minTemp - 273.15))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D2_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day2.maxTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D2_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day2.maxTemp - 273.15))));
|
||||||
}
|
}
|
||||||
if (weatherSpec.forecasts.size() > 2) {
|
if (weatherSpec.forecasts.size() > 2) {
|
||||||
WeatherSpec.Forecast day3 = weatherSpec.forecasts.get(2);
|
WeatherSpec.Daily day3 = weatherSpec.forecasts.get(2);
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D3_ICON, (Object) (getIconForConditionCode(day3.conditionCode, false))));
|
pairs.add(new Pair<>(KEY_WEATHER_D3_ICON, (Object) (getIconForConditionCode(day3.conditionCode, false))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D3_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day3.minTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D3_MINTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day3.minTemp - 273.15))));
|
||||||
pairs.add(new Pair<>(KEY_WEATHER_D3_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day3.maxTemp - 273.15))));
|
pairs.add(new Pair<>(KEY_WEATHER_D3_MAXTEMP, (Object) (String.format(Locale.ENGLISH, "%.0f°C", day3.maxTemp - 273.15))));
|
||||||
|
@ -1142,7 +1142,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
short tomorrowMin = 0;
|
short tomorrowMin = 0;
|
||||||
int tomorrowConditionCode = 0;
|
int tomorrowConditionCode = 0;
|
||||||
if (weatherSpec.forecasts.size() > 0) {
|
if (weatherSpec.forecasts.size() > 0) {
|
||||||
WeatherSpec.Forecast tomorrow = weatherSpec.forecasts.get(0);
|
WeatherSpec.Daily tomorrow = weatherSpec.forecasts.get(0);
|
||||||
tomorrowMax = (short) (tomorrow.maxTemp - 273);
|
tomorrowMax = (short) (tomorrow.maxTemp - 273);
|
||||||
tomorrowMin = (short) (tomorrow.minTemp - 273);
|
tomorrowMin = (short) (tomorrow.minTemp - 273);
|
||||||
tomorrowConditionCode = tomorrow.conditionCode;
|
tomorrowConditionCode = tomorrow.conditionCode;
|
||||||
|
@ -1471,7 +1471,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTimeInMillis(weatherSpec.timestamp * 1000L);
|
cal.setTimeInMillis(weatherSpec.timestamp * 1000L);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (WeatherSpec.Forecast forecast : weatherSpec.forecasts) {
|
for (WeatherSpec.Daily forecast : weatherSpec.forecasts) {
|
||||||
cal.add(Calendar.DATE, 1);
|
cal.add(Calendar.DATE, 1);
|
||||||
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
|
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
|
||||||
forecastWeekArray.put(new JSONObject()
|
forecastWeekArray.put(new JSONObject()
|
||||||
|
@ -89,7 +89,12 @@ public class ParcelableWeather2 implements Parcelable {
|
|||||||
int forecastLowTemp = forecastBundle.getInt("weather_low_temp");
|
int forecastLowTemp = forecastBundle.getInt("weather_low_temp");
|
||||||
int forecastHighTemp = forecastBundle.getInt("weather_high_temp");
|
int forecastHighTemp = forecastBundle.getInt("weather_high_temp");
|
||||||
int forecastHumidity = forecastBundle.getInt("weather_humidity_value");
|
int forecastHumidity = forecastBundle.getInt("weather_humidity_value");
|
||||||
weatherSpec.forecasts.add(new WeatherSpec.Forecast(forecastLowTemp, forecastHighTemp, forecastConditionCode, forecastHumidity));
|
WeatherSpec.Daily daily = new WeatherSpec.Daily();
|
||||||
|
daily.minTemp = forecastLowTemp;
|
||||||
|
daily.maxTemp = forecastHighTemp;
|
||||||
|
daily.conditionCode = forecastConditionCode;
|
||||||
|
daily.humidity = forecastHumidity;
|
||||||
|
weatherSpec.forecasts.add(daily);
|
||||||
try {
|
try {
|
||||||
condition.put("id", forecastConditionCode);
|
condition.put("id", forecastConditionCode);
|
||||||
condition.put("main", forecastBundle.getString("weather_condition_text"));
|
condition.put("main", forecastBundle.getString("weather_condition_text"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user