mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 21:06:50 +01:00
Mi Band 7: Fix Weather
This commit is contained in:
parent
31cdc58258
commit
462aec6f71
@ -52,8 +52,7 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWeather() {
|
public boolean supportsWeather() {
|
||||||
// TODO: It's supported by the devices, but not yet implemented
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -258,4 +258,10 @@ public class Huami2021Service {
|
|||||||
public static final byte CALENDAR_CMD_CREATE_EVENT_ACK = 0x08;
|
public static final byte CALENDAR_CMD_CREATE_EVENT_ACK = 0x08;
|
||||||
public static final byte CALENDAR_CMD_DELETE_EVENT = 0x09;
|
public static final byte CALENDAR_CMD_DELETE_EVENT = 0x09;
|
||||||
public static final byte CALENDAR_CMD_DELETE_EVENT_ACK = 0x0a;
|
public static final byte CALENDAR_CMD_DELETE_EVENT_ACK = 0x0a;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Weather, for {@link Huami2021Service#CHUNKED2021_ENDPOINT_WEATHER}.
|
||||||
|
*/
|
||||||
|
public static final byte WEATHER_CMD_SET_DEFAULT_LOCATION = 0x09;
|
||||||
|
public static final byte WEATHER_CMD_DEFAULT_LOCATION_ACK = 0x0a;
|
||||||
}
|
}
|
||||||
|
@ -1049,7 +1049,7 @@ public abstract class Huami2021Support extends HuamiSupport {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
baos.write((byte) 0x09);
|
baos.write(Huami2021Service.WEATHER_CMD_SET_DEFAULT_LOCATION);
|
||||||
baos.write((byte) 0x02); // ? 2 for current, 4 for default
|
baos.write((byte) 0x02); // ? 2 for current, 4 for default
|
||||||
baos.write((byte) 0x00); // ?
|
baos.write((byte) 0x00); // ?
|
||||||
baos.write((byte) 0x00); // ?
|
baos.write((byte) 0x00); // ?
|
||||||
@ -1720,6 +1720,9 @@ public abstract class Huami2021Support extends HuamiSupport {
|
|||||||
case CHUNKED2021_ENDPOINT_ICONS:
|
case CHUNKED2021_ENDPOINT_ICONS:
|
||||||
handle2021Icons(payload);
|
handle2021Icons(payload);
|
||||||
return;
|
return;
|
||||||
|
case CHUNKED2021_ENDPOINT_WEATHER:
|
||||||
|
handle2021Weather(payload);
|
||||||
|
return;
|
||||||
case CHUNKED2021_ENDPOINT_WORKOUT:
|
case CHUNKED2021_ENDPOINT_WORKOUT:
|
||||||
handle2021Workout(payload);
|
handle2021Workout(payload);
|
||||||
return;
|
return;
|
||||||
@ -2427,6 +2430,16 @@ public abstract class Huami2021Support extends HuamiSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void handle2021Weather(final byte[] payload) {
|
||||||
|
switch (payload[0]) {
|
||||||
|
case WEATHER_CMD_DEFAULT_LOCATION_ACK:
|
||||||
|
LOG.info("Weather default location ACK, status = {}", payload[1]);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
LOG.warn("Unexpected weather byte {}", String.format("0x%02x", payload[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void sendNextQueuedIconData() {
|
private void sendNextQueuedIconData() {
|
||||||
if (queuedIconPackage == null) {
|
if (queuedIconPackage == null) {
|
||||||
LOG.error("No queued icon to send");
|
LOG.error("No queued icon to send");
|
||||||
|
@ -120,44 +120,60 @@ public class Huami2021Weather {
|
|||||||
public List<Range> windDirection = new ArrayList<>();
|
public List<Range> windDirection = new ArrayList<>();
|
||||||
public List<Range> sunRiseSet = new ArrayList<>();
|
public List<Range> sunRiseSet = new ArrayList<>();
|
||||||
public List<Range> windSpeed = new ArrayList<>();
|
public List<Range> windSpeed = new ArrayList<>();
|
||||||
public List<Object> moonRiseSet = new ArrayList<>();
|
public Object moonRiseSet = new Object();
|
||||||
public List<Object> airQualities = new ArrayList<>();
|
public List<Object> airQualities = new ArrayList<>();
|
||||||
|
|
||||||
public ForecastResponse(final WeatherSpec weatherSpec, final int days) {
|
public ForecastResponse(final WeatherSpec weatherSpec, final int days) {
|
||||||
|
final int actualDays = Math.min(weatherSpec.forecasts.size(), days - 1); // leave one slot for the first day
|
||||||
|
|
||||||
pubTime = new Date(weatherSpec.timestamp * 1000L);
|
pubTime = new Date(weatherSpec.timestamp * 1000L);
|
||||||
|
|
||||||
final Calendar calendar = GregorianCalendar.getInstance();
|
final Calendar calendar = GregorianCalendar.getInstance();
|
||||||
calendar.setTime(new Date(weatherSpec.timestamp * 1000L));
|
calendar.setTime(pubTime);
|
||||||
|
|
||||||
// TODO: We should send sunrise on the same location as the weather
|
|
||||||
final SimpleDateFormat sunRiseSetSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
|
|
||||||
final Location lastKnownLocation = new CurrentPosition().getLastKnownLocation();
|
final Location lastKnownLocation = new CurrentPosition().getLastKnownLocation();
|
||||||
final GregorianCalendar sunriseDate = new GregorianCalendar();
|
final GregorianCalendar sunriseDate = new GregorianCalendar();
|
||||||
sunriseDate.setTime(calendar.getTime());
|
sunriseDate.setTime(calendar.getTime());
|
||||||
|
|
||||||
for (int i = 0; i < Math.min(weatherSpec.forecasts.size(), days); i++) {
|
// First one is for the current day
|
||||||
|
temperature.add(new Range(weatherSpec.todayMinTemp - 273, weatherSpec.todayMaxTemp - 273));
|
||||||
|
final String currentWeatherCode = String.valueOf(HuamiWeatherConditions.mapToAmazfitBipWeatherCode(weatherSpec.currentConditionCode) & 0xff);
|
||||||
|
weather.add(new Range(currentWeatherCode, currentWeatherCode));
|
||||||
|
sunRiseSet.add(getSunriseSunset(sunriseDate, lastKnownLocation));
|
||||||
|
sunriseDate.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
windDirection.add(new Range(0, 0));
|
||||||
|
windSpeed.add(new Range(0, 0));
|
||||||
|
|
||||||
|
for (int i = 0; i < actualDays; i++) {
|
||||||
final WeatherSpec.Forecast forecast = weatherSpec.forecasts.get(i);
|
final WeatherSpec.Forecast 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(HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode) & 0xff); // is it?
|
final String weatherCode = String.valueOf(HuamiWeatherConditions.mapToAmazfitBipWeatherCode(forecast.conditionCode) & 0xff);
|
||||||
weather.add(new Range(weatherCode, weatherCode));
|
weather.add(new Range(weatherCode, weatherCode));
|
||||||
|
|
||||||
final GregorianCalendar[] sunriseTransitSet = SPA.calculateSunriseTransitSet(
|
sunRiseSet.add(getSunriseSunset(sunriseDate, lastKnownLocation));
|
||||||
sunriseDate,
|
|
||||||
lastKnownLocation.getLatitude(),
|
|
||||||
lastKnownLocation.getLongitude(),
|
|
||||||
DeltaT.estimate(sunriseDate)
|
|
||||||
);
|
|
||||||
|
|
||||||
final String from = sunRiseSetSdf.format(sunriseTransitSet[0].getTime());
|
|
||||||
final String to = sunRiseSetSdf.format(sunriseTransitSet[2].getTime());
|
|
||||||
sunRiseSet.add(new Range(from, to));
|
|
||||||
|
|
||||||
sunriseDate.add(Calendar.DAY_OF_MONTH, 1);
|
sunriseDate.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
|
||||||
windDirection.add(new Range(0, 0));
|
windDirection.add(new Range(0, 0));
|
||||||
windSpeed.add(new Range(0, 0));
|
windSpeed.add(new Range(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Range getSunriseSunset(final GregorianCalendar date, final Location location) {
|
||||||
|
// TODO: We should send sunrise on the same location as the weather
|
||||||
|
final SimpleDateFormat sunRiseSetSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
|
||||||
|
|
||||||
|
final GregorianCalendar[] sunriseTransitSet = SPA.calculateSunriseTransitSet(
|
||||||
|
date,
|
||||||
|
location.getLatitude(),
|
||||||
|
location.getLongitude(),
|
||||||
|
DeltaT.estimate(date)
|
||||||
|
);
|
||||||
|
|
||||||
|
final String from = sunRiseSetSdf.format(sunriseTransitSet[0].getTime());
|
||||||
|
final String to = sunRiseSetSdf.format(sunriseTransitSet[2].getTime());
|
||||||
|
|
||||||
|
return new Range(from, to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Range {
|
private static class Range {
|
||||||
|
Loading…
Reference in New Issue
Block a user