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

add local time service to PineTime, fixed standard ble format

This commit is contained in:
uli 2022-05-28 23:56:56 +02:00 committed by Gitea
parent c05734ed0f
commit 5097327234
4 changed files with 47 additions and 19 deletions

View File

@ -40,9 +40,8 @@ public class BLETypeConversions {
* @return
* @see GattCharacteristic#UUID_CHARACTERISTIC_CURRENT_TIME
*/
public static byte[] calendarToRawBytes(Calendar timestamp) {
// MiBand2:
// year,year,month,dayofmonth,hour,minute,second,dayofweek,0,0,tz
public static byte[] calendarToCurrentTime(Calendar timestamp) {
// year,year,month,dayofmonth,hour,minute,second,dayofweek,fractions256,reason
byte[] year = fromUint16(timestamp.get(Calendar.YEAR));
return new byte[] {
@ -54,9 +53,33 @@ public class BLETypeConversions {
fromUint8(timestamp.get(Calendar.MINUTE)),
fromUint8(timestamp.get(Calendar.SECOND)),
dayOfWeekToRawBytes(timestamp),
0, // fractions256 (not set)
// 0 (DST offset?) Mi2
// k (tz) Mi2
fromUint8((int) (timestamp.get(Calendar.MILLISECOND) / 1000. * 256)),
0, // reason (not set)
};
}
/**
* Converts a timestamp to the byte sequence to be sent to the local time characteristic
*
* Values are expressed in quarters of hours
* Following the BLE specification, timezone is constant over dst changes
*
* @param timestamp
* @return
* @see GattCharacteristic#UUID_CHARACTERISTIC_LOCAL_TIME
*/
public static byte[] calendarToLocalTime(Calendar timestamp) {
TimeZone timeZone = timestamp.getTimeZone();
int offsetMillisTimezone = timeZone.getRawOffset();
int utcOffsetInQuarterHours = (offsetMillisTimezone / (1000 * 60 * 15));
int offsetMillisIncludingDST = timestamp.getTimeZone().getOffset(timestamp.getTimeInMillis());
int dstOffsetMillis = offsetMillisIncludingDST - offsetMillisTimezone;
int dstOffsetInQuarterHours = (dstOffsetMillis / (1000 * 60 * 15));
return new byte[] {
fromUint8(utcOffsetInQuarterHours),
fromUint8(dstOffsetInQuarterHours),
};
}

View File

@ -47,7 +47,7 @@ public class GattCharacteristic {
public static final UUID UUID_CHARACTERISTIC_EXACT_TIME_256 = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A0C")));
public static final UUID UUID_CHARACTERISTIC_DST_OFFSET = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A0D")));
public static final UUID UUID_CHARACTERISTIC_TIME_ZONE = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A0E")));
public static final UUID UUID_CHARACTERISTIC_LOCAL_TIME_INFORMATION = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A0F")));
public static final UUID UUID_CHARACTERISTIC_LOCAL_TIME = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A0F")));
public static final UUID UUID_CHARACTERISTIC_TIME_WITH_DST = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A11")));
public static final UUID UUID_CHARACTERISTIC_TIME_ACCURACY = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A12")));
public static final UUID UUID_CHARACTERISTIC_TIME_SOURCE = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A13")));

View File

@ -404,15 +404,20 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
return weatherSpec.windSpeedAsBeaufort() + ""; // cast to string
}
public byte[] getTimeBytes(final Calendar calendar, final TimeUnit precision) {
final byte[] bytes = BLETypeConversions.shortCalendarToRawBytes(calendar);
if (precision != TimeUnit.MINUTES && precision != TimeUnit.SECONDS) {
throw new IllegalArgumentException("Unsupported precision, only MINUTES and SECONDS are supported");
public byte[] getTimeBytes(Calendar calendar, TimeUnit precision) {
if (precision == TimeUnit.MINUTES) {
final byte[] bytes = BLETypeConversions.shortCalendarToRawBytes(calendar);
//add nonstandard extension
final byte[] tail = new byte[] { 0, BLETypeConversions.mapTimeZone(calendar, BLETypeConversions.TZ_FLAG_INCLUDE_DST_IN_TZ) };
return BLETypeConversions.join(bytes, tail);
} else if (precision == TimeUnit.SECONDS) {
final byte[] bytes = BLETypeConversions.calendarToCurrentTime(calendar);
//add nonstandard extension, only one byte needed, as format is different from above
final byte[] tail = new byte[] { BLETypeConversions.mapTimeZone(calendar, BLETypeConversions.TZ_FLAG_INCLUDE_DST_IN_TZ) };
return BLETypeConversions.join(bytes, tail);
} else {
throw new IllegalArgumentException("Unsupported precision, only MINUTES and SECONDS are supported till now");
}
final byte seconds = precision == TimeUnit.SECONDS ? fromUint8(calendar.get(Calendar.SECOND)) : 0;
final byte tz = BLETypeConversions.mapTimeZone(calendar, BLETypeConversions.TZ_FLAG_INCLUDE_DST_IN_TZ);
return BLETypeConversions.join(bytes, new byte[]{seconds, tz});
}
public Calendar fromTimeBytes(byte[] bytes) {

View File

@ -316,12 +316,12 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
public void onSetTime() {
// Since this is a standard we should generalize this in Gadgetbridge (properly)
GregorianCalendar now = BLETypeConversions.createCalendar();
byte[] bytes = BLETypeConversions.calendarToRawBytes(now);
byte[] tail = new byte[]{0, BLETypeConversions.mapTimeZone(now, BLETypeConversions.TZ_FLAG_INCLUDE_DST_IN_TZ)};
byte[] all = BLETypeConversions.join(bytes, tail);
byte[] bytesCurrentTime = BLETypeConversions.calendarToCurrentTime(now);
byte[] bytesLocalTime = BLETypeConversions.calendarToLocalTime(now);
TransactionBuilder builder = new TransactionBuilder("set time");
builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_CURRENT_TIME), all);
builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_CURRENT_TIME), bytesCurrentTime);
builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_LOCAL_TIME), bytesLocalTime);
builder.queue(getQueue());
}