-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathled.go
130 lines (108 loc) · 3.7 KB
/
led.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
// Package blink provides an interface to ThingM blink(1) USB RGB LEDs
package blink
import (
"errors"
"fmt"
"time"
)
const (
// VendorNumber is the USB vendor identifier as defined in github.com/todbot/blink1
// https://github.com/todbot/blink1/blob/3c51231d302d7676c50f28debaf82adc5bfa9460/commandline/blink1-lib.h#L30
VendorNumber = 0x27B8
// ProductNumber is the USB device identifier as defined in github.com/todbot/blink1
// https://github.com/todbot/blink1/blob/3c51231d302d7676c50f28debaf82adc5bfa9460/commandline/blink1-lib.h#L31
ProductNumber = 0x01ED
)
// ErrNoDevice is the error that New() returns if no connected blink(1) device was found.
var ErrNoDevice = errors.New("could not find blink1 device")
// LED represents a locally connected blink(1) USB device.
type LED struct {
*usbDevice
ID byte // ID signals which LED to address: 0=all, 1=led#1, 2=led#2, etc. (mk2 only)
}
// New connects to a locally connected blink(1) USB device.
// The caller must call Close when it is done with this LED.
// The function returns a NoDeviceErr if no blink(1) device can be found
// or another error if the device could not be opened.
//
// Multiple connected devices are not yet supported and the library will just
// pick one of them to talk to.
func New() (*LED, error) {
l := LED{}
found := false
var di usbDeviceInfo
for di = range usbDevices() {
if di.vendorID == VendorNumber && di.productID == ProductNumber {
found = true
break
}
}
if !found {
return nil, ErrNoDevice
}
var err error
l.usbDevice, err = di.open()
if err != nil {
return nil, fmt.Errorf("could not open blink1 device %+v: %s", l.usbDevice.info, err)
}
return &l, nil
}
// Close implements io.Closer by closing to the connection to the USB device.
// The function is idempotent and can be called on already closed or never
// opened devices.
func (l *LED) Close() error {
if l != nil && l.usbDevice != nil {
l.close()
}
return nil
}
// FadeOutClose can be used to disable all lights on the blink(1) device and then
// close this LED. The optional fadeDuration argument can be used to let
// the LED fade out smoothly. If it is omitted a default value if 1s is assumed.
// Examples:
// defer l.FadeOutClose()
// defer l.FadeOutClose(500 * time.Millisecond)
func (l *LED) FadeOutClose(fadeDuration ...time.Duration) error {
if l == nil {
return nil
}
if len(fadeDuration) > 0 {
l.FadeRGB(0, 0, 0, fadeDuration[0])
} else {
l.FadeRGB(0, 0, 0, 1*time.Second)
}
return l.Close()
}
// SetRGB is a handy shortcut to LED.SetRGB(Color{r, g, b})
func (l *LED) SetRGB(r, g, b byte) error {
return l.Set(Color{r, g, b})
}
// Set lights up the blink(1) with the specified color immediately.
func (l *LED) Set(c Color) error {
_, err := l.write(&setRGBCommand{c})
return err
}
// FadeRGB is a handy shortcut to LED.Fade(Color{r, g, b}, d)
func (l *LED) FadeRGB(r, g, b byte, d time.Duration) error {
return l.Fade(Color{r, g, b}, d)
}
// Fade lights up the blink(1) with the specified RGB color, fading to that color over a specified duration.
func (l *LED) Fade(c Color, d time.Duration) error {
_, err := l.write(&fadeRGBCommand{Color: c, duration: d, n: l.ID})
return err
}
// ReadRGB is deprecated and will be removed in v2. Use LED.Read() instead.
// ReadRGB reads the currently active color of the blink(1) device.
// Will return meaningful results for mk2 devices only.
func (l *LED) ReadRGB() (Color, error) {
return l.Read()
}
// Read reads the currently active color of the blink(1) device.
// Will return meaningful results for mk2 devices only.
func (l *LED) Read() (Color, error) {
buf, err := l.read(&readRGBCommand{})
if err != nil {
return Color{}, err
}
return Color{R: buf[2], G: buf[3], B: buf[4]}, nil
}