-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscanner.go
85 lines (68 loc) · 1.59 KB
/
scanner.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
package tilt
import (
"context"
"log"
"time"
"github.com/JuulLabs-OSS/ble"
"github.com/JuulLabs-OSS/ble/examples/lib/dev"
"github.com/pkg/errors"
)
// Scanner for Tilt devices
type Scanner struct {
devices Devices
}
// Devices stores discovered devices
type Devices map[Colour]Tilt
// NewScanner returns a Scanner
func NewScanner() *Scanner {
return &Scanner{}
}
// Scan finds Tilt devices and times out after a duration
func (s *Scanner) Scan(timeout time.Duration) {
log.Printf("Scanning for %v", timeout)
s.devices = make(map[Colour]Tilt)
d, err := dev.NewDevice("go-tilt")
if err != nil {
log.Fatalf("Unable to initialise new device : %s", err)
}
ble.SetDefaultDevice(d)
ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), timeout))
err = ble.Scan(ctx, false, s.advHandler, advFilter)
if err != nil {
switch errors.Cause(err) {
case nil:
case context.DeadlineExceeded:
log.Printf("Finished scanning\n")
case context.Canceled:
log.Printf("Cancelled\n")
default:
log.Fatalf(err.Error())
}
}
}
func advFilter(a ble.Advertisement) bool {
return IsTilt(a.ManufacturerData())
}
func (s *Scanner) advHandler(a ble.Advertisement) {
// create iBeacon
b, err := NewIBeacon(a.ManufacturerData())
if err != nil {
log.Println(err)
return
}
// create Tilt from iBeacon
t, err := NewTilt(b)
if err != nil {
log.Println(err)
return
}
s.HandleTilt(t)
}
// HandleTilt adds a discovered Tilt to a map
func (s *Scanner) HandleTilt(t Tilt) {
s.devices[t.col] = t
}
// Tilts contains the found devices
func (s *Scanner) Tilts() Devices {
return s.devices
}