forked from Elara6331/infinitime
		
	Added Navigation service (#5)
InfiniTime implements a [Navigation Service](https://github.com/InfiniTimeOrg/InfiniTime/blob/develop/doc/NavigationService.md). This pull request will add it to the go library by defining a function ```go func (i *Device) Navigation(flag string, narrative string, dist string, progress uint8) error { ... } ``` From the InfiniTime manual * `flag`: the graphic instruction as provided by [Pure Maps](https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation). A list of valid instruction icons can be found [here](https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation) * `narrative`: the instruction in words, eg. "At the roundabout take the first exit". * `dist`: a short string describing the distance to the upcoming instruction such as "50 m". * `progress`: the percent complete in a `uint8` Adding this to the `itd` daemon is straightforward ```patch diff --git a/api/types.go b/api/types.go index 281a85b..14c84de 100644 --- a/api/types.go +++ b/api/types.go @@ -22,6 +22,13 @@ type FwUpgradeData struct { Files []string } +type NavigationData struct { + Flag string + Narrative string + Dist string + Progress uint8 +} + type NotifyData struct { Title string Body string diff --git a/socket.go b/socket.go index 6fcba5c..91b37c0 100644 --- a/socket.go +++ b/socket.go @@ -204,6 +204,10 @@ func (i *ITD) Address(_ *server.Context) string { return i.dev.Address() } +func (i *ITD) Navigation(_ *server.Context, data api.NavigationData) error { + return i.dev.Navigation(data.Flag, data.Narrative, data.Dist, data.Progress) +} + func (i *ITD) Notify(_ *server.Context, data api.NotifyData) error { return i.dev.Notify(data.Title, data.Body) } ``` Co-authored-by: Yannick Ulrich <yannick.ulrich@durham.ac.uk> Reviewed-on: https://gitea.arsenm.dev/Arsen6331/infinitime/pulls/5 Co-authored-by: yannickulrich <yannick.ulrich@protonmail.com> Co-committed-by: yannickulrich <yannick.ulrich@protonmail.com>
This commit is contained in:
		| @@ -47,6 +47,7 @@ This library currently supports the following features: | |||||||
| - Battery level | - Battery level | ||||||
| - Music control | - Music control | ||||||
| - OTA firmware upgrades | - OTA firmware upgrades | ||||||
|  | - Navigation | ||||||
|  |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -52,6 +52,10 @@ var charNames = map[string]string{ | |||||||
| 	FSTransferChar:  "Filesystem Transfer", | 	FSTransferChar:  "Filesystem Transfer", | ||||||
| 	FSVersionChar:   "Filesystem Version", | 	FSVersionChar:   "Filesystem Version", | ||||||
| 	WeatherDataChar: "Weather Data", | 	WeatherDataChar: "Weather Data", | ||||||
|  | 	NavFlagsChar:    "Navigation Icon", | ||||||
|  | 	NavNarrativeChar:"Navigation Instruction", | ||||||
|  | 	NavManDistChar:  "Navigation Distance to next event", | ||||||
|  | 	NavProgressChar: "Navigation Progress", | ||||||
| } | } | ||||||
|  |  | ||||||
| type Device struct { | type Device struct { | ||||||
| @@ -67,10 +71,13 @@ type Device struct { | |||||||
| 	fsVersionChar   *gatt.GattCharacteristic1 | 	fsVersionChar   *gatt.GattCharacteristic1 | ||||||
| 	fsTransferChar  *gatt.GattCharacteristic1 | 	fsTransferChar  *gatt.GattCharacteristic1 | ||||||
| 	weatherDataChar *gatt.GattCharacteristic1 | 	weatherDataChar *gatt.GattCharacteristic1 | ||||||
|  | 	weatherdataChar *gatt.GattCharacteristic1 | ||||||
| 	notifEventCh    chan uint8 | 	notifEventCh    chan uint8 | ||||||
| 	notifEventDone  bool | 	notifEventDone  bool | ||||||
| 	Music           MusicCtrl | 	Music           MusicCtrl | ||||||
|  | 	Navigation      NavigationCtrl | ||||||
| 	DFU             DFU | 	DFU             DFU | ||||||
|  | 	navigationEv    NavigationEvent | ||||||
| } | } | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| @@ -394,6 +401,14 @@ func (i *Device) resolveChars() error { | |||||||
| 		charResolved := true | 		charResolved := true | ||||||
| 		// Set correct characteristics | 		// Set correct characteristics | ||||||
| 		switch char.Properties.UUID { | 		switch char.Properties.UUID { | ||||||
|  | 		case NavFlagsChar: | ||||||
|  | 			i.Navigation.flagsChar = char | ||||||
|  | 		case NavNarrativeChar: | ||||||
|  | 			i.Navigation.narrativeChar = char | ||||||
|  | 		case NavManDistChar: | ||||||
|  | 			i.Navigation.mandistChar = char | ||||||
|  | 		case NavProgressChar: | ||||||
|  | 			i.Navigation.progressChar = char | ||||||
| 		case NewAlertChar: | 		case NewAlertChar: | ||||||
| 			i.newAlertChar = char | 			i.newAlertChar = char | ||||||
| 		case NotifEventChar: | 		case NotifEventChar: | ||||||
| @@ -723,6 +738,7 @@ func (i *Device) Notify(title, body string) error { | |||||||
| 	) | 	) | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // These constants represent the possible call statuses selected by the user | // These constants represent the possible call statuses selected by the user | ||||||
| const ( | const ( | ||||||
| 	CallStatusDeclined uint8 = iota | 	CallStatusDeclined uint8 = iota | ||||||
|   | |||||||
							
								
								
									
										188
									
								
								navigation.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								navigation.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | 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 NavFlag string | ||||||
|  | const ( | ||||||
|  | 	NavFlagArrive                  NavFlag = "arrive" | ||||||
|  | 	NavFlagArriveLeft              NavFlag = "arrive-left" | ||||||
|  | 	NavFlagArriveRight             NavFlag = "arrive-right" | ||||||
|  | 	NavFlagArriveStraight          NavFlag = "arrive-straight" | ||||||
|  | 	NavFlagClose                   NavFlag = "close" | ||||||
|  | 	NavFlagContinue                NavFlag = "continue" | ||||||
|  | 	NavFlagContinueLeft            NavFlag = "continue-left" | ||||||
|  | 	NavFlagContinueRight           NavFlag = "continue-right" | ||||||
|  | 	NavFlagContinueSlightLeft      NavFlag = "continue-slight-left" | ||||||
|  | 	NavFlagContinueSlightRight     NavFlag = "continue-slight-right" | ||||||
|  | 	NavFlagContinueStraight        NavFlag = "continue-straight" | ||||||
|  | 	NavFlagContinueUturn           NavFlag = "continue-uturn" | ||||||
|  | 	NavFlagDepart                  NavFlag = "depart" | ||||||
|  | 	NavFlagDepartLeft              NavFlag = "depart-left" | ||||||
|  | 	NavFlagDepartRight             NavFlag = "depart-right" | ||||||
|  | 	NavFlagDepartStraight          NavFlag = "depart-straight" | ||||||
|  | 	NavFlagEndOfRoadLeft           NavFlag = "end-of-road-left" | ||||||
|  | 	NavFlagEndOfRoadRight          NavFlag = "end-of-road-right" | ||||||
|  | 	NavFlagFerry                   NavFlag = "ferry" | ||||||
|  | 	NavFlagFlag                    NavFlag = "flag" | ||||||
|  | 	NavFlagFork                    NavFlag = "fork" | ||||||
|  | 	NavFlagForkLeft                NavFlag = "fork-left" | ||||||
|  | 	NavFlagForkRight               NavFlag = "fork-right" | ||||||
|  | 	NavFlagForkSlightLeft          NavFlag = "fork-slight-left" | ||||||
|  | 	NavFlagForkSlightRight         NavFlag = "fork-slight-right" | ||||||
|  | 	NavFlagForkStraight            NavFlag = "fork-straight" | ||||||
|  | 	NavFlagInvalid                 NavFlag = "invalid" | ||||||
|  | 	NavFlagInvalidLeft             NavFlag = "invalid-left" | ||||||
|  | 	NavFlagInvalidRight            NavFlag = "invalid-right" | ||||||
|  | 	NavFlagInvalidSlightLeft       NavFlag = "invalid-slight-left" | ||||||
|  | 	NavFlagInvalidSlightRight      NavFlag = "invalid-slight-right" | ||||||
|  | 	NavFlagInvalidStraight         NavFlag = "invalid-straight" | ||||||
|  | 	NavFlagInvalidUturn            NavFlag = "invalid-uturn" | ||||||
|  | 	NavFlagMergeLeft               NavFlag = "merge-left" | ||||||
|  | 	NavFlagMergeRight              NavFlag = "merge-right" | ||||||
|  | 	NavFlagMergeSlightLeft         NavFlag = "merge-slight-left" | ||||||
|  | 	NavFlagMergeSlightRight        NavFlag = "merge-slight-right" | ||||||
|  | 	NavFlagMergeStraight           NavFlag = "merge-straight" | ||||||
|  | 	NavFlagNewNameLeft             NavFlag = "new-name-left" | ||||||
|  | 	NavFlagNewNameRight            NavFlag = "new-name-right" | ||||||
|  | 	NavFlagNewNameSharpLeft        NavFlag = "new-name-sharp-left" | ||||||
|  | 	NavFlagNewNameSharpRight       NavFlag = "new-name-sharp-right" | ||||||
|  | 	NavFlagNewNameSlightLeft       NavFlag = "new-name-slight-left" | ||||||
|  | 	NavFlagNewNameSlightRight      NavFlag = "new-name-slight-right" | ||||||
|  | 	NavFlagNewNameStraight         NavFlag = "new-name-straight" | ||||||
|  | 	NavFlagNotificationLeft        NavFlag = "notification-left" | ||||||
|  | 	NavFlagNotificationRight       NavFlag = "notification-right" | ||||||
|  | 	NavFlagNotificationSharpLeft   NavFlag = "notification-sharp-left" | ||||||
|  | 	NavFlagNotificationSharpRight  NavFlag = "notification-sharp-right" | ||||||
|  | 	NavFlagNotificationSlightLeft  NavFlag = "notification-slight-left" | ||||||
|  | 	NavFlagNotificationSlightRight NavFlag = "notification-slight-right" | ||||||
|  | 	NavFlagNotificationStraight    NavFlag = "notification-straight" | ||||||
|  | 	NavFlagOffRampLeft             NavFlag = "off-ramp-left" | ||||||
|  | 	NavFlagOffRampRight            NavFlag = "off-ramp-right" | ||||||
|  | 	NavFlagOffRampSharpLeft        NavFlag = "off-ramp-sharp-left" | ||||||
|  | 	NavFlagOffRampSharpRight       NavFlag = "off-ramp-sharp-right" | ||||||
|  | 	NavFlagOffRampSlightLeft       NavFlag = "off-ramp-slight-left" | ||||||
|  | 	NavFlagOffRampSlightRight      NavFlag = "off-ramp-slight-right" | ||||||
|  | 	NavFlagOffRampStraight         NavFlag = "off-ramp-straight" | ||||||
|  | 	NavFlagOnRampLeft              NavFlag = "on-ramp-left" | ||||||
|  | 	NavFlagOnRampRight             NavFlag = "on-ramp-right" | ||||||
|  | 	NavFlagOnRampSharpLeft         NavFlag = "on-ramp-sharp-left" | ||||||
|  | 	NavFlagOnRampSharpRight        NavFlag = "on-ramp-sharp-right" | ||||||
|  | 	NavFlagOnRampSlightLeft        NavFlag = "on-ramp-slight-left" | ||||||
|  | 	NavFlagOnRampSlightRight       NavFlag = "on-ramp-slight-right" | ||||||
|  | 	NavFlagOnRampStraight          NavFlag = "on-ramp-straight" | ||||||
|  | 	NavFlagRotary                  NavFlag = "rotary" | ||||||
|  | 	NavFlagRotaryLeft              NavFlag = "rotary-left" | ||||||
|  | 	NavFlagRotaryRight             NavFlag = "rotary-right" | ||||||
|  | 	NavFlagRotarySharpLeft         NavFlag = "rotary-sharp-left" | ||||||
|  | 	NavFlagRotarySharpRight        NavFlag = "rotary-sharp-right" | ||||||
|  | 	NavFlagRotarySlightLeft        NavFlag = "rotary-slight-left" | ||||||
|  | 	NavFlagRotarySlightRight       NavFlag = "rotary-slight-right" | ||||||
|  | 	NavFlagRotaryStraight          NavFlag = "rotary-straight" | ||||||
|  | 	NavFlagRoundabout              NavFlag = "roundabout" | ||||||
|  | 	NavFlagRoundaboutLeft          NavFlag = "roundabout-left" | ||||||
|  | 	NavFlagRoundaboutRight         NavFlag = "roundabout-right" | ||||||
|  | 	NavFlagRoundaboutSharpLeft     NavFlag = "roundabout-sharp-left" | ||||||
|  | 	NavFlagRoundaboutSharpRight    NavFlag = "roundabout-sharp-right" | ||||||
|  | 	NavFlagRoundaboutSlightLeft    NavFlag = "roundabout-slight-left" | ||||||
|  | 	NavFlagRoundaboutSlightRight   NavFlag = "roundabout-slight-right" | ||||||
|  | 	NavFlagRoundaboutStraight      NavFlag = "roundabout-straight" | ||||||
|  | 	NavFlagTurnLeft                NavFlag = "turn-left" | ||||||
|  | 	NavFlagTurnRight               NavFlag = "turn-right" | ||||||
|  | 	NavFlagTurnSharpLeft           NavFlag = "turn-sharp-left" | ||||||
|  | 	NavFlagTurnSharpRight          NavFlag = "turn-sharp-right" | ||||||
|  | 	NavFlagTurnSlightLeft          NavFlag = "turn-slight-left" | ||||||
|  | 	NavFlagTurnSlightRight         NavFlag = "turn-slight-right" | ||||||
|  | 	NavFlagTurnStright             NavFlag = "turn-stright" | ||||||
|  | 	NavFlagUpdown                  NavFlag = "updown" | ||||||
|  | 	NavFlagUturn                   NavFlag = "uturn" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type NavigationEvent struct { | ||||||
|  | 	Flag         NavFlag | ||||||
|  | 	Narrative    string | ||||||
|  | 	Dist         string | ||||||
|  | 	Progress     uint8 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	ErrNavProgress      = errors.New("progress needs to between 0 and 100") | ||||||
|  | 	ErrNavInvalidFlag   = errors.New("this flag is invalid") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Navigation sends a NavigationEvent to the watch | ||||||
|  | func (i *Device) SetNavigation(ev NavigationEvent) error { | ||||||
|  | 	if ev.Progress > 100 { | ||||||
|  | 		return ErrNavProgress | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ev.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(ev.Flag), nil); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		i.navigationEv.Flag = ev.Flag | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ev.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(ev.Narrative), nil); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		i.navigationEv.Narrative = ev.Narrative | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ev.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(ev.Dist), nil); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		i.navigationEv.Dist = ev.Dist | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ev.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, ev.Progress) | ||||||
|  | 		if err := i.Navigation.progressChar.WriteValue(buf.Bytes(), nil); err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		i.navigationEv.Progress = ev.Progress | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user