2022-12-16 22:27:24 +00:00
|
|
|
package PinControlService
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PinControlService struct {
|
2022-12-30 17:42:48 +00:00
|
|
|
Pins map[string]Pin
|
|
|
|
timer *time.Ticker
|
|
|
|
exit chan bool
|
2022-12-16 22:27:24 +00:00
|
|
|
OnChangeCallback PinCallback
|
2022-12-30 17:42:48 +00:00
|
|
|
OnCycleCallback PinCallback
|
2022-12-16 22:27:24 +00:00
|
|
|
}
|
|
|
|
|
2022-12-30 17:42:48 +00:00
|
|
|
func (p *PinControlService) AddPin(
|
2022-12-16 22:27:24 +00:00
|
|
|
config PinConfig) {
|
|
|
|
pin := NewPin(config)
|
|
|
|
p.Pins[pin.Name] = pin
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-12-30 17:42:48 +00:00
|
|
|
func (p *PinControlService) Command(pinName string, command PinCommand) error {
|
2022-12-16 22:27:24 +00:00
|
|
|
if pin, found := p.Pins[pinName]; found == false {
|
|
|
|
return errors.New("pin not configured")
|
|
|
|
} else {
|
|
|
|
return pin.Command(command)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-30 17:42:48 +00:00
|
|
|
func (p *PinControlService) Start() {
|
|
|
|
if err := HardwarePinOpen(); err != nil {
|
2022-12-16 22:27:24 +00:00
|
|
|
log.Fatal(err)
|
2023-01-08 10:09:25 +00:00
|
|
|
log.Exit(1)
|
2022-12-16 22:27:24 +00:00
|
|
|
}
|
|
|
|
|
2022-12-30 17:42:48 +00:00
|
|
|
for _, v := range p.Pins {
|
2022-12-16 22:27:24 +00:00
|
|
|
v.Configure()
|
|
|
|
}
|
|
|
|
go p._task()
|
|
|
|
}
|
2022-12-30 17:42:48 +00:00
|
|
|
func (p *PinControlService) Stop() {
|
2022-12-16 22:27:24 +00:00
|
|
|
p.exit <- true
|
|
|
|
}
|
|
|
|
|
2022-12-30 17:42:48 +00:00
|
|
|
func (p *PinControlService) _task() {
|
2022-12-16 22:27:24 +00:00
|
|
|
for {
|
|
|
|
select {
|
2022-12-30 17:42:48 +00:00
|
|
|
case <-p.timer.C:
|
2022-12-16 22:27:24 +00:00
|
|
|
for pinName, pin := range p.Pins {
|
2022-12-31 10:09:28 +00:00
|
|
|
//log.Debug("timer event")
|
2022-12-16 22:27:24 +00:00
|
|
|
if pin.Changed() {
|
|
|
|
log.Debugf("detected pin change for pin %s (pin no %d)", pin.Name, pin.Id)
|
|
|
|
if pin.SendChangeEvents && p.OnChangeCallback != nil {
|
|
|
|
p.OnChangeCallback(pinName, pin.State())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if pin.SendPollingEvents && p.OnCycleCallback != nil {
|
|
|
|
p.OnCycleCallback(pinName, pin.State())
|
|
|
|
}
|
|
|
|
}
|
2022-12-30 17:42:48 +00:00
|
|
|
case <-p.exit:
|
2022-12-16 22:27:24 +00:00
|
|
|
log.Debug("stop timer")
|
|
|
|
p.timer.Stop()
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPinControl(config *PinControlConfig) (*PinControlService, error) {
|
|
|
|
p := PinControlService{
|
2022-12-30 17:42:48 +00:00
|
|
|
Pins: make(map[string]Pin),
|
|
|
|
exit: make(chan bool, 1),
|
2022-12-16 22:27:24 +00:00
|
|
|
timer: time.NewTicker(time.Duration(config.PollingTimeMs) * time.Millisecond)}
|
|
|
|
|
|
|
|
for _, pinConfig := range config.GpioPins {
|
|
|
|
p.AddPin(pinConfig)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &p, nil
|
2022-12-30 17:42:48 +00:00
|
|
|
}
|