rpi-vsts-ci-led/pkg/led/led.go

108 lines
1.6 KiB
Go

package led
import (
"errors"
"rpi-ci-led/pkg/ws2812b"
"time"
)
type LEDSvc struct {
pin int
count int
blink map[int]chan struct{}
done chan struct{}
}
var led *LEDSvc
func Init(pin, count int) (*LEDSvc, error) {
_, err := ws2812b.Init(pin, count, 255)
if err != nil {
return nil, err
}
return &LEDSvc{
pin: pin,
count: count,
blink: make(map[int]chan struct{}),
done: make(chan struct{}),
}, nil
}
func Get() *LEDSvc {
if led == nil {
panic(errors.New("not init"))
}
return led
}
func (p *LEDSvc) Stop() {
for k := range p.blink {
p.StopBlink(k)
}
ws2812b.ClearAll()
close(p.done)
}
func (p *LEDSvc) SetColor(pos int, color uint32) error {
if pos < 0 || pos > p.count {
return errors.New("out of range")
}
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
ws2812b.WriteColor(pos, color)
return nil
}
func (p *LEDSvc) StopBlink(pos int) {
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
}
func (p *LEDSvc) SetBlink(pos int, color uint32, interval time.Duration) {
if ch, ok := p.blink[pos]; ok {
close(ch)
delete(p.blink, pos)
}
go func() {
defer func() {
ws2812b.WriteColor(pos, 0)
delete(p.blink, pos)
}()
ch := make(chan struct{})
p.blink[pos] = ch
timer := time.NewTicker(interval)
on := false
for {
select {
case <-ch:
return
case <-timer.C:
if on {
ws2812b.WriteColor(pos, 0)
} else {
ws2812b.WriteColor(pos, color)
}
on = !on
}
}
}()
}
func (p *LEDSvc) Run() {
ticker := time.NewTicker(time.Millisecond * 100)
for {
select {
case <-p.done:
return
case <-ticker.C:
}
}
}