Added Navigation service #5

Merged
Elara6331 merged 9 commits from yannickulrich/infinitime:navigation-service into master 2022-11-03 19:09:07 +00:00
2 changed files with 146 additions and 126 deletions
Showing only changes of commit e00a4fce70 - Show all commits

View File

@ -38,10 +38,6 @@ const (
FSTransferChar = "adaf0200-4669-6c65-5472-616e73666572"
FSVersionChar = "adaf0100-4669-6c65-5472-616e73666572"
WeatherDataChar = "00040001-78fc-48fe-8e23-433b3a1942d0"
NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0"
NavNarrativeChar= "00010002-78fc-48fe-8e23-433b3a1942d0"
NavManDistChar = "00010003-78fc-48fe-8e23-433b3a1942d0"
NavProgressChar = "00010004-78fc-48fe-8e23-433b3a1942d0"
)
var charNames = map[string]string{
@ -62,54 +58,8 @@ var charNames = map[string]string{
NavProgressChar: "Navigation Progress",
}
var NavFlagNames = []string{
"arrive", "arrive-left", "arrive-right", "arrive-straight",
"close",
"continue", "continue-left", "continue-right", "continue-slight-left",
"continue-slight-right", "continue-straight", "continue-uturn",
"depart", "depart-left", "depart-right", "depart-straight",
"end-of-road-left", "end-of-road-right",
"ferry", "flag",
"fork", "fork-left", "fork-right", "fork-straight",
"fork-slight-left", "fork-slight-right",
"invalid", "invalid-left", "invalid-right",
"invalid-slight-left", "invalid-slight-right",
"invalid-straight", "invalid-uturn",
"merge-left", "merge-right", "merge-slight-left",
"merge-slight-right", "merge-straight",
"new-name-left", "new-name-right", "new-name-sharp-left", "new-name-sharp-right",
"new-name-slight-left", "new-name-slight-right", "new-name-straight",
"notification-left", "notification-right",
"notification-sharp-left", "notification-sharp-right",
"notification-slight-left", "notification-slight-right",
"notification-straight",
"off-ramp-left", "off-ramp-right", "off-ramp-sharp-left", "off-ramp-sharp-right",
"off-ramp-slight-left", "off-ramp-slight-right", "off-ramp-straight",
"on-ramp-left", "on-ramp-right", "on-ramp-sharp-left", "on-ramp-sharp-right",
"on-ramp-slight-left", "on-ramp-slight-right", "on-ramp-straight",
"rotary", "rotary-left", "rotary-right", "rotary-sharp-left", "rotary-sharp-right",
"rotary-slight-left", "rotary-slight-right", "rotary-straight",
"roundabout", "roundabout-left", "roundabout-right",
"roundabout-sharp-left", "roundabout-sharp-right",
"roundabout-slight-left", "roundabout-slight-right", "roundabout-straight",
"turn-left", "turn-right", "turn-sharp-left", "turn-sharp-right",
"turn-slight-left", "turn-slight-right", "turn-stright",
"updown", "uturn",
}
type NavigationEvent struct {
flag string
narrative string
dist string
progress uint8
}
type Device struct {
device *device.Device1
navflagsChar *gatt.GattCharacteristic1
navnarrativeChar*gatt.GattCharacteristic1
navmandistChar *gatt.GattCharacteristic1
navprogressChar *gatt.GattCharacteristic1
newAlertChar *gatt.GattCharacteristic1
notifEventChar *gatt.GattCharacteristic1
stepCountChar *gatt.GattCharacteristic1
yannickulrich marked this conversation as resolved Outdated

I think it would be better if these were individual constants rather than a slice. That way, they could have their own type and the compiler can guarantee that they're valid instead of needing a separate function. Since that will add quite a bit of code, I think the navigation service can be moved into a separate file.

I think it would be better if these were individual constants rather than a slice. That way, they could have their own type and the compiler can guarantee that they're valid instead of needing a separate function. Since that will add quite a bit of code, I think the navigation service can be moved into a separate file.

Maybe something like

type NavFlag string

const (
    NavFlagArrive     NavFlag = "arrive"
    NavFlagArriveLeft NavFlag = "arrive-left"
    // ...
)

Then, the NavigationEvent can take a NavFlag instead of string.

Maybe something like ```go type NavFlag string const ( NavFlagArrive NavFlag = "arrive" NavFlagArriveLeft NavFlag = "arrive-left" // ... ) ``` Then, the `NavigationEvent` can take a `NavFlag` instead of `string`.

Taken care of in d46f545

Taken care of in d46f545
@ -121,9 +71,11 @@ type Device struct {
fsVersionChar *gatt.GattCharacteristic1
fsTransferChar *gatt.GattCharacteristic1
weatherDataChar *gatt.GattCharacteristic1
weatherdataChar *gatt.GattCharacteristic1
notifEventCh chan uint8
notifEventDone bool
Music MusicCtrl
Navigation NavigationCtrl
DFU DFU
navigationEv NavigationEvent
}
@ -134,8 +86,6 @@ var (
ErrNotConnected = errors.New("not connected")
ErrNoTimelineHeader = errors.New("events must contain the timeline header")
ErrPairTimeout = errors.New("reached timeout while pairing")
ErrNavProgress = errors.New("progress needs to between 0 and 100")
ErrNavInvalidFlag = errors.New("this flag is invalid")
)
type ErrCharNotAvail struct {
@ -452,13 +402,13 @@ func (i *Device) resolveChars() error {
// Set correct characteristics
switch char.Properties.UUID {
case NavFlagsChar:
i.navflagsChar = char
i.Navigation.flagsChar = char
case NavNarrativeChar:
i.navnarrativeChar = char
i.Navigation.narrativeChar = char
case NavManDistChar:
i.navmandistChar = char
i.Navigation.mandistChar = char
case NavProgressChar:
i.navprogressChar = char
i.Navigation.progressChar = char
case NewAlertChar:
i.newAlertChar = char
case NotifEventChar:
@ -788,76 +738,6 @@ func (i *Device) Notify(title, body string) error {
)
}
func CheckValidNavFlag(flag string) error {
for _, v := range NavFlagNames {
if v == flag {
return nil
}
}
return ErrNavInvalidFlag
}
// Navigation sends a NavigationEvent to the watch
func (i *Device) Navigation(flag string, narrative string, dist string, progress uint8) error {
if progress > 100 {
return ErrNavProgress
}
if err := CheckValidNavFlag(flag); err != nil {
return err
}
if flag != i.navigationEv.flag {
log.Debug().Str("func", "Navigation").
Msg("Sending flag")
if err := i.checkStatus(i.navflagsChar, NavFlagsChar); err != nil {
return err
}
if err := i.navflagsChar.WriteValue([]byte(flag), nil); err != nil {
return err
}
i.navigationEv.flag = flag
}
if narrative != i.navigationEv.narrative {
log.Debug().Str("func", "Navigation").
Msg("Sending narrative")
if err := i.checkStatus(i.navnarrativeChar, NavNarrativeChar); err != nil {
return err
}
if err := i.navnarrativeChar.WriteValue([]byte(narrative), nil); err != nil {
return err
}
i.navigationEv.narrative = narrative
}
if dist != i.navigationEv.dist {
log.Debug().Str("func", "Navigation").
Msg("Sending mandist")
if err := i.checkStatus(i.navmandistChar, NavManDistChar); err != nil {
return err
}
if err := i.navmandistChar.WriteValue([]byte(dist), nil); err != nil {
return err
}
i.navigationEv.dist = dist
}
if progress != i.navigationEv.progress {
log.Debug().Str("func", "Navigation").
Msg("Sending progress")
if err := i.checkStatus(i.navprogressChar, NavProgressChar); err != nil {
return err
}
buf := &bytes.Buffer{}
binary.Write(buf, binary.LittleEndian, progress)
if err := i.navprogressChar.WriteValue(buf.Bytes(), nil); err != nil {
return err
}
i.navigationEv.progress = progress
}
return nil
}
// These constants represent the possible call statuses selected by the user
const (

140
navigation.go Normal file
View File

@ -0,0 +1,140 @@
package infinitime
import (
"bytes"
"encoding/binary"
"errors"
"github.com/muka/go-bluetooth/bluez/profile/gatt"
)
const (
NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0"
NavNarrativeChar= "00010002-78fc-48fe-8e23-433b3a1942d0"
NavManDistChar = "00010003-78fc-48fe-8e23-433b3a1942d0"
NavProgressChar = "00010004-78fc-48fe-8e23-433b3a1942d0"
)
type NavigationCtrl struct {
flagsChar *gatt.GattCharacteristic1
narrativeChar*gatt.GattCharacteristic1
mandistChar *gatt.GattCharacteristic1
progressChar *gatt.GattCharacteristic1
}
type NavigationEvent struct {
flag string
narrative string
dist string
progress uint8
}
var (
ErrNavProgress = errors.New("progress needs to between 0 and 100")
ErrNavInvalidFlag = errors.New("this flag is invalid")
)
var NavFlagNames = []string{
"arrive", "arrive-left", "arrive-right", "arrive-straight",
"close",
"continue", "continue-left", "continue-right", "continue-slight-left",
"continue-slight-right", "continue-straight", "continue-uturn",
"depart", "depart-left", "depart-right", "depart-straight",
"end-of-road-left", "end-of-road-right",
"ferry", "flag",
"fork", "fork-left", "fork-right", "fork-straight",
"fork-slight-left", "fork-slight-right",
"invalid", "invalid-left", "invalid-right",
"invalid-slight-left", "invalid-slight-right",
"invalid-straight", "invalid-uturn",
"merge-left", "merge-right", "merge-slight-left",
"merge-slight-right", "merge-straight",
"new-name-left", "new-name-right", "new-name-sharp-left", "new-name-sharp-right",
"new-name-slight-left", "new-name-slight-right", "new-name-straight",
"notification-left", "notification-right",
"notification-sharp-left", "notification-sharp-right",
"notification-slight-left", "notification-slight-right",
"notification-straight",
"off-ramp-left", "off-ramp-right", "off-ramp-sharp-left", "off-ramp-sharp-right",
"off-ramp-slight-left", "off-ramp-slight-right", "off-ramp-straight",
"on-ramp-left", "on-ramp-right", "on-ramp-sharp-left", "on-ramp-sharp-right",
"on-ramp-slight-left", "on-ramp-slight-right", "on-ramp-straight",
"rotary", "rotary-left", "rotary-right", "rotary-sharp-left", "rotary-sharp-right",
"rotary-slight-left", "rotary-slight-right", "rotary-straight",
"roundabout", "roundabout-left", "roundabout-right",
"roundabout-sharp-left", "roundabout-sharp-right",
"roundabout-slight-left", "roundabout-slight-right", "roundabout-straight",
"turn-left", "turn-right", "turn-sharp-left", "turn-sharp-right",
"turn-slight-left", "turn-slight-right", "turn-stright",
"updown", "uturn",
}
func CheckValidNavFlag(flag string) error {
for _, v := range NavFlagNames {
if v == flag {
return nil
}
}
return ErrNavInvalidFlag
}
// Navigation sends a NavigationEvent to the watch
func (i *Device) SetNavigation(flag string, narrative string, dist string, progress uint8) error {
if progress > 100 {
return ErrNavProgress
}
if err := CheckValidNavFlag(flag); err != nil {
return err
}
if flag != i.navigationEv.flag {
log.Debug().Str("func", "Navigation").
Msg("Sending flag")
if err := i.checkStatus(i.Navigation.flagsChar, NavFlagsChar); err != nil {
return err
}
if err := i.Navigation.flagsChar.WriteValue([]byte(flag), nil); err != nil {
return err
}
i.navigationEv.flag = flag
}
if narrative != i.navigationEv.narrative {
log.Debug().Str("func", "Navigation").
Msg("Sending narrative")
if err := i.checkStatus(i.Navigation.narrativeChar, NavNarrativeChar); err != nil {
return err
}
if err := i.Navigation.narrativeChar.WriteValue([]byte(narrative), nil); err != nil {
return err
}
i.navigationEv.narrative = narrative
}
if dist != i.navigationEv.dist {
log.Debug().Str("func", "Navigation").
Msg("Sending mandist")
if err := i.checkStatus(i.Navigation.mandistChar, NavManDistChar); err != nil {
return err
}
if err := i.Navigation.mandistChar.WriteValue([]byte(dist), nil); err != nil {
return err
}
i.navigationEv.dist = dist
}
if progress != i.navigationEv.progress {
log.Debug().Str("func", "Navigation").
Msg("Sending progress")
if err := i.checkStatus(i.Navigation.progressChar, NavProgressChar); err != nil {
return err
}
buf := &bytes.Buffer{}
binary.Write(buf, binary.LittleEndian, progress)
if err := i.Navigation.progressChar.WriteValue(buf.Bytes(), nil); err != nil {
return err
}
i.navigationEv.progress = progress
}
return nil
}