1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-28 04:46:51 +01:00

CMF Watch Pro 2: Add sunrise/sunset

This commit is contained in:
José Rebelo 2024-07-22 13:39:57 +01:00
parent 80256e9114
commit dc0b044977

View File

@ -27,6 +27,10 @@ import android.net.Uri;
import android.os.Build;
import android.widget.Toast;
import net.e175.klaus.solarpositioning.DeltaT;
import net.e175.klaus.solarpositioning.SPA;
import net.e175.klaus.solarpositioning.SunriseTransitSet;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@ -39,6 +43,7 @@ import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.UUID;
@ -618,8 +623,9 @@ public class CmfWatchProSupport extends AbstractBTLEDeviceSupport implements Cmf
// Each weather entry takes up 9 bytes
// There are 7 of those weather entries - 7*9 bytes
// Then there are 24-hour entries of temp and weather condition (2 bytes each)
// Then finally the location name as bytes - allow for 30 bytes, watch auto-scrolls
final ByteBuffer buf = ByteBuffer.allocate((7 * 9) + (24 * 2) + 30).order(ByteOrder.BIG_ENDIAN);
// Then the location name as bytes - allow for 31 bytes, watch auto-scrolls. Pad it to 32 bytes
// Then finally the sunrise / sunset pairs, for 7 days (7*8)
final ByteBuffer buf = ByteBuffer.allocate((7 * 9) + (24 * 2) + 32 + (7 * 8)).order(ByteOrder.BIG_ENDIAN);
// start with the current day's weather
buf.put(Weather.mapToCmfCondition(weatherSpec.currentConditionCode));
buf.put((byte) (weatherSpec.currentTemp - 273 + 100)); // convert Kelvin to C, add 100
@ -669,11 +675,53 @@ public class CmfWatchProSupport extends AbstractBTLEDeviceSupport implements Cmf
buf.put((byte) (Weather.mapToCmfCondition(weatherSpec.currentConditionCode))); // current condition
}
}
// place name - watch scrolls after ~10 chars
buf.put(StringUtils.truncate(weatherSpec.location, 30).getBytes(StandardCharsets.UTF_8));
// place name - watch scrolls after ~10 chars. Pad up to 32 bytes.
final byte[] locationNameBytes = nodomain.freeyourgadget.gadgetbridge.util.StringUtils.truncateToBytes(weatherSpec.location, 31);
buf.put(locationNameBytes);
buf.put(new byte[32 - locationNameBytes.length]);
// Sunrise / sunset
buf.order(ByteOrder.LITTLE_ENDIAN); // why...
final Location location = weatherSpec.getLocation() != null ? weatherSpec.getLocation() : new CurrentPosition().getLastKnownLocation();
final GregorianCalendar sunriseDate = new GregorianCalendar();
if (weatherSpec.sunRise != 0 && weatherSpec.sunSet != 0) {
buf.putInt(weatherSpec.sunRise);
buf.putInt(weatherSpec.sunSet);
} else {
putSunriseSunset(buf, location, sunriseDate);
}
for (int i = 0; i < 6; i++) {
sunriseDate.add(Calendar.DAY_OF_MONTH, 1);
if (i < weatherSpec.forecasts.size() && weatherSpec.forecasts.get(i).sunRise != 0 && weatherSpec.forecasts.get(i).sunSet != 0) {
buf.putInt(weatherSpec.forecasts.get(i).sunRise);
buf.putInt(weatherSpec.forecasts.get(i).sunSet);
} else {
putSunriseSunset(buf, location, sunriseDate);
}
}
sendCommand("send weather", CmfCommand.WEATHER_SET_1, buf.array());
}
private void putSunriseSunset(final ByteBuffer buf, final Location location, final GregorianCalendar date) {
final SunriseTransitSet sunriseTransitSet = SPA.calculateSunriseTransitSet(
date.toZonedDateTime(),
location.getLatitude(),
location.getLongitude(),
DeltaT.estimate(date.toZonedDateTime().toLocalDate())
);
if (sunriseTransitSet.getSunrise() != null && sunriseTransitSet.getSunset() != null) {
buf.putInt((int) sunriseTransitSet.getSunrise().toInstant().getEpochSecond());
buf.putInt((int) sunriseTransitSet.getSunset().toInstant().getEpochSecond());
} else {
buf.putInt(0);
buf.putInt(0);
}
}
@Override
public void onTestNewFunction() {