package PinControlService import ( "errors" log "github.com/sirupsen/logrus" "time" ) type PinControlService struct { Pins map[string]Pin timer *time.Ticker exit chan bool OnChangeCallback PinCallback OnCycleCallback PinCallback } func (p *PinControlService) AddPin( config PinConfig) { pin := NewPin(config) p.Pins[pin.Name] = pin } func (p *PinControlService) Command(pinName string, command PinCommand) error { if pin, found := p.Pins[pinName]; found == false { return errors.New("pin not configured") } else { return pin.Command(command) } } func (p *PinControlService) Start() { if err := HardwarePinOpen(); err != nil { log.Fatal(err) log.Exit(1) } for _, v := range p.Pins { v.Configure() } go p._task() } func (p *PinControlService) Stop() { p.exit <- true } func (p *PinControlService) _task() { for { select { case <-p.timer.C: for pinName, pin := range p.Pins { //log.Debug("timer event") 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()) } } case <-p.exit: log.Debug("stop timer") p.timer.Stop() return } } } func NewPinControl(config *PinControlConfig) (*PinControlService, error) { p := PinControlService{ Pins: make(map[string]Pin), exit: make(chan bool, 1), timer: time.NewTicker(time.Duration(config.PollingTimeMs) * time.Millisecond)} for _, pinConfig := range config.GpioPins { p.AddPin(pinConfig) } return &p, nil }