Add local time characteristic (#4)

Co-authored-by: cybuzuma <cybuzuma@vnxs.de>
Co-committed-by: cybuzuma <cybuzuma@vnxs.de>
This commit is contained in:
cybuzuma 2022-11-21 16:51:49 +00:00 committed by Elara Musayelyan
parent 1f15572063
commit 02444f2b66

View file

@ -33,6 +33,7 @@ const (
MotionValChar = "00030002-78fc-48fe-8e23-433b3a1942d0"
FirmwareVerChar = "00002a26-0000-1000-8000-00805f9b34fb"
CurrentTimeChar = "00002a2b-0000-1000-8000-00805f9b34fb"
LocalTimeChar = "00002a0f-0000-1000-8000-00805f9b34fb"
BatteryLvlChar = "00002a19-0000-1000-8000-00805f9b34fb"
HeartRateChar = "00002a37-0000-1000-8000-00805f9b34fb"
FSTransferChar = "adaf0200-4669-6c65-5472-616e73666572"
@ -47,6 +48,7 @@ var charNames = map[string]string{
MotionValChar: "Motion Values",
FirmwareVerChar: "Firmware Version",
CurrentTimeChar: "Current Time",
LocalTimeChar: "Local Time",
BatteryLvlChar: "Battery Level",
HeartRateChar: "Heart Rate",
FSTransferChar: "Filesystem Transfer",
@ -66,6 +68,7 @@ type Device struct {
motionValChar *gatt.GattCharacteristic1
fwVersionChar *gatt.GattCharacteristic1
currentTimeChar *gatt.GattCharacteristic1
localTimeChar *gatt.GattCharacteristic1
battLevelChar *gatt.GattCharacteristic1
heartRateChar *gatt.GattCharacteristic1
fsVersionChar *gatt.GattCharacteristic1
@ -421,6 +424,8 @@ func (i *Device) resolveChars() error {
i.fwVersionChar = char
case CurrentTimeChar:
i.currentTimeChar = char
case LocalTimeChar:
i.localTimeChar = char
case BatteryLvlChar:
i.battLevelChar = char
case HeartRateChar:
@ -708,7 +713,9 @@ func (i *Device) WatchMotion(ctx context.Context) (<-chan MotionValues, error) {
return out, nil
}
// SetTime sets the watch's time using the Current Time Service
// SetTime sets the watch's
// * time using the Current Time Service's current time characteristic
// * timezone information using the CTS's local time characteristic
func (i *Device) SetTime(t time.Time) error {
if err := i.checkStatus(i.currentTimeChar, CurrentTimeChar); err != nil {
return err
@ -723,7 +730,38 @@ func (i *Device) SetTime(t time.Time) error {
binary.Write(buf, binary.LittleEndian, uint8(t.Weekday()))
binary.Write(buf, binary.LittleEndian, uint8((t.Nanosecond()/1000)/1e6*256))
binary.Write(buf, binary.LittleEndian, uint8(0b0001))
return i.currentTimeChar.WriteValue(buf.Bytes(), nil)
if err := i.currentTimeChar.WriteValue(buf.Bytes(), nil); err != nil {
return err
}
if err := i.checkStatus(i.localTimeChar, LocalTimeChar); err != nil {
// If the characteristic is unavailable,
// fail silently, as many people may be on
// older InfiniTime versions. A warning
// may be added later.
if _, ok := err.(ErrCharNotAvail); ok {
return nil
} else {
return err
}
}
_, offset := t.Zone()
dst := 0
// Local time expects two values: the timezone offset and the dst offset, both
// expressed in quarters of an hour.
// Timezone offset is to be constant over DST, with dst offset holding the offset != 0
// when DST is in effect.
// As there is no standard way in go to get the actual dst offset, we assume it to be 1h
// when DST is in effect
if t.IsDST() {
dst = 3600
offset -= 3600
}
bufTz := &bytes.Buffer{}
binary.Write(bufTz, binary.LittleEndian, uint8(offset / 3600 * 4))
binary.Write(bufTz, binary.LittleEndian, uint8(dst / 3600 * 4))
return i.localTimeChar.WriteValue(bufTz.Bytes(), nil)
}
// Notify sends a notification to InfiniTime via