Add weather service

This commit is contained in:
2021-12-12 12:43:43 -08:00
parent 522c10a9c0
commit a2ff29ce84
4 changed files with 237 additions and 4 deletions

View File

@@ -4,9 +4,11 @@ import (
"bytes"
"encoding/binary"
"errors"
"reflect"
"strings"
"time"
"github.com/fxamacker/cbor/v2"
bt "github.com/muka/go-bluetooth/api"
"github.com/muka/go-bluetooth/bluez/profile/adapter"
"github.com/muka/go-bluetooth/bluez/profile/device"
@@ -27,6 +29,7 @@ const (
HeartRateChar = "00002a37-0000-1000-8000-00805f9b34fb"
FSTransferChar = "adaf0200-4669-6c65-5472-616e73666572"
FSVersionChar = "adaf0100-4669-6c65-5472-616e73666572"
WeatherDataChar = "00040001-78fc-48fe-8e23-433b3a1942d0"
)
type Device struct {
@@ -42,6 +45,7 @@ type Device struct {
heartRateChar *gatt.GattCharacteristic1
fsVersionChar *gatt.GattCharacteristic1
fsTransferChar *gatt.GattCharacteristic1
weatherDataChar *gatt.GattCharacteristic1
notifEventCh chan uint8
notifEventDone bool
onReconnect func()
@@ -50,10 +54,11 @@ type Device struct {
}
var (
ErrNoDevices = errors.New("no InfiniTime devices found")
ErrNotFound = errors.New("could not find any advertising InfiniTime devices")
ErrNotConnected = errors.New("not connected")
ErrCharNotAvail = errors.New("required characteristic is not available")
ErrNoDevices = errors.New("no InfiniTime devices found")
ErrNotFound = errors.New("could not find any advertising InfiniTime devices")
ErrNotConnected = errors.New("not connected")
ErrCharNotAvail = errors.New("required characteristic is not available")
ErrNoTimelineHeader = errors.New("events must contain the timeline header")
)
type Options struct {
@@ -333,6 +338,8 @@ func (i *Device) resolveChars() error {
i.fsTransferChar = char
case FSVersionChar:
i.fsVersionChar = char
case WeatherDataChar:
i.weatherDataChar = char
}
}
return nil
@@ -685,6 +692,32 @@ func (i *Device) FS() (*blefs.FS, error) {
return blefs.New(i.fsTransferChar)
}
// AddWeatherEvent adds one of the event structs from
// the weather package to the timeline. Input must be
// a struct containing TimelineHeader.
func (i *Device) AddWeatherEvent(event interface{}) error {
if err := i.checkStatus(i.weatherDataChar); err != nil {
return err
}
// Get type of input
inputType := reflect.TypeOf(event)
// Check if input contains TimelineHeader
_, hdrExists := inputType.FieldByName("TimelineHeader")
// If header does not exist or input is not struct
if !hdrExists || inputType.Kind() != reflect.Struct {
return ErrNoTimelineHeader
}
// Encode event as CBOR
data, err := cbor.Marshal(event)
if err != nil {
return err
}
// Write data to weather data characteristic
return i.weatherDataChar.WriteValue(data, nil)
}
func (i *Device) checkStatus(char *gatt.GattCharacteristic1) error {
if !i.device.Properties.Connected {
return ErrNotConnected