rpicontrol/internal/PinControlService/Pin.go

107 lines
2.3 KiB
Go

package PinControlService
import (
"errors"
log "github.com/sirupsen/logrus"
)
type Pin struct {
Id int
Name string
Direction PinDirection
PullConfig PinPull
InitialState *PinCommand
PinHandle HardwarePinInterface
SendPollingEvents bool
SendChangeEvents bool
}
func NewPin(config PinConfig) Pin {
p := Pin{
Direction: config.Direction,
PullConfig: config.PullConfig,
Name: config.Name,
Id: config.PinNumber,
PinHandle: NewHardwarePin(config.PinNumber),
}
if config.SendPollingEvents != nil {
p.SendPollingEvents = *config.SendPollingEvents
} else {
p.SendPollingEvents = true
}
if config.SendChangeEvents != nil {
p.SendChangeEvents = *config.SendChangeEvents
} else {
p.SendChangeEvents = true
}
p.InitialState = config.InitialState
return p
}
func (p *Pin) State() PinState {
if state := p.PinHandle.Read(); State(state) == HighState {
return StateOn
} else {
return StateOff
}
}
func (p *Pin) Command(cmd PinCommand) error {
log.Infof("send command \"%s\" for pin %s (pin no: %d)", cmd, p.Name, p.Id)
if p.Direction != Output {
return errors.New("pin is not an output")
}
if cmd == On {
p.PinHandle.High()
} else if cmd == Off {
p.PinHandle.Low()
} else if cmd == Toggle {
p.PinHandle.Toggle()
} else {
return errors.New("unknown command")
}
return nil
}
func (p *Pin) Configure() {
if p.Direction == Input {
log.Infof("configuring pin %s (pin no: %d) as Input", p.Name, p.Id)
p.PinHandle.Input()
} else if p.Direction == Output {
log.Infof("configuring pin %s (pin no: %d) as Output", p.Name, p.Id)
p.PinHandle.Output()
if p.InitialState != nil {
log.Infof("set initial state \"%s\" for pin %s (pin no: %d)", *p.InitialState, p.Name, p.Id)
_ = p.Command(*p.InitialState)
}
}
p.PinHandle.Detect(AnyEdge)
if p.PullConfig == PullUp {
p.PinHandle.PullUp()
} else if p.PullConfig == PullDown {
p.PinHandle.PullDown()
} else if p.PullConfig == PullOff {
p.PinHandle.PullOff()
} else {
log.Errorf("unknown config value \"%s\" for pull-config", p.PullConfig)
}
}
func (p *Pin) Changed() bool {
ret := p.PinHandle.EdgeDetected()
if ret {
log.Infof("pin %s (pin no: %d) changed state", p.Name, p.Id)
}
return ret
}