Add MeterReturnEnergy (#29805)
This commit is contained in:
parent
869ac1d6eb
commit
7b5df178ce
20 changed files with 196 additions and 57 deletions
|
|
@ -9,7 +9,7 @@ import (
|
|||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
//go:generate go tool mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff
|
||||
//go:generate go tool mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,MeterReturnEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff
|
||||
|
||||
// Meter provides total active power in W
|
||||
type Meter interface {
|
||||
|
|
@ -21,6 +21,11 @@ type MeterEnergy interface {
|
|||
TotalEnergy() (float64, error)
|
||||
}
|
||||
|
||||
// MeterReturnEnergy provides total returned energy in kWh
|
||||
type MeterReturnEnergy interface {
|
||||
ReturnEnergy() (float64, error)
|
||||
}
|
||||
|
||||
// PhaseCurrents provides per-phase current A
|
||||
type PhaseCurrents interface {
|
||||
Currents() (float64, float64, float64, error)
|
||||
|
|
|
|||
|
|
@ -273,6 +273,21 @@ func (i *iMeterEnergy) TotalEnergy() (float64, error) {
|
|||
return i.meterEnergy0()
|
||||
}
|
||||
|
||||
func MeterReturnEnergy(meterReturnEnergy0 func() (float64, error)) api.MeterReturnEnergy {
|
||||
if meterReturnEnergy0 == nil {
|
||||
return nil
|
||||
}
|
||||
return &iMeterReturnEnergy{meterReturnEnergy0}
|
||||
}
|
||||
|
||||
type iMeterReturnEnergy struct {
|
||||
meterReturnEnergy0 func() (float64, error)
|
||||
}
|
||||
|
||||
func (i *iMeterReturnEnergy) ReturnEnergy() (float64, error) {
|
||||
return i.meterReturnEnergy0()
|
||||
}
|
||||
|
||||
func PhaseCurrents(phaseCurrents0 func() (float64, float64, float64, error)) api.PhaseCurrents {
|
||||
if phaseCurrents0 == nil {
|
||||
return nil
|
||||
|
|
|
|||
43
api/mock.go
43
api/mock.go
|
|
@ -1,9 +1,9 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/evcc-io/evcc/api (interfaces: Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff)
|
||||
// Source: github.com/evcc-io/evcc/api (interfaces: Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,MeterReturnEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff
|
||||
// mockgen -package api -destination mock.go github.com/evcc-io/evcc/api Charger,ChargeState,CurrentLimiter,CurrentGetter,PhaseSwitcher,PhaseGetter,FeatureDescriber,Identifier,Meter,MeterEnergy,MeterReturnEnergy,PhaseCurrents,Vehicle,ConnectionTimer,ChargeRater,Battery,BatteryController,BatterySocLimiter,Circuit,Dimmer,Tariff
|
||||
//
|
||||
|
||||
// Package api is a generated GoMock package.
|
||||
|
|
@ -448,6 +448,45 @@ func (mr *MockMeterEnergyMockRecorder) TotalEnergy() *gomock.Call {
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TotalEnergy", reflect.TypeOf((*MockMeterEnergy)(nil).TotalEnergy))
|
||||
}
|
||||
|
||||
// MockMeterReturnEnergy is a mock of MeterReturnEnergy interface.
|
||||
type MockMeterReturnEnergy struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockMeterReturnEnergyMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockMeterReturnEnergyMockRecorder is the mock recorder for MockMeterReturnEnergy.
|
||||
type MockMeterReturnEnergyMockRecorder struct {
|
||||
mock *MockMeterReturnEnergy
|
||||
}
|
||||
|
||||
// NewMockMeterReturnEnergy creates a new mock instance.
|
||||
func NewMockMeterReturnEnergy(ctrl *gomock.Controller) *MockMeterReturnEnergy {
|
||||
mock := &MockMeterReturnEnergy{ctrl: ctrl}
|
||||
mock.recorder = &MockMeterReturnEnergyMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockMeterReturnEnergy) EXPECT() *MockMeterReturnEnergyMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// ReturnEnergy mocks base method.
|
||||
func (m *MockMeterReturnEnergy) ReturnEnergy() (float64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReturnEnergy")
|
||||
ret0, _ := ret[0].(float64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ReturnEnergy indicates an expected call of ReturnEnergy.
|
||||
func (mr *MockMeterReturnEnergyMockRecorder) ReturnEnergy() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReturnEnergy", reflect.TypeOf((*MockMeterReturnEnergy)(nil).ReturnEnergy))
|
||||
}
|
||||
|
||||
// MockPhaseCurrents is a mock of PhaseCurrents interface.
|
||||
type MockPhaseCurrents struct {
|
||||
ctrl *gomock.Controller
|
||||
|
|
|
|||
|
|
@ -146,13 +146,13 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.C
|
|||
implement.May(c, implement.Battery(soc))
|
||||
implement.May(c, implement.SocLimiter(limitsoc))
|
||||
|
||||
// decorate measurements
|
||||
powerG, energyG, err := cc.Energy.Configure(ctx)
|
||||
powerG, energyG, returnG, err := cc.Energy.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
implement.May(c, implement.Meter(powerG))
|
||||
implement.May(c, implement.MeterEnergy(energyG))
|
||||
implement.May(c, implement.MeterReturnEnergy(returnG))
|
||||
|
||||
currentsG, voltagesG, _, err := cc.Phases.Configure(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -82,12 +82,13 @@ func NewHeatpumpFromConfig(ctx context.Context, other map[string]any) (api.Charg
|
|||
return nil, err
|
||||
}
|
||||
|
||||
powerG, energyG, err := cc.Energy.Configure(ctx)
|
||||
powerG, energyG, returnG, err := cc.Energy.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
implement.May(res, implement.Meter(powerG))
|
||||
implement.May(res, implement.MeterEnergy(energyG))
|
||||
implement.May(res, implement.MeterReturnEnergy(returnG))
|
||||
|
||||
tempG, limitTempG, err := cc.Temperature.Configure(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -10,22 +10,29 @@ import (
|
|||
type Energy struct {
|
||||
Power *plugin.Config // optional
|
||||
Energy *plugin.Config // optional
|
||||
ReturnEnergy *plugin.Config // optional
|
||||
}
|
||||
|
||||
func (cc *Energy) Configure(ctx context.Context) (
|
||||
func() (float64, error),
|
||||
func() (float64, error),
|
||||
func() (float64, error),
|
||||
error,
|
||||
) {
|
||||
powerG, err := cc.Power.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("power: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("power: %w", err)
|
||||
}
|
||||
|
||||
energyG, err := cc.Energy.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("energy: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("energy: %w", err)
|
||||
}
|
||||
|
||||
return powerG, energyG, nil
|
||||
returnG, err := cc.ReturnEnergy.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("returnEnergy: %w", err)
|
||||
}
|
||||
|
||||
return powerG, energyG, returnG, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,12 +61,13 @@ func NewSgReadyRelayFromConfig(ctx context.Context, other map[string]any) (api.C
|
|||
return nil, err
|
||||
}
|
||||
|
||||
powerG, energyG, err := cc.Energy.Configure(ctx)
|
||||
powerG, energyG, returnG, err := cc.Energy.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
implement.May(res, implement.Meter(powerG))
|
||||
implement.May(res, implement.MeterEnergy(energyG))
|
||||
implement.May(res, implement.MeterReturnEnergy(returnG))
|
||||
|
||||
tempG, limitTempG, err := cc.Temperature.Configure(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -107,12 +107,13 @@ func NewSgReadyFromConfig(ctx context.Context, other map[string]any) (api.Charge
|
|||
return nil, err
|
||||
}
|
||||
|
||||
powerG, energyG, err := cc.Energy.Configure(ctx)
|
||||
powerG, energyG, returnG, err := cc.Energy.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
implement.May(res, implement.Meter(powerG))
|
||||
implement.May(res, implement.MeterEnergy(energyG))
|
||||
implement.May(res, implement.MeterReturnEnergy(returnG))
|
||||
|
||||
tempG, limitTempG, err := cc.Temperature.Configure(ctx)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@ func (d *dumper) Dump(name string, v any) {
|
|||
})
|
||||
}
|
||||
|
||||
if v, ok := api.Cap[api.MeterReturnEnergy](v); ok {
|
||||
d.measureTime(w, "Return Energy", func() (string, error) {
|
||||
energy, err := v.ReturnEnergy()
|
||||
return fmt.Sprintf("%.1fkWh", energy), err
|
||||
})
|
||||
}
|
||||
|
||||
if v, ok := api.Cap[api.PhaseCurrents](v); ok {
|
||||
d.measureTime(w, "Current L1..L3", func() (string, error) {
|
||||
i1, i2, i3, err := v.Currents()
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ func generate(out io.Writer) error {
|
|||
reflect.TypeFor[api.MaxACPowerGetter](),
|
||||
reflect.TypeFor[api.Meter](),
|
||||
reflect.TypeFor[api.MeterEnergy](),
|
||||
reflect.TypeFor[api.MeterReturnEnergy](),
|
||||
reflect.TypeFor[api.PhaseCurrents](),
|
||||
reflect.TypeFor[api.PhaseGetter](),
|
||||
reflect.TypeFor[api.PhasePowers](),
|
||||
|
|
|
|||
|
|
@ -10,22 +10,29 @@ import (
|
|||
type Energy struct {
|
||||
Power plugin.Config
|
||||
Energy *plugin.Config // optional
|
||||
ReturnEnergy *plugin.Config // optional
|
||||
}
|
||||
|
||||
func (cc *Energy) Configure(ctx context.Context) (
|
||||
func() (float64, error),
|
||||
func() (float64, error),
|
||||
func() (float64, error),
|
||||
error,
|
||||
) {
|
||||
powerG, err := cc.Power.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("power: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("power: %w", err)
|
||||
}
|
||||
|
||||
energyG, err := cc.Energy.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("energy: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("energy: %w", err)
|
||||
}
|
||||
|
||||
return powerG, energyG, nil
|
||||
returnG, err := cc.ReturnEnergy.FloatGetter(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("returnEnergy: %w", err)
|
||||
}
|
||||
|
||||
return powerG, energyG, returnG, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,13 +44,14 @@ func NewConfigurableFromConfig(ctx context.Context, other map[string]any) (api.M
|
|||
return nil, err
|
||||
}
|
||||
|
||||
powerG, energyG, err := cc.Energy.Configure(ctx)
|
||||
powerG, energyG, returnG, err := cc.Energy.Configure(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m, _ := NewConfigurable(powerG)
|
||||
implement.May(m, implement.MeterEnergy(energyG))
|
||||
implement.May(m, implement.MeterReturnEnergy(returnG))
|
||||
|
||||
// dim/curtail
|
||||
if err := cc.Dimmer.Implement(ctx, m); err != nil {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ func NewMovingAverageFromConfig(ctx context.Context, other map[string]any) (api.
|
|||
totalEnergy = m.TotalEnergy
|
||||
}
|
||||
|
||||
// decorate return energy reading
|
||||
var returnEnergy func() (float64, error)
|
||||
if m, ok := api.Cap[api.MeterReturnEnergy](m); ok {
|
||||
returnEnergy = m.ReturnEnergy
|
||||
}
|
||||
|
||||
// decorate battery reading
|
||||
var batterySoc func() (float64, error)
|
||||
if m, ok := api.Cap[api.Battery](m); ok {
|
||||
|
|
@ -72,6 +78,7 @@ func NewMovingAverageFromConfig(ctx context.Context, other map[string]any) (api.
|
|||
}
|
||||
|
||||
implement.May(meter, implement.MeterEnergy(totalEnergy))
|
||||
implement.May(meter, implement.MeterReturnEnergy(returnEnergy))
|
||||
|
||||
if batterySoc != nil {
|
||||
implement.Has(meter, implement.Battery(batterySoc))
|
||||
|
|
|
|||
|
|
@ -6,22 +6,24 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/evcc-io/evcc/util/transport"
|
||||
)
|
||||
|
||||
type Generation interface {
|
||||
CurrentPower() (float64, error)
|
||||
Enabled() (bool, error)
|
||||
Enable(bool) error
|
||||
TotalEnergy() (float64, error)
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterReturnEnergy
|
||||
}
|
||||
|
||||
type Phases interface {
|
||||
Currents() (float64, float64, float64, error)
|
||||
Voltages() (float64, float64, float64, error)
|
||||
Powers() (float64, float64, float64, error)
|
||||
api.PhaseCurrents
|
||||
api.PhaseVoltages
|
||||
api.PhasePowers
|
||||
}
|
||||
|
||||
// Connection is the Shelly connection
|
||||
|
|
|
|||
|
|
@ -125,6 +125,25 @@ func (c *gen1) TotalEnergy() (float64, error) {
|
|||
return c.energy(energy) / 1000, nil
|
||||
}
|
||||
|
||||
func (c *gen1) ReturnEnergy() (float64, error) {
|
||||
var energy float64
|
||||
res, err := c.status.Get()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.channel < len(res.Meters):
|
||||
energy = res.Meters[c.channel].Total_Returned
|
||||
case c.channel < len(res.EMeters):
|
||||
energy = res.EMeters[c.channel].Total_Returned
|
||||
default:
|
||||
return 0, errors.New("invalid channel, missing power meter")
|
||||
}
|
||||
|
||||
return c.energy(energy) / 1000, nil
|
||||
}
|
||||
|
||||
// gen1Energy in kWh
|
||||
func (c *gen1) energy(energy float64) float64 {
|
||||
// Gen 1 Shelly EM devices are providing Watt hours, Gen 1 Shelly PM devices are providing Watt minutes
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ func (c *gen2) Enable(enable bool) error {
|
|||
return c.execEnableCmd(c.switchchannel, "Switch.Set", enable, &res)
|
||||
}
|
||||
|
||||
// TotalEnergy implements the api.Meter interface
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
func (c *gen2) TotalEnergy() (float64, error) {
|
||||
switch {
|
||||
case c.hasEM1Endpoint():
|
||||
|
|
@ -239,6 +239,26 @@ func (c *gen2) TotalEnergy() (float64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// ReturnEnergy implements the api.MeterReturnEnergy interface
|
||||
func (c *gen2) ReturnEnergy() (float64, error) {
|
||||
switch {
|
||||
case c.hasEM1Endpoint():
|
||||
res, err := c.em1data()
|
||||
return res.TotalActRetEnergy / 1000, err
|
||||
|
||||
case c.hasEMEndpoint():
|
||||
res, err := c.emdata()
|
||||
return res.TotalActRet / 1000, err
|
||||
|
||||
case c.hasSwitchEndpoint():
|
||||
res, err := c.switchstatus.Get()
|
||||
return res.Ret_Aenergy.Total / 1000, err
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unknown shelly model: %s", c.model)
|
||||
}
|
||||
}
|
||||
|
||||
// Currents implements the api.PhaseCurrents interface
|
||||
func (c *gen2) Currents() (float64, float64, float64, error) {
|
||||
switch {
|
||||
|
|
|
|||
|
|
@ -51,32 +51,28 @@ func NewMeterFromConfig(ctx context.Context, other map[string]any) (Plugin, erro
|
|||
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 !api.HasCap[api.MeterEnergy](o.meter) {
|
||||
return nil, err
|
||||
}
|
||||
case Soc:
|
||||
if !api.HasCap[api.Battery](o.meter) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return func() (float64, error) {
|
||||
switch o.method {
|
||||
case Energy:
|
||||
m, _ := api.Cap[api.MeterEnergy](o.meter)
|
||||
if m, ok := api.Cap[api.MeterEnergy](o.meter); ok {
|
||||
f, err := m.TotalEnergy()
|
||||
return f * o.scale, err
|
||||
}
|
||||
case ReturnEnergy:
|
||||
if m, ok := api.Cap[api.MeterReturnEnergy](o.meter); ok {
|
||||
f, err := m.ReturnEnergy()
|
||||
return f * o.scale, err
|
||||
}
|
||||
case Soc:
|
||||
m, _ := api.Cap[api.Battery](o.meter)
|
||||
if m, ok := api.Cap[api.Battery](o.meter); ok {
|
||||
f, err := m.Soc()
|
||||
return f * o.scale, err
|
||||
default:
|
||||
}
|
||||
case Power:
|
||||
f, err := o.meter.CurrentPower()
|
||||
return f * o.scale, err
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("unsupported method: %s", o.method.String())
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ type Method int
|
|||
const (
|
||||
_ Method = iota
|
||||
Energy
|
||||
ReturnEnergy
|
||||
Power
|
||||
Soc
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const _MethodName = "EnergyPowerSoc"
|
||||
const _MethodName = "EnergyReturnEnergyPowerSoc"
|
||||
|
||||
var _MethodIndex = [...]uint8{0, 6, 11, 14}
|
||||
var _MethodIndex = [...]uint8{0, 6, 18, 23, 26}
|
||||
|
||||
const _MethodLowerName = "energypowersoc"
|
||||
const _MethodLowerName = "energyreturnenergypowersoc"
|
||||
|
||||
func (i Method) String() string {
|
||||
i -= 1
|
||||
|
|
@ -26,25 +26,29 @@ func (i Method) String() string {
|
|||
func _MethodNoOp() {
|
||||
var x [1]struct{}
|
||||
_ = x[Energy-(1)]
|
||||
_ = x[Power-(2)]
|
||||
_ = x[Soc-(3)]
|
||||
_ = x[ReturnEnergy-(2)]
|
||||
_ = x[Power-(3)]
|
||||
_ = x[Soc-(4)]
|
||||
}
|
||||
|
||||
var _MethodValues = []Method{Energy, Power, Soc}
|
||||
var _MethodValues = []Method{Energy, ReturnEnergy, 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,
|
||||
_MethodName[6:18]: ReturnEnergy,
|
||||
_MethodLowerName[6:18]: ReturnEnergy,
|
||||
_MethodName[18:23]: Power,
|
||||
_MethodLowerName[18:23]: Power,
|
||||
_MethodName[23:26]: Soc,
|
||||
_MethodLowerName[23:26]: Soc,
|
||||
}
|
||||
|
||||
var _MethodNames = []string{
|
||||
_MethodName[0:6],
|
||||
_MethodName[6:11],
|
||||
_MethodName[11:14],
|
||||
_MethodName[6:18],
|
||||
_MethodName[18:23],
|
||||
_MethodName[23:26],
|
||||
}
|
||||
|
||||
// MethodString retrieves an enum value from the enum constants string name.
|
||||
|
|
|
|||
|
|
@ -279,6 +279,11 @@ func testInstance(instance any) map[string]testResult {
|
|||
makeResult("energy", val, err)
|
||||
}
|
||||
|
||||
if dev, ok := api.Cap[api.MeterReturnEnergy](instance); ok {
|
||||
val, err := dev.ReturnEnergy()
|
||||
makeResult("returnEnergy", val, err)
|
||||
}
|
||||
|
||||
if dev, ok := api.Cap[api.Battery](instance); ok {
|
||||
val, err := dev.Soc()
|
||||
key := "soc"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue