Add GPIO plugin (#25806)
This commit is contained in:
parent
60c8993c0c
commit
1c11cc46a1
5 changed files with 92 additions and 12 deletions
|
|
@ -8,7 +8,10 @@ import (
|
|||
)
|
||||
|
||||
// ErrNotAvailable indicates that a feature is not available
|
||||
var ErrNotAvailable = errors.New("not available")
|
||||
var ErrNotAvailable = backoff.Permanent(errors.New("not available"))
|
||||
|
||||
// ErrUnsupportedPlatform indicates unsupported hardware platform
|
||||
var ErrUnsupportedPlatform error = backoff.Permanent(errors.New("unsupported platform"))
|
||||
|
||||
// ErrMustRetry indicates that a rate-limited operation should be retried
|
||||
var ErrMustRetry = errors.New("must retry")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package charger
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
|
@ -15,5 +14,5 @@ func init() {
|
|||
|
||||
// NewOpenWbNativeFromConfig creates an OpenWbNative DIN charger from generic config
|
||||
func NewOpenWbNativeFromConfig(ctx context.Context, other map[string]any) (api.Charger, error) {
|
||||
return nil, errors.New("unsupported platform")
|
||||
return nil, api.ErrUnsupportedPlatform
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,20 +108,12 @@ func NewOpenWbNative(ctx context.Context, uri, device, comset string, baudrate i
|
|||
if err := rpio.Open(); err != nil {
|
||||
return nil, fmt.Errorf("failed to open GPIO: %w", err)
|
||||
}
|
||||
defer rpio.Close()
|
||||
|
||||
for _, pin := range structs.Fields(native.ChargePoints[connector-1]) {
|
||||
rpio.Pin(pin.Value().(int)).Output()
|
||||
}
|
||||
|
||||
// close GPIO when context is cancelled
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
log.DEBUG.Println("context canceled, closing GPIO")
|
||||
if err := rpio.Close(); err != nil {
|
||||
log.ERROR.Printf("error closing GPIO: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return decorateOpenWbNative(wb, phases1p3p, identify), nil
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +152,11 @@ func (wb *OpenWbNative) WakeUp() error {
|
|||
|
||||
// runGpioSequence executes a sequence of GPIO operations
|
||||
func (wb *OpenWbNative) runGpioSequence(seq []gpioAction) error {
|
||||
if err := rpio.Open(); err != nil {
|
||||
return fmt.Errorf("failed to open GPIO: %w", err)
|
||||
}
|
||||
defer rpio.Close()
|
||||
|
||||
if err := wb.Enable(false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
18
plugin/gpio.go
Normal file
18
plugin/gpio.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//go:build !linux
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.AddCtx("gpio", NewGpioPluginFromConfig)
|
||||
}
|
||||
|
||||
// NewGpioPluginFromConfig creates a GPIO provider
|
||||
func NewGpioPluginFromConfig(ctx context.Context, other map[string]any) (Plugin, error) {
|
||||
return nil, api.ErrUnsupportedPlatform
|
||||
}
|
||||
63
plugin/gpio_linux.go
Normal file
63
plugin/gpio_linux.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue