1
0
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:
José Rebelo 2022-09-18 00:48:36 +01:00
parent 31cdc58258
commit 462aec6f71
4 changed files with 54 additions and 20 deletions

View File

@ -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

View File

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

View File

@ -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");

View File

@ -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 {