Add meter plugin (#21477)
This commit is contained in:
parent
5c8f101bb3
commit
02d3a362b2
5 changed files with 196 additions and 15 deletions
|
|
@ -2,14 +2,12 @@ package meter
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
"github.com/evcc-io/evcc/meter/config"
|
||||
)
|
||||
|
||||
var registry = reg.New[api.Meter]("meter")
|
||||
var registry = config.Registry
|
||||
|
||||
// Types returns the list of types
|
||||
func Types() []string {
|
||||
|
|
@ -18,15 +16,5 @@ func Types() []string {
|
|||
|
||||
// NewFromConfig creates meter from configuration
|
||||
func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Meter, error) {
|
||||
factory, err := registry.Get(strings.ToLower(typ))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(ctx, other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create meter type '%s': %w", typ, err)
|
||||
}
|
||||
|
||||
return v, err
|
||||
return config.NewFromConfig(ctx, typ, other)
|
||||
}
|
||||
|
|
|
|||
27
meter/config/config.go
Normal file
27
meter/config/config.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
reg "github.com/evcc-io/evcc/util/registry"
|
||||
)
|
||||
|
||||
var Registry = reg.New[api.Meter]("meter")
|
||||
|
||||
// NewFromConfig creates meter from configuration
|
||||
func NewFromConfig(ctx context.Context, typ string, other map[string]interface{}) (api.Meter, error) {
|
||||
factory, err := Registry.Get(strings.ToLower(typ))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v, err := factory(ctx, other)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("cannot create meter type '%s': %w", typ, err)
|
||||
}
|
||||
|
||||
return v, err
|
||||
}
|
||||
72
plugin/meter.go
Normal file
72
plugin/meter.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
meter "github.com/evcc-io/evcc/meter/config"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/config"
|
||||
)
|
||||
|
||||
type meterPlugin struct {
|
||||
meter api.Meter
|
||||
method Method
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.AddCtx("meter", NewMeterFromConfig)
|
||||
}
|
||||
|
||||
// NewMeterFromConfig creates type conversion provider
|
||||
func NewMeterFromConfig(ctx context.Context, other map[string]interface{}) (Plugin, error) {
|
||||
var cc struct {
|
||||
Config config.Typed
|
||||
Method
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
meter, err := meter.NewFromConfig(ctx, cc.Config.Type, cc.Config.Other)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
o := &meterPlugin{
|
||||
meter: meter,
|
||||
method: cc.Method,
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
var _ FloatGetter = (*meterPlugin)(nil)
|
||||
|
||||
func (o *meterPlugin) FloatGetter() (func() (float64, error), error) {
|
||||
err := fmt.Errorf("unsupported method: %s", o.method.String())
|
||||
|
||||
switch o.method {
|
||||
case Energy:
|
||||
if _, ok := o.meter.(api.MeterEnergy); !ok {
|
||||
return nil, err
|
||||
}
|
||||
case Soc:
|
||||
if _, ok := o.meter.(api.Battery); !ok {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return func() (float64, error) {
|
||||
switch o.method {
|
||||
case Energy:
|
||||
return o.meter.(api.MeterEnergy).TotalEnergy()
|
||||
case Soc:
|
||||
return o.meter.(api.Battery).Soc()
|
||||
default:
|
||||
return o.meter.CurrentPower()
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
11
plugin/method.go
Normal file
11
plugin/method.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package plugin
|
||||
|
||||
//go:generate go tool enumer -type Method
|
||||
type Method int
|
||||
|
||||
const (
|
||||
_ Method = iota
|
||||
Energy
|
||||
Power
|
||||
Soc
|
||||
)
|
||||
83
plugin/method_enumer.go
Normal file
83
plugin/method_enumer.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Code generated by "enumer -type Method"; DO NOT EDIT.
|
||||
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const _MethodName = "EnergyPowerSoc"
|
||||
|
||||
var _MethodIndex = [...]uint8{0, 6, 11, 14}
|
||||
|
||||
const _MethodLowerName = "energypowersoc"
|
||||
|
||||
func (i Method) String() string {
|
||||
i -= 1
|
||||
if i < 0 || i >= Method(len(_MethodIndex)-1) {
|
||||
return fmt.Sprintf("Method(%d)", i+1)
|
||||
}
|
||||
return _MethodName[_MethodIndex[i]:_MethodIndex[i+1]]
|
||||
}
|
||||
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
func _MethodNoOp() {
|
||||
var x [1]struct{}
|
||||
_ = x[Energy-(1)]
|
||||
_ = x[Power-(2)]
|
||||
_ = x[Soc-(3)]
|
||||
}
|
||||
|
||||
var _MethodValues = []Method{Energy, Power, Soc}
|
||||
|
||||
var _MethodNameToValueMap = map[string]Method{
|
||||
_MethodName[0:6]: Energy,
|
||||
_MethodLowerName[0:6]: Energy,
|
||||
_MethodName[6:11]: Power,
|
||||
_MethodLowerName[6:11]: Power,
|
||||
_MethodName[11:14]: Soc,
|
||||
_MethodLowerName[11:14]: Soc,
|
||||
}
|
||||
|
||||
var _MethodNames = []string{
|
||||
_MethodName[0:6],
|
||||
_MethodName[6:11],
|
||||
_MethodName[11:14],
|
||||
}
|
||||
|
||||
// MethodString retrieves an enum value from the enum constants string name.
|
||||
// Throws an error if the param is not part of the enum.
|
||||
func MethodString(s string) (Method, error) {
|
||||
if val, ok := _MethodNameToValueMap[s]; ok {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
if val, ok := _MethodNameToValueMap[strings.ToLower(s)]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return 0, fmt.Errorf("%s does not belong to Method values", s)
|
||||
}
|
||||
|
||||
// MethodValues returns all values of the enum
|
||||
func MethodValues() []Method {
|
||||
return _MethodValues
|
||||
}
|
||||
|
||||
// MethodStrings returns a slice of all String values of the enum
|
||||
func MethodStrings() []string {
|
||||
strs := make([]string, len(_MethodNames))
|
||||
copy(strs, _MethodNames)
|
||||
return strs
|
||||
}
|
||||
|
||||
// IsAMethod returns "true" if the value is listed in the enum definition. "false" otherwise
|
||||
func (i Method) IsAMethod() bool {
|
||||
for _, v := range _MethodValues {
|
||||
if i == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue