63 lines
1.1 KiB
Go
63 lines
1.1 KiB
Go
//go:build linux
|
|
|
|
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/evcc-io/evcc/util"
|
|
"github.com/stianeikeland/go-rpio/v4"
|
|
)
|
|
|
|
func init() {
|
|
registry.AddCtx("gpio", NewGpioPluginFromConfig)
|
|
}
|
|
|
|
type gpio struct {
|
|
mu sync.Mutex
|
|
pin rpio.Pin
|
|
}
|
|
|
|
// NewGpioPluginFromConfig creates a GPIO provider
|
|
func NewGpioPluginFromConfig(ctx context.Context, other map[string]any) (Plugin, error) {
|
|
var cc struct {
|
|
Pin int
|
|
}
|
|
|
|
if err := util.DecodeOther(other, &cc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p := &gpio{
|
|
pin: rpio.Pin(cc.Pin),
|
|
}
|
|
|
|
// initialize GPIO and set pins to input
|
|
if err := rpio.Open(); err != nil {
|
|
return nil, fmt.Errorf("failed to open GPIO: %w", err)
|
|
}
|
|
defer rpio.Close()
|
|
|
|
p.pin.Input()
|
|
|
|
return p, nil
|
|
}
|
|
|
|
var _ BoolGetter = (*gpio)(nil)
|
|
|
|
// BoolGetter returns GPIO pin active
|
|
func (p *gpio) BoolGetter() (func() (bool, error), error) {
|
|
return func() (bool, error) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
|
|
if err := rpio.Open(); err != nil {
|
|
return false, fmt.Errorf("failed to open GPIO: %w", err)
|
|
}
|
|
defer rpio.Close()
|
|
|
|
return p.pin.Read() != rpio.Low, nil
|
|
}, nil
|
|
}
|