From e10697448ca5f420e04463d443ce07cbffa5d34a Mon Sep 17 00:00:00 2001 From: uli Date: Sun, 29 May 2022 23:41:19 +0200 Subject: [PATCH 1/4] added local time characteristic --- infinitime.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/infinitime.go b/infinitime.go index d48e902..d0edb1d 100644 --- a/infinitime.go +++ b/infinitime.go @@ -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", @@ -62,6 +64,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 @@ -406,6 +409,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: @@ -711,6 +716,23 @@ func (i *Device) SetTime(t time.Time) error { return i.currentTimeChar.WriteValue(buf.Bytes(), nil) } +// SetTimezone sets the watch's timezone information using the Local Time Service +func (i *Device) SetTimezone(t time.Time) error { + if err := i.checkStatus(i.localTimeChar, LocalTimeChar); err != nil { + return err + } + _, offset := t.Zone() + dst := 0 + if t.IsDST() { + dst = 3600 + offset = offset - 3600 + } + buf := &bytes.Buffer{} + binary.Write(buf, binary.LittleEndian, uint8(offset / 3600 * 4)) + binary.Write(buf, binary.LittleEndian, uint8(dst / 3600 * 4)) + return i.localTimeChar.WriteValue(buf.Bytes(), nil) +} + // Notify sends a notification to InfiniTime via // the Alert Notification Service (ANS) func (i *Device) Notify(title, body string) error { -- 2.40.1 From ee06b342819bb82443e633467c528189acf8245c Mon Sep 17 00:00:00 2001 From: uli Date: Mon, 30 May 2022 15:37:32 +0200 Subject: [PATCH 2/4] nicer code --- infinitime.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infinitime.go b/infinitime.go index d0edb1d..d92b189 100644 --- a/infinitime.go +++ b/infinitime.go @@ -725,7 +725,7 @@ func (i *Device) SetTimezone(t time.Time) error { dst := 0 if t.IsDST() { dst = 3600 - offset = offset - 3600 + offset -= 3600 } buf := &bytes.Buffer{} binary.Write(buf, binary.LittleEndian, uint8(offset / 3600 * 4)) -- 2.40.1 From 49cde2b3c2a3958be164167ab304d16f60a772a0 Mon Sep 17 00:00:00 2001 From: uli Date: Mon, 30 May 2022 22:34:03 +0200 Subject: [PATCH 3/4] moved SetTimezone into SetTime to keep values consistent --- infinitime.go | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/infinitime.go b/infinitime.go index d92b189..e07f831 100644 --- a/infinitime.go +++ b/infinitime.go @@ -698,7 +698,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 @@ -713,24 +715,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) -} - -// SetTimezone sets the watch's timezone information using the Local Time Service -func (i *Device) SetTimezone(t time.Time) error { - if err := i.checkStatus(i.localTimeChar, LocalTimeChar); err != nil { + if err := i.currentTimeChar.WriteValue(buf.Bytes(), nil); err != nil { return err } + + if err := i.checkStatus(i.localTimeChar, LocalTimeChar); err != nil { + // this characteristic might not be there in older versions of infinitime + // so we fail silently in this case. + _, notAvailable := err.(ErrCharNotAvail) + if notAvailable { + log.Warn().Msg("No Local Time Characteristic detected. Old Version of Infinitime (pre 1.10.0)?") + 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 } - buf := &bytes.Buffer{} - binary.Write(buf, binary.LittleEndian, uint8(offset / 3600 * 4)) - binary.Write(buf, binary.LittleEndian, uint8(dst / 3600 * 4)) - return i.localTimeChar.WriteValue(buf.Bytes(), nil) + 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 -- 2.40.1 From f56be08106bc5976137eb194570f1b839c1faa25 Mon Sep 17 00:00:00 2001 From: uli Date: Tue, 31 May 2022 12:00:38 +0200 Subject: [PATCH 4/4] removed warning --- infinitime.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/infinitime.go b/infinitime.go index e07f831..d3631b4 100644 --- a/infinitime.go +++ b/infinitime.go @@ -720,11 +720,11 @@ func (i *Device) SetTime(t time.Time) error { } if err := i.checkStatus(i.localTimeChar, LocalTimeChar); err != nil { - // this characteristic might not be there in older versions of infinitime - // so we fail silently in this case. - _, notAvailable := err.(ErrCharNotAvail) - if notAvailable { - log.Warn().Msg("No Local Time Characteristic detected. Old Version of Infinitime (pre 1.10.0)?") + // 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 -- 2.40.1