-
Notifications
You must be signed in to change notification settings - Fork 0
/
btconnect.go
142 lines (120 loc) · 3.19 KB
/
btconnect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package tilt
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/go-ble/ble"
"github.com/go-ble/ble/linux"
"github.com/google/logger"
)
const redUUID string = "A495BB10C5B14B44B5121370F02D74DE"
const greenUUID string = "A495BB20C5B14B44B5121370F02D74DE"
const blackUUID string = "A495BB30C5B14B44B5121370F02D74DE"
const purpleUUID string = "A495BB40C5B14B44B5121370F02D74DE"
const orangeUUID string = "A495BB50C5B14B44B5121370F02D74DE"
const blueUUID string = "A495BB60C5B14B44B5121370F02D74DE"
const yellowUUID string = "A495BB70C5B14B44B5121370F02D74DE"
const pinkUUID string = "A495BB80C5B14B44B5121370F02D74DE"
var uuidMap = map[string]string{
redUUID: "RED",
greenUUID: "GREEN",
blackUUID: "BLACK",
purpleUUID: "PURPLE",
orangeUUID: "ORANGE",
blueUUID: "BLUE",
yellowUUID: "YELLOW",
pinkUUID: "PINK",
}
type TiltDataPoint struct {
UUID string
SpecificGravity float32
Temperature float32
RSSI int
TXPower int
Address string
Color string
Timestamp time.Time
}
func (tdp *TiltDataPoint) StrVals() []string {
return []string{
fmt.Sprintf("%d", tdp.Timestamp.UnixMilli()),
tdp.Color,
tdp.UUID,
tdp.Address,
fmt.Sprintf("%1.4f", tdp.SpecificGravity),
fmt.Sprintf("%.1f", tdp.Temperature),
fmt.Sprintf("%d", tdp.RSSI),
fmt.Sprintf("%d", tdp.TXPower),
}
}
func (tdp *TiltDataPoint) ToJson() ([]byte, error) {
return json.Marshal(tdp)
}
var newBtDevice = linux.NewDevice
var setBtDevice = ble.SetDefaultDevice
var btScan = ble.Scan
var dataPointChan chan *TiltDataPoint
func Connect(ctx context.Context, tdpChan chan *TiltDataPoint) error {
logger.Info("Setting up BT connection")
if tdpChan != nil {
dataPointChan = tdpChan
} else {
return fmt.Errorf("BLE scanning requires you provide a channel to pass data back")
}
device, err := newBtDevice()
if err != nil {
return fmt.Errorf("unable to get new device: %v", err)
}
setBtDevice(device)
logger.Info("Scanning for BLE advertisements...")
return btScan(ctx, true, advHandler, advFilter)
}
func advHandler(adv ble.Advertisement) {
if dataPointChan != nil {
now := time.Now()
addr := adv.Addr().String()
rssi := adv.RSSI()
manData := adv.ManufacturerData()
uuid, devUUIDErr := decodeDeviceUUID(manData)
if devUUIDErr != nil {
logger.Errorf("%v", devUUIDErr)
}
temp, tempErr := decodeTemperature(manData)
if tempErr != nil {
logger.Errorf("%v", tempErr)
}
sg, sgErr := decodeSpecificGravity(manData)
if sgErr != nil {
logger.Errorf("%v", sgErr)
}
txPow, txErr := decodeTransmitPower(manData)
if txErr != nil {
logger.Errorf("%v", txErr)
}
color := uuidMap[uuid]
tdp := TiltDataPoint{
Timestamp: now,
Address: addr,
RSSI: rssi,
UUID: uuid,
Temperature: temp,
SpecificGravity: sg,
TXPower: txPow,
Color: color,
}
dataPointChan <- &tdp
} else {
logger.Info("Advertisement data skipped; no data channel specified!")
}
}
func advFilter(adv ble.Advertisement) bool {
uuid, err := decodeDeviceUUID(adv.ManufacturerData())
if err != nil {
return false
} else if _, ok := uuidMap[uuid]; ok {
return true
} else {
return false
}
}