Replace combinatorial decorators with capability registry (BC) (#28565)

This commit is contained in:
Maschga 2026-03-27 09:17:19 +01:00 • committed by GitHub
parent 33d2de24c1
commit 00967eb57e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
101 changed files with 2416 additions and 44670 deletions

36
api/capable.go Normal file
View file

@ -0,0 +1,36 @@
package api
import "reflect"
// Capable is implemented by decorated types that support dynamic capability lookup.
// This allows O(n) decorator code instead of O(2^n) combinatorial struct generation.
type Capable interface {
Capability(typ reflect.Type) (any, bool)
}
// Cap checks whether v implements interface T, either directly (via Go type assertion)
// or through the Capable registry (for decorated types) and returns the interface same
// as a Go type assertion would do.
func Cap[T any](v any) (T, bool) {
// fast path: direct type assertion (works for non-decorated concrete types)
if t, ok := v.(T); ok {
return t, ok
}
// slow path: capability registry lookup (for decorated types)
if c, ok := v.(Capable); ok {
if impl, ok := c.Capability(reflect.TypeFor[T]()); ok {
return impl.(T), true
}
}
var zero T
return zero, false
}
// HasCap checks whether v implements interface T, either directly (via Go type assertion)
// or through the Capable registry (for decorated types).
func HasCap[T any](v any) bool {
_, ok := Cap[T](v)
return ok
}

89
api/capable_test.go Normal file
View file

@ -0,0 +1,89 @@
package api
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// mock decorated type with capability registry
type decoratedMeter struct {
Meter
caps map[reflect.Type]any
}
func (d *decoratedMeter) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type testMeterEnergyImpl struct{}
func (t *testMeterEnergyImpl) TotalEnergy() (float64, error) {
return 99.0, nil
}
type testMeterImpl struct{}
func (t *testMeterImpl) CurrentPower() (float64, error) {
return 100.0, nil
}
func TestCap_DirectTypeAssertion(t *testing.T) {
// concrete type that directly implements MeterEnergy
impl := &testMeterEnergyImpl{}
me, ok := Cap[MeterEnergy](impl)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
}
func TestCap_CapableRegistryLookup(t *testing.T) {
base := &testMeterImpl{}
decorated := &decoratedMeter{
Meter: base,
caps: map[reflect.Type]any{
reflect.TypeFor[MeterEnergy](): &testMeterEnergyImpl{},
},
}
// should find MeterEnergy via registry
me, ok := Cap[MeterEnergy](decorated)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
// should NOT find PhaseCurrents (not registered)
_, ok = Cap[PhaseCurrents](decorated)
assert.False(t, ok)
}
func TestCap_NilValue(t *testing.T) {
_, ok := Cap[MeterEnergy](nil)
assert.False(t, ok)
}
func TestCap_DirectTakesPrecedence(t *testing.T) {
// type that both directly implements AND has registry
type directAndCapable struct {
testMeterEnergyImpl
caps map[reflect.Type]any //nolint:unused
}
v := &directAndCapable{}
me, ok := Cap[MeterEnergy](v)
require.True(t, ok)
energy, err := me.TotalEnergy()
assert.NoError(t, err)
assert.Equal(t, 99.0, energy)
}

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateABLeMH(base *ABLeMH, meter func() (float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateABLeMHMeterImpl{meter: meter}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateABLeMHPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case meter != nil && phaseCurrents == nil:
return &struct {
return &decorateABLeMHCapable{ABLeMH: base, caps: caps}
}
type decorateABLeMHCapable struct {
*ABLeMH
api.Meter
}{
ABLeMH: base,
Meter: &decorateABLeMHMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && phaseCurrents != nil:
return &struct {
*ABLeMH
api.Meter
api.PhaseCurrents
}{
ABLeMH: base,
Meter: &decorateABLeMHMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateABLeMHPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decorateABLeMHCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateABLeMHMeterImpl struct {

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateAlfen(base *Alfen, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateAlfenPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateAlfenPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateAlfenCapable{Alfen: base, caps: caps}
}
type decorateAlfenCapable struct {
*Alfen
api.PhaseSwitcher
}{
Alfen: base,
PhaseSwitcher: &decorateAlfenPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Alfen
api.PhaseGetter
api.PhaseSwitcher
}{
Alfen: base,
PhaseGetter: &decorateAlfenPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateAlfenPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateAlfenCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateAlfenPhaseGetterImpl struct {

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateAmperfied(base *Amperfied, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateAmperfiedPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateAmperfiedPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateAmperfiedCapable{Amperfied: base, caps: caps}
}
type decorateAmperfiedCapable struct {
*Amperfied
api.PhaseSwitcher
}{
Amperfied: base,
PhaseSwitcher: &decorateAmperfiedPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Amperfied
api.PhaseGetter
api.PhaseSwitcher
}{
Amperfied: base,
PhaseGetter: &decorateAmperfiedPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateAmperfiedPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateAmperfiedCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateAmperfiedPhaseGetterImpl struct {

File diff suppressed because it is too large Load diff

View file

@ -3,163 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateCfos(base *CfosPowerBrain, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseSwitcher func(int) error) api.Charger {
switch {
case meter == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateCfosMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateCfosMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateCfosPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateCfosPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseSwitcher == nil:
return &struct {
return &decorateCfosCapable{CfosPowerBrain: base, caps: caps}
}
type decorateCfosCapable struct {
*CfosPowerBrain
api.Meter
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseSwitcher == nil:
return &struct {
*CfosPowerBrain
api.Meter
api.MeterEnergy
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
MeterEnergy: &decorateCfosMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseSwitcher == nil:
return &struct {
*CfosPowerBrain
api.Meter
api.PhaseCurrents
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateCfosPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseSwitcher == nil:
return &struct {
*CfosPowerBrain
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
MeterEnergy: &decorateCfosMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateCfosPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter == nil && phaseSwitcher != nil:
return &struct {
*CfosPowerBrain
api.PhaseSwitcher
}{
CfosPowerBrain: base,
PhaseSwitcher: &decorateCfosPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseSwitcher != nil:
return &struct {
*CfosPowerBrain
api.Meter
api.PhaseSwitcher
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
PhaseSwitcher: &decorateCfosPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseSwitcher != nil:
return &struct {
*CfosPowerBrain
api.Meter
api.MeterEnergy
api.PhaseSwitcher
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
MeterEnergy: &decorateCfosMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseSwitcher: &decorateCfosPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseSwitcher != nil:
return &struct {
*CfosPowerBrain
api.Meter
api.PhaseCurrents
api.PhaseSwitcher
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateCfosPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseSwitcher: &decorateCfosPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseSwitcher != nil:
return &struct {
*CfosPowerBrain
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseSwitcher
}{
CfosPowerBrain: base,
Meter: &decorateCfosMeterImpl{
meter: meter,
},
MeterEnergy: &decorateCfosMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateCfosPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseSwitcher: &decorateCfosPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateCfosCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateCfosMeterImpl struct {

File diff suppressed because it is too large Load diff

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateDaheimLaden(base *DaheimLaden, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateDaheimLadenPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateDaheimLadenPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateDaheimLadenCapable{DaheimLaden: base, caps: caps}
}
type decorateDaheimLadenCapable struct {
*DaheimLaden
api.PhaseSwitcher
}{
DaheimLaden: base,
PhaseSwitcher: &decorateDaheimLadenPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*DaheimLaden
api.PhaseGetter
api.PhaseSwitcher
}{
DaheimLaden: base,
PhaseGetter: &decorateDaheimLadenPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateDaheimLadenPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateDaheimLadenCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateDaheimLadenPhaseGetterImpl struct {

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEEBus(base *EEBus, meter func() (float64, error), phaseCurrents func() (float64, float64, float64, error), chargeRater func() (float64, error)) api.Charger {
switch {
case chargeRater == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateEEBusMeterImpl{meter: meter}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateEEBusPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if chargeRater != nil {
caps[reflect.TypeFor[api.ChargeRater]()] = &decorateEEBusChargeRaterImpl{chargeRater: chargeRater}
}
if len(caps) == 0 {
return base
}
case chargeRater == nil && meter != nil && phaseCurrents == nil:
return &struct {
return &decorateEEBusCapable{EEBus: base, caps: caps}
}
type decorateEEBusCapable struct {
*EEBus
api.Meter
}{
EEBus: base,
Meter: &decorateEEBusMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case chargeRater == nil && meter != nil && phaseCurrents != nil:
return &struct {
*EEBus
api.Meter
api.PhaseCurrents
}{
EEBus: base,
Meter: &decorateEEBusMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEEBusPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargeRater != nil && meter == nil:
return &struct {
*EEBus
api.ChargeRater
}{
EEBus: base,
ChargeRater: &decorateEEBusChargeRaterImpl{
chargeRater: chargeRater,
},
}
case chargeRater != nil && meter != nil && phaseCurrents == nil:
return &struct {
*EEBus
api.ChargeRater
api.Meter
}{
EEBus: base,
ChargeRater: &decorateEEBusChargeRaterImpl{
chargeRater: chargeRater,
},
Meter: &decorateEEBusMeterImpl{
meter: meter,
},
}
case chargeRater != nil && meter != nil && phaseCurrents != nil:
return &struct {
*EEBus
api.ChargeRater
api.Meter
api.PhaseCurrents
}{
EEBus: base,
ChargeRater: &decorateEEBusChargeRaterImpl{
chargeRater: chargeRater,
},
Meter: &decorateEEBusMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEEBusPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decorateEEBusCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEEBusChargeRaterImpl struct {

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEm2Go(base *Em2Go, chargerEx func(float64) error, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case chargerEx == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decorateEm2GoChargerExImpl{chargerEx: chargerEx}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateEm2GoPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateEm2GoPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case chargerEx != nil && phaseSwitcher == nil:
return &struct {
return &decorateEm2GoCapable{Em2Go: base, caps: caps}
}
type decorateEm2GoCapable struct {
*Em2Go
api.ChargerEx
}{
Em2Go: base,
ChargerEx: &decorateEm2GoChargerExImpl{
chargerEx: chargerEx,
},
caps map[reflect.Type]any
}
case chargerEx == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Em2Go
api.PhaseSwitcher
}{
Em2Go: base,
PhaseSwitcher: &decorateEm2GoPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Em2Go
api.ChargerEx
api.PhaseSwitcher
}{
Em2Go: base,
ChargerEx: &decorateEm2GoChargerExImpl{
chargerEx: chargerEx,
},
PhaseSwitcher: &decorateEm2GoPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Em2Go
api.PhaseGetter
api.PhaseSwitcher
}{
Em2Go: base,
PhaseGetter: &decorateEm2GoPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateEm2GoPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Em2Go
api.ChargerEx
api.PhaseGetter
api.PhaseSwitcher
}{
Em2Go: base,
ChargerEx: &decorateEm2GoChargerExImpl{
chargerEx: chargerEx,
},
PhaseGetter: &decorateEm2GoPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateEm2GoPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateEm2GoCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEm2GoChargerExImpl struct {

View file

@ -3,76 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEtek(base *Etek, meter func() (float64, error), meterEnergy func() (float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateEtekMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateEtekMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateEtekPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseVoltages == nil:
return &struct {
return &decorateEtekCapable{Etek: base, caps: caps}
}
type decorateEtekCapable struct {
*Etek
api.Meter
}{
Etek: base,
Meter: &decorateEtekMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseVoltages == nil:
return &struct {
*Etek
api.Meter
api.MeterEnergy
}{
Etek: base,
Meter: &decorateEtekMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEtekMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseVoltages != nil:
return &struct {
*Etek
api.Meter
api.PhaseVoltages
}{
Etek: base,
Meter: &decorateEtekMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateEtekPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseVoltages != nil:
return &struct {
*Etek
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
Etek: base,
Meter: &decorateEtekMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEtekMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateEtekPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateEtekCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEtekMeterImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEVECUBE(base *EVECUBE, phaseSwitcher func(int) error, identifier func() (string, error)) api.Charger {
switch {
case identifier == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateEVECUBEPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateEVECUBEIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case identifier == nil && phaseSwitcher != nil:
return &struct {
return &decorateEVECUBECapable{EVECUBE: base, caps: caps}
}
type decorateEVECUBECapable struct {
*EVECUBE
api.PhaseSwitcher
}{
EVECUBE: base,
PhaseSwitcher: &decorateEVECUBEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case identifier != nil && phaseSwitcher == nil:
return &struct {
*EVECUBE
api.Identifier
}{
EVECUBE: base,
Identifier: &decorateEVECUBEIdentifierImpl{
identifier: identifier,
},
}
case identifier != nil && phaseSwitcher != nil:
return &struct {
*EVECUBE
api.Identifier
api.PhaseSwitcher
}{
EVECUBE: base,
Identifier: &decorateEVECUBEIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateEVECUBEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateEVECUBECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEVECUBEIdentifierImpl struct {

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEvseDIN(base *EvseDIN, chargerEx func(float64) error) api.Charger {
switch {
case chargerEx == nil:
caps := make(map[reflect.Type]any)
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decorateEvseDINChargerExImpl{chargerEx: chargerEx}
}
if len(caps) == 0 {
return base
}
case chargerEx != nil:
return &struct {
return &decorateEvseDINCapable{EvseDIN: base, caps: caps}
}
type decorateEvseDINCapable struct {
*EvseDIN
api.ChargerEx
}{
EvseDIN: base,
ChargerEx: &decorateEvseDINChargerExImpl{
chargerEx: chargerEx,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateEvseDINCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEvseDINChargerExImpl struct {

View file

@ -3,725 +3,53 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error), chargerEx func(float64) error, identifier func() (string, error)) api.Charger {
switch {
case chargerEx == nil && identifier == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateEVSEMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateEVSEMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateEVSEPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateEVSEPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decorateEVSEChargerExImpl{chargerEx: chargerEx}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateEVSEIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
return &decorateEVSECapable{EVSEWifi: base, caps: caps}
}
type decorateEVSECapable struct {
*EVSEWifi
api.Meter
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Meter
api.MeterEnergy
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Meter
api.PhaseCurrents
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Meter
api.PhaseVoltages
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter == nil:
return &struct {
*EVSEWifi
api.ChargerEx
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.MeterEnergy
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.PhaseCurrents
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter == nil:
return &struct {
*EVSEWifi
api.Identifier
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.MeterEnergy
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.PhaseCurrents
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.PhaseVoltages
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.PhaseCurrents
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*EVSEWifi
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
EVSEWifi: base,
ChargerEx: &decorateEVSEChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateEVSEIdentifierImpl{
identifier: identifier,
},
Meter: &decorateEVSEMeterImpl{
meter: meter,
},
MeterEnergy: &decorateEVSEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateEVSEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateEVSECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateEVSEChargerExImpl struct {

View file

@ -28,19 +28,19 @@ func TestEvseWifi(t *testing.T) {
t.Error(err)
}
if _, ok := wb.(api.Meter); !ok {
if _, ok := api.Cap[api.Meter](wb); !ok {
t.Error("missing api.Meter")
}
if _, ok := wb.(api.MeterEnergy); !ok {
if _, ok := api.Cap[api.MeterEnergy](wb); !ok {
t.Error("missing api.MeterEnergy")
}
if _, ok := wb.(api.PhaseCurrents); !ok {
if _, ok := api.Cap[api.PhaseCurrents](wb); !ok {
t.Error("missing api.PhaseCurrents")
}
if _, ok := wb.(api.PhaseVoltages); !ok {
if _, ok := api.Cap[api.PhaseVoltages](wb); !ok {
t.Error("missing api.PhaseVoltages")
}
}
@ -58,7 +58,7 @@ func TestEvseWifiEx(t *testing.T) {
t.Error(err)
}
if _, ok := wb.(api.ChargerEx); !ok {
if _, ok := api.Cap[api.ChargerEx](wb); !ok {
t.Error("missing api.ChargerEx")
}
}

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateGoE(base *GoE, chargeRater func() (float64, error), phaseSwitcher func(int) error) api.Charger {
switch {
case chargeRater == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if chargeRater != nil {
caps[reflect.TypeFor[api.ChargeRater]()] = &decorateGoEChargeRaterImpl{chargeRater: chargeRater}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateGoEPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case chargeRater != nil && phaseSwitcher == nil:
return &struct {
return &decorateGoECapable{GoE: base, caps: caps}
}
type decorateGoECapable struct {
*GoE
api.ChargeRater
}{
GoE: base,
ChargeRater: &decorateGoEChargeRaterImpl{
chargeRater: chargeRater,
},
caps map[reflect.Type]any
}
case chargeRater == nil && phaseSwitcher != nil:
return &struct {
*GoE
api.PhaseSwitcher
}{
GoE: base,
PhaseSwitcher: &decorateGoEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargeRater != nil && phaseSwitcher != nil:
return &struct {
*GoE
api.ChargeRater
api.PhaseSwitcher
}{
GoE: base,
ChargeRater: &decorateGoEChargeRaterImpl{
chargeRater: chargeRater,
},
PhaseSwitcher: &decorateGoEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateGoECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateGoEChargeRaterImpl struct {

View file

@ -42,15 +42,15 @@ func TestGoEV1(t *testing.T) {
t.Error(err)
}
if _, ok := wb.(api.Meter); !ok {
if _, ok := api.Cap[api.Meter](wb); !ok {
t.Error("missing Meter api")
}
if _, ok := wb.(api.PhaseCurrents); !ok {
if _, ok := api.Cap[api.PhaseCurrents](wb); !ok {
t.Error("missing PhaseCurrents api")
}
if _, ok := wb.(api.Identifier); !ok {
if _, ok := api.Cap[api.Identifier](wb); !ok {
t.Error("missing Identifier api")
}
}
@ -66,23 +66,23 @@ func TestGoEV2(t *testing.T) {
t.Error(err)
}
if _, ok := wb.(api.Meter); !ok {
if _, ok := api.Cap[api.Meter](wb); !ok {
t.Error("missing Meter api")
}
if _, ok := wb.(api.PhaseCurrents); !ok {
if _, ok := api.Cap[api.PhaseCurrents](wb); !ok {
t.Error("missing PhaseCurrents api")
}
if _, ok := wb.(api.Identifier); !ok {
if _, ok := api.Cap[api.Identifier](wb); !ok {
t.Error("missing Identifier api")
}
if _, ok := wb.(api.MeterEnergy); !ok {
if _, ok := api.Cap[api.MeterEnergy](wb); !ok {
t.Error("missing MeterEnergy api")
}
if _, ok := wb.(api.PhaseSwitcher); !ok {
if _, ok := api.Cap[api.PhaseSwitcher](wb); !ok {
t.Error("missing PhaseSwitcher api")
}
}

View file

@ -3,270 +3,49 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateSalia(base *Salia, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case meter == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateSaliaMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateSaliaMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateSaliaPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateSaliaPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateSaliaPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseSwitcher == nil:
return &struct {
return &decorateSaliaCapable{Salia: base, caps: caps}
}
type decorateSaliaCapable struct {
*Salia
api.Meter
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseSwitcher == nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseSwitcher == nil:
return &struct {
*Salia
api.Meter
api.PhaseCurrents
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseSwitcher == nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Salia
api.PhaseSwitcher
}{
Salia: base,
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.PhaseCurrents
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Salia
api.PhaseGetter
api.PhaseSwitcher
}{
Salia: base,
PhaseGetter: &decorateSaliaPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.PhaseGetter
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
PhaseGetter: &decorateSaliaPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
api.PhaseGetter
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseGetter: &decorateSaliaPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.PhaseCurrents
api.PhaseGetter
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseGetter: &decorateSaliaPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Salia
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseGetter
api.PhaseSwitcher
}{
Salia: base,
Meter: &decorateSaliaMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSaliaMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateSaliaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseGetter: &decorateSaliaPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSaliaPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateSaliaCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateSaliaMeterImpl struct {

View file

@ -3,144 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateHeatpump(base *Heatpump, meter func() (float64, error), meterEnergy func() (float64, error), battery func() (float64, error), socLimiter func() (int64, error)) api.Charger {
switch {
case battery == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateHeatpumpMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateHeatpumpMeterEnergyImpl{meterEnergy: meterEnergy}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateHeatpumpBatteryImpl{battery: battery}
}
if socLimiter != nil {
caps[reflect.TypeFor[api.SocLimiter]()] = &decorateHeatpumpSocLimiterImpl{socLimiter: socLimiter}
}
if len(caps) == 0 {
return base
}
case battery == nil && meter != nil && meterEnergy == nil:
return &struct {
return &decorateHeatpumpCapable{Heatpump: base, caps: caps}
}
type decorateHeatpumpCapable struct {
*Heatpump
api.Meter
}{
Heatpump: base,
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case battery == nil && meter != nil && meterEnergy != nil:
return &struct {
*Heatpump
api.Meter
api.MeterEnergy
}{
Heatpump: base,
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHeatpumpMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && meter == nil && socLimiter == nil:
return &struct {
*Heatpump
api.Battery
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
}
case battery != nil && meter != nil && meterEnergy == nil && socLimiter == nil:
return &struct {
*Heatpump
api.Battery
api.Meter
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
}
case battery != nil && meter != nil && meterEnergy != nil && socLimiter == nil:
return &struct {
*Heatpump
api.Battery
api.Meter
api.MeterEnergy
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHeatpumpMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && meter == nil && socLimiter != nil:
return &struct {
*Heatpump
api.Battery
api.SocLimiter
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
SocLimiter: &decorateHeatpumpSocLimiterImpl{
socLimiter: socLimiter,
},
}
case battery != nil && meter != nil && meterEnergy == nil && socLimiter != nil:
return &struct {
*Heatpump
api.Battery
api.Meter
api.SocLimiter
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
SocLimiter: &decorateHeatpumpSocLimiterImpl{
socLimiter: socLimiter,
},
}
case battery != nil && meter != nil && meterEnergy != nil && socLimiter != nil:
return &struct {
*Heatpump
api.Battery
api.Meter
api.MeterEnergy
api.SocLimiter
}{
Heatpump: base,
Battery: &decorateHeatpumpBatteryImpl{
battery: battery,
},
Meter: &decorateHeatpumpMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHeatpumpMeterEnergyImpl{
meterEnergy: meterEnergy,
},
SocLimiter: &decorateHeatpumpSocLimiterImpl{
socLimiter: socLimiter,
},
}
}
return nil
func (d *decorateHeatpumpCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateHeatpumpBatteryImpl struct {

View file

@ -3,152 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateHomeAssistant(base *HomeAssistant, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateHomeAssistantMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateHomeAssistantMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateHomeAssistantPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateHomeAssistantPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
return &decorateHomeAssistantCapable{HomeAssistant: base, caps: caps}
}
type decorateHomeAssistantCapable struct {
*HomeAssistant
api.Meter
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Meter
api.MeterEnergy
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Meter
api.PhaseCurrents
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*HomeAssistant
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Meter
api.PhaseVoltages
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*HomeAssistant
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
HomeAssistant: base,
Meter: &decorateHomeAssistantMeterImpl{
meter: meter,
},
MeterEnergy: &decorateHomeAssistantMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateHomeAssistantPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateHomeAssistantPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateHomeAssistantCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateHomeAssistantMeterImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateInnogy(base *Innogy, meterEnergy func() (float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Charger {
switch {
case meterEnergy == nil && phaseVoltages == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateInnogyMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateInnogyPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if len(caps) == 0 {
return base
}
case meterEnergy != nil && phaseVoltages == nil:
return &struct {
return &decorateInnogyCapable{Innogy: base, caps: caps}
}
type decorateInnogyCapable struct {
*Innogy
api.MeterEnergy
}{
Innogy: base,
MeterEnergy: &decorateInnogyMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case meterEnergy == nil && phaseVoltages != nil:
return &struct {
*Innogy
api.PhaseVoltages
}{
Innogy: base,
PhaseVoltages: &decorateInnogyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy != nil && phaseVoltages != nil:
return &struct {
*Innogy
api.MeterEnergy
api.PhaseVoltages
}{
Innogy: base,
MeterEnergy: &decorateInnogyMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateInnogyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateInnogyCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateInnogyMeterEnergyImpl struct {

File diff suppressed because it is too large Load diff

View file

@ -3,76 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateKebaUdp(base *KebaUdp, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateKebaUdpMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateKebaUdpMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateKebaUdpPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil:
return &struct {
return &decorateKebaUdpCapable{KebaUdp: base, caps: caps}
}
type decorateKebaUdpCapable struct {
*KebaUdp
api.Meter
}{
KebaUdp: base,
Meter: &decorateKebaUdpMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil:
return &struct {
*KebaUdp
api.Meter
api.MeterEnergy
}{
KebaUdp: base,
Meter: &decorateKebaUdpMeterImpl{
meter: meter,
},
MeterEnergy: &decorateKebaUdpMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil:
return &struct {
*KebaUdp
api.Meter
api.PhaseCurrents
}{
KebaUdp: base,
Meter: &decorateKebaUdpMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateKebaUdpPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil:
return &struct {
*KebaUdp
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
KebaUdp: base,
Meter: &decorateKebaUdpMeterImpl{
meter: meter,
},
MeterEnergy: &decorateKebaUdpMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateKebaUdpPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decorateKebaUdpCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateKebaUdpMeterImpl struct {

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateKSE(base *KSE, phaseSwitcher func(int) error, phaseGetter func() (int, error), identifier func() (string, error)) api.Charger {
switch {
case identifier == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateKSEPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateKSEPhaseGetterImpl{phaseGetter: phaseGetter}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateKSEIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case identifier == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateKSECapable{KSE: base, caps: caps}
}
type decorateKSECapable struct {
*KSE
api.PhaseSwitcher
}{
KSE: base,
PhaseSwitcher: &decorateKSEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case identifier == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*KSE
api.PhaseGetter
api.PhaseSwitcher
}{
KSE: base,
PhaseGetter: &decorateKSEPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateKSEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case identifier != nil && phaseSwitcher == nil:
return &struct {
*KSE
api.Identifier
}{
KSE: base,
Identifier: &decorateKSEIdentifierImpl{
identifier: identifier,
},
}
case identifier != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*KSE
api.Identifier
api.PhaseSwitcher
}{
KSE: base,
Identifier: &decorateKSEIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateKSEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case identifier != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*KSE
api.Identifier
api.PhaseGetter
api.PhaseSwitcher
}{
KSE: base,
Identifier: &decorateKSEIdentifierImpl{
identifier: identifier,
},
PhaseGetter: &decorateKSEPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateKSEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateKSECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateKSEIdentifierImpl struct {

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateMennekesCompact(base *MennekesCompact, phaseSwitcher func(int) error) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateMennekesCompactPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case phaseSwitcher != nil:
return &struct {
return &decorateMennekesCompactCapable{MennekesCompact: base, caps: caps}
}
type decorateMennekesCompactCapable struct {
*MennekesCompact
api.PhaseSwitcher
}{
MennekesCompact: base,
PhaseSwitcher: &decorateMennekesCompactPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateMennekesCompactCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateMennekesCompactPhaseSwitcherImpl struct {

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateNRGKickGen2(base *NRGKickGen2, phaseSwitcher func(int) error) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateNRGKickGen2PhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case phaseSwitcher != nil:
return &struct {
return &decorateNRGKickGen2Capable{NRGKickGen2: base, caps: caps}
}
type decorateNRGKickGen2Capable struct {
*NRGKickGen2
api.PhaseSwitcher
}{
NRGKickGen2: base,
PhaseSwitcher: &decorateNRGKickGen2PhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateNRGKickGen2Capable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateNRGKickGen2PhaseSwitcherImpl struct {

File diff suppressed because it is too large Load diff

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateOpenEVSE(base *OpenEVSE, phaseSwitcher func(int) error) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateOpenEVSEPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case phaseSwitcher != nil:
return &struct {
return &decorateOpenEVSECapable{OpenEVSE: base, caps: caps}
}
type decorateOpenEVSECapable struct {
*OpenEVSE
api.PhaseSwitcher
}{
OpenEVSE: base,
PhaseSwitcher: &decorateOpenEVSEPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateOpenEVSECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateOpenEVSEPhaseSwitcherImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateOpenWB20(base *OpenWB20, phaseSwitcher func(int) error, identifier func() (string, error)) api.Charger {
switch {
case identifier == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateOpenWB20PhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateOpenWB20IdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case identifier == nil && phaseSwitcher != nil:
return &struct {
return &decorateOpenWB20Capable{OpenWB20: base, caps: caps}
}
type decorateOpenWB20Capable struct {
*OpenWB20
api.PhaseSwitcher
}{
OpenWB20: base,
PhaseSwitcher: &decorateOpenWB20PhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case identifier != nil && phaseSwitcher == nil:
return &struct {
*OpenWB20
api.Identifier
}{
OpenWB20: base,
Identifier: &decorateOpenWB20IdentifierImpl{
identifier: identifier,
},
}
case identifier != nil && phaseSwitcher != nil:
return &struct {
*OpenWB20
api.Identifier
api.PhaseSwitcher
}{
OpenWB20: base,
Identifier: &decorateOpenWB20IdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateOpenWB20PhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateOpenWB20Capable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateOpenWB20IdentifierImpl struct {

View file

@ -3,113 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateOpenWbNative(base *OpenWbNative, chargerEx func(float64) error, phaseSwitcher func(int) error, identifier func() (string, error)) api.Charger {
switch {
case chargerEx == nil && identifier == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decorateOpenWbNativeChargerExImpl{chargerEx: chargerEx}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateOpenWbNativePhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateOpenWbNativeIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case chargerEx != nil && identifier == nil && phaseSwitcher == nil:
return &struct {
return &decorateOpenWbNativeCapable{OpenWbNative: base, caps: caps}
}
type decorateOpenWbNativeCapable struct {
*OpenWbNative
api.ChargerEx
}{
OpenWbNative: base,
ChargerEx: &decorateOpenWbNativeChargerExImpl{
chargerEx: chargerEx,
},
caps map[reflect.Type]any
}
case chargerEx == nil && identifier == nil && phaseSwitcher != nil:
return &struct {
*OpenWbNative
api.PhaseSwitcher
}{
OpenWbNative: base,
PhaseSwitcher: &decorateOpenWbNativePhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx != nil && identifier == nil && phaseSwitcher != nil:
return &struct {
*OpenWbNative
api.ChargerEx
api.PhaseSwitcher
}{
OpenWbNative: base,
ChargerEx: &decorateOpenWbNativeChargerExImpl{
chargerEx: chargerEx,
},
PhaseSwitcher: &decorateOpenWbNativePhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx == nil && identifier != nil && phaseSwitcher == nil:
return &struct {
*OpenWbNative
api.Identifier
}{
OpenWbNative: base,
Identifier: &decorateOpenWbNativeIdentifierImpl{
identifier: identifier,
},
}
case chargerEx != nil && identifier != nil && phaseSwitcher == nil:
return &struct {
*OpenWbNative
api.ChargerEx
api.Identifier
}{
OpenWbNative: base,
ChargerEx: &decorateOpenWbNativeChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateOpenWbNativeIdentifierImpl{
identifier: identifier,
},
}
case chargerEx == nil && identifier != nil && phaseSwitcher != nil:
return &struct {
*OpenWbNative
api.Identifier
api.PhaseSwitcher
}{
OpenWbNative: base,
Identifier: &decorateOpenWbNativeIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateOpenWbNativePhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargerEx != nil && identifier != nil && phaseSwitcher != nil:
return &struct {
*OpenWbNative
api.ChargerEx
api.Identifier
api.PhaseSwitcher
}{
OpenWbNative: base,
ChargerEx: &decorateOpenWbNativeChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decorateOpenWbNativeIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateOpenWbNativePhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateOpenWbNativeCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateOpenWbNativeChargerExImpl struct {

View file

@ -99,7 +99,7 @@ func NewOpenWbNative(ctx context.Context, uri, device, comset string, baudrate i
maxCurrentMillis func(float64) error
)
if ex, ok := evse.(api.ChargerEx); ok {
if ex, ok := api.Cap[api.ChargerEx](evse); ok {
maxCurrentMillis = ex.MaxCurrentMillis
}

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateOpenWBPro(base *OpenWBPro, resurrector func() error) api.Charger {
switch {
case resurrector == nil:
caps := make(map[reflect.Type]any)
if resurrector != nil {
caps[reflect.TypeFor[api.Resurrector]()] = &decorateOpenWBProResurrectorImpl{resurrector: resurrector}
}
if len(caps) == 0 {
return base
}
case resurrector != nil:
return &struct {
return &decorateOpenWBProCapable{OpenWBPro: base, caps: caps}
}
type decorateOpenWBProCapable struct {
*OpenWBPro
api.Resurrector
}{
OpenWBPro: base,
Resurrector: &decorateOpenWBProResurrectorImpl{
resurrector: resurrector,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateOpenWBProCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateOpenWBProResurrectorImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateOpenWB(base *OpenWB, phaseSwitcher func(int) error, battery func() (float64, error)) api.Charger {
switch {
case battery == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateOpenWBPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateOpenWBBatteryImpl{battery: battery}
}
if len(caps) == 0 {
return base
}
case battery == nil && phaseSwitcher != nil:
return &struct {
return &decorateOpenWBCapable{OpenWB: base, caps: caps}
}
type decorateOpenWBCapable struct {
*OpenWB
api.PhaseSwitcher
}{
OpenWB: base,
PhaseSwitcher: &decorateOpenWBPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case battery != nil && phaseSwitcher == nil:
return &struct {
*OpenWB
api.Battery
}{
OpenWB: base,
Battery: &decorateOpenWBBatteryImpl{
battery: battery,
},
}
case battery != nil && phaseSwitcher != nil:
return &struct {
*OpenWB
api.Battery
api.PhaseSwitcher
}{
OpenWB: base,
Battery: &decorateOpenWBBatteryImpl{
battery: battery,
},
PhaseSwitcher: &decorateOpenWBPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateOpenWBCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateOpenWBBatteryImpl struct {

View file

@ -3,76 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePCE(base *PCElectric, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decoratePCEMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decoratePCEMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decoratePCEPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil:
return &struct {
return &decoratePCECapable{PCElectric: base, caps: caps}
}
type decoratePCECapable struct {
*PCElectric
api.Meter
}{
PCElectric: base,
Meter: &decoratePCEMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil:
return &struct {
*PCElectric
api.Meter
api.MeterEnergy
}{
PCElectric: base,
Meter: &decoratePCEMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePCEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil:
return &struct {
*PCElectric
api.Meter
api.PhaseCurrents
}{
PCElectric: base,
Meter: &decoratePCEMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePCEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil:
return &struct {
*PCElectric
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PCElectric: base,
Meter: &decoratePCEMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePCEMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePCEPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decoratePCECapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePCEMeterImpl struct {

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePeblar(base *Peblar, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decoratePeblarPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decoratePeblarPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decoratePeblarCapable{Peblar: base, caps: caps}
}
type decoratePeblarCapable struct {
*Peblar
api.PhaseSwitcher
}{
Peblar: base,
PhaseSwitcher: &decoratePeblarPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Peblar
api.PhaseGetter
api.PhaseSwitcher
}{
Peblar: base,
PhaseGetter: &decoratePeblarPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decoratePeblarPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decoratePeblarCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePeblarPhaseGetterImpl struct {

View file

@ -3,152 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePhoenixCharx(base *PhoenixCharx, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decoratePhoenixCharxMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decoratePhoenixCharxMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decoratePhoenixCharxPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decoratePhoenixCharxPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
return &decoratePhoenixCharxCapable{PhoenixCharx: base, caps: caps}
}
type decoratePhoenixCharxCapable struct {
*PhoenixCharx
api.Meter
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixCharx
api.Meter
api.MeterEnergy
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixCharxMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixCharx
api.Meter
api.PhaseCurrents
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixCharxPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixCharx
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixCharxMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixCharxPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixCharx
api.Meter
api.PhaseVoltages
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixCharxPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixCharx
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixCharxMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixCharxPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixCharx
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixCharxPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixCharxPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixCharx
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixCharx: base,
Meter: &decoratePhoenixCharxMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixCharxMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixCharxPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixCharxPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decoratePhoenixCharxCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePhoenixCharxMeterImpl struct {

View file

@ -3,152 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePhoenixEMEth(base *PhoenixEMEth, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error)) api.Charger {
switch {
case meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decoratePhoenixEMEthMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decoratePhoenixEMEthMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decoratePhoenixEMEthPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decoratePhoenixEMEthPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if len(caps) == 0 {
return base
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
return &decoratePhoenixEMEthCapable{PhoenixEMEth: base, caps: caps}
}
type decoratePhoenixEMEthCapable struct {
*PhoenixEMEth
api.Meter
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEMEth
api.Meter
api.MeterEnergy
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEMEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEMEth
api.Meter
api.PhaseCurrents
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEMEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEMEth
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEMEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEMEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEMEth
api.Meter
api.PhaseVoltages
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixEMEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEMEth
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEMEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixEMEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEMEth
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEMEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEMEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEMEth
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEMEth: base,
Meter: &decoratePhoenixEMEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEMEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEMEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEMEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decoratePhoenixEMEthCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePhoenixEMEthMeterImpl struct {

View file

@ -3,725 +3,53 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePhoenixEVEth(base *PhoenixEVEth, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error), chargerEx func(float64) error, identifier func() (string, error)) api.Charger {
switch {
case chargerEx == nil && identifier == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decoratePhoenixEVEthMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decoratePhoenixEVEthMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decoratePhoenixEVEthPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decoratePhoenixEVEthPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decoratePhoenixEVEthChargerExImpl{chargerEx: chargerEx}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decoratePhoenixEVEthIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
return &decoratePhoenixEVEthCapable{PhoenixEVEth: base, caps: caps}
}
type decoratePhoenixEVEthCapable struct {
*PhoenixEVEth
api.Meter
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Meter
api.MeterEnergy
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Meter
api.PhaseCurrents
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Meter
api.PhaseVoltages
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.MeterEnergy
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.PhaseCurrents
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter == nil:
return &struct {
*PhoenixEVEth
api.Identifier
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.MeterEnergy
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.PhaseCurrents
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.PhaseVoltages
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.PhaseCurrents
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*PhoenixEVEth
api.ChargerEx
api.Identifier
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
PhoenixEVEth: base,
ChargerEx: &decoratePhoenixEVEthChargerExImpl{
chargerEx: chargerEx,
},
Identifier: &decoratePhoenixEVEthIdentifierImpl{
identifier: identifier,
},
Meter: &decoratePhoenixEVEthMeterImpl{
meter: meter,
},
MeterEnergy: &decoratePhoenixEVEthMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decoratePhoenixEVEthPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decoratePhoenixEVEthPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decoratePhoenixEVEthCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePhoenixEVEthChargerExImpl struct {

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePulsares(base *Pulsares, phaseSwitcher func(int) error) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decoratePulsaresPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case phaseSwitcher != nil:
return &struct {
return &decoratePulsaresCapable{Pulsares: base, caps: caps}
}
type decoratePulsaresCapable struct {
*Pulsares
api.PhaseSwitcher
}{
Pulsares: base,
PhaseSwitcher: &decoratePulsaresPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decoratePulsaresCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePulsaresPhaseSwitcherImpl struct {

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateSEMP(base *SEMP, phaseSwitcher func(int) error, phaseGetter func() (int, error), chargeRater func() (float64, error)) api.Charger {
switch {
case chargeRater == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateSEMPPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateSEMPPhaseGetterImpl{phaseGetter: phaseGetter}
}
if chargeRater != nil {
caps[reflect.TypeFor[api.ChargeRater]()] = &decorateSEMPChargeRaterImpl{chargeRater: chargeRater}
}
if len(caps) == 0 {
return base
}
case chargeRater == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateSEMPCapable{SEMP: base, caps: caps}
}
type decorateSEMPCapable struct {
*SEMP
api.PhaseSwitcher
}{
SEMP: base,
PhaseSwitcher: &decorateSEMPPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case chargeRater == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*SEMP
api.PhaseGetter
api.PhaseSwitcher
}{
SEMP: base,
PhaseGetter: &decorateSEMPPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSEMPPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargeRater != nil && phaseSwitcher == nil:
return &struct {
*SEMP
api.ChargeRater
}{
SEMP: base,
ChargeRater: &decorateSEMPChargeRaterImpl{
chargeRater: chargeRater,
},
}
case chargeRater != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*SEMP
api.ChargeRater
api.PhaseSwitcher
}{
SEMP: base,
ChargeRater: &decorateSEMPChargeRaterImpl{
chargeRater: chargeRater,
},
PhaseSwitcher: &decorateSEMPPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case chargeRater != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*SEMP
api.ChargeRater
api.PhaseGetter
api.PhaseSwitcher
}{
SEMP: base,
ChargeRater: &decorateSEMPChargeRaterImpl{
chargeRater: chargeRater,
},
PhaseGetter: &decorateSEMPPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSEMPPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateSEMPCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateSEMPChargeRaterImpl struct {

View file

@ -281,7 +281,7 @@ func TestSEMPCharger(t *testing.T) {
handler.requestCount = 0
// Reset cache to force new request
wb.(*SEMP).deviceG.Reset()
meter, ok := wb.(api.Meter)
meter, ok := api.Cap[api.Meter](wb)
require.True(t, ok)
power, err := meter.CurrentPower()
require.NoError(t, err)
@ -339,7 +339,7 @@ func TestSEMPChargerOff(t *testing.T) {
})
t.Run("CurrentPowerZero", func(t *testing.T) {
meter, ok := wb.(api.Meter)
meter, ok := api.Cap[api.Meter](wb)
require.True(t, ok)
power, err := meter.CurrentPower()
require.NoError(t, err)
@ -405,7 +405,7 @@ func TestSEMPChargerPhases1p3p(t *testing.T) {
require.NoError(t, err)
// Check if the charger supports phase switching
phaseSwitcher, ok := wb.(api.PhaseSwitcher)
phaseSwitcher, ok := api.Cap[api.PhaseSwitcher](wb)
require.True(t, ok, "Expected charger to support phase switching")
t.Run("SwitchTo1Phase", func(t *testing.T) {
@ -449,7 +449,7 @@ func TestSEMPChargerChargedEnergy(t *testing.T) {
require.NoError(t, err)
t.Run("ChargedEnergy", func(t *testing.T) {
chargeRater, ok := wb.(api.ChargeRater)
chargeRater, ok := api.Cap[api.ChargeRater](wb)
require.True(t, ok)
energy, err := chargeRater.ChargedEnergy()
require.NoError(t, err)
@ -472,7 +472,7 @@ func TestSEMPChargerChargedEnergy(t *testing.T) {
require.NoError(t, err)
// ChargeRater interface should NOT be available when parameters are not supported
_, ok := wb2.(api.ChargeRater)
_, ok := api.Cap[api.ChargeRater](wb2)
assert.False(t, ok, "ChargeRater should not be available when device doesn't support parameters")
})
}

View file

@ -3,144 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateSgReady(base *SgReady, meter func() (float64, error), meterEnergy func() (float64, error), battery func() (float64, error), socLimiter func() (int64, error)) api.Charger {
switch {
case battery == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateSgReadyMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateSgReadyMeterEnergyImpl{meterEnergy: meterEnergy}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateSgReadyBatteryImpl{battery: battery}
}
if socLimiter != nil {
caps[reflect.TypeFor[api.SocLimiter]()] = &decorateSgReadySocLimiterImpl{socLimiter: socLimiter}
}
if len(caps) == 0 {
return base
}
case battery == nil && meter != nil && meterEnergy == nil:
return &struct {
return &decorateSgReadyCapable{SgReady: base, caps: caps}
}
type decorateSgReadyCapable struct {
*SgReady
api.Meter
}{
SgReady: base,
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case battery == nil && meter != nil && meterEnergy != nil:
return &struct {
*SgReady
api.Meter
api.MeterEnergy
}{
SgReady: base,
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSgReadyMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && meter == nil && socLimiter == nil:
return &struct {
*SgReady
api.Battery
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
}
case battery != nil && meter != nil && meterEnergy == nil && socLimiter == nil:
return &struct {
*SgReady
api.Battery
api.Meter
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
}
case battery != nil && meter != nil && meterEnergy != nil && socLimiter == nil:
return &struct {
*SgReady
api.Battery
api.Meter
api.MeterEnergy
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSgReadyMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && meter == nil && socLimiter != nil:
return &struct {
*SgReady
api.Battery
api.SocLimiter
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
SocLimiter: &decorateSgReadySocLimiterImpl{
socLimiter: socLimiter,
},
}
case battery != nil && meter != nil && meterEnergy == nil && socLimiter != nil:
return &struct {
*SgReady
api.Battery
api.Meter
api.SocLimiter
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
SocLimiter: &decorateSgReadySocLimiterImpl{
socLimiter: socLimiter,
},
}
case battery != nil && meter != nil && meterEnergy != nil && socLimiter != nil:
return &struct {
*SgReady
api.Battery
api.Meter
api.MeterEnergy
api.SocLimiter
}{
SgReady: base,
Battery: &decorateSgReadyBatteryImpl{
battery: battery,
},
Meter: &decorateSgReadyMeterImpl{
meter: meter,
},
MeterEnergy: &decorateSgReadyMeterEnergyImpl{
meterEnergy: meterEnergy,
},
SocLimiter: &decorateSgReadySocLimiterImpl{
socLimiter: socLimiter,
},
}
}
return nil
func (d *decorateSgReadyCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateSgReadyBatteryImpl struct {

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateShelly(base *Shelly, phaseVoltages func() (float64, float64, float64, error), phaseCurrents func() (float64, float64, float64, error), phasePowers func() (float64, float64, float64, error)) api.Charger {
switch {
case phaseCurrents == nil && phaseVoltages == nil:
caps := make(map[reflect.Type]any)
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateShellyPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateShellyPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phasePowers != nil {
caps[reflect.TypeFor[api.PhasePowers]()] = &decorateShellyPhasePowersImpl{phasePowers: phasePowers}
}
if len(caps) == 0 {
return base
}
case phaseCurrents == nil && phaseVoltages != nil:
return &struct {
return &decorateShellyCapable{Shelly: base, caps: caps}
}
type decorateShellyCapable struct {
*Shelly
api.PhaseVoltages
}{
Shelly: base,
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
caps map[reflect.Type]any
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages == nil:
return &struct {
*Shelly
api.PhaseCurrents
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages != nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhaseVoltages
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages == nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhasePowers
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateShellyPhasePowersImpl{
phasePowers: phasePowers,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages != nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhasePowers
api.PhaseVoltages
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateShellyPhasePowersImpl{
phasePowers: phasePowers,
},
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateShellyCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateShellyPhaseCurrentsImpl struct {

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateSolax(base *Solax, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateSolaxPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateSolaxPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateSolaxCapable{Solax: base, caps: caps}
}
type decorateSolaxCapable struct {
*Solax
api.PhaseSwitcher
}{
Solax: base,
PhaseSwitcher: &decorateSolaxPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Solax
api.PhaseGetter
api.PhaseSwitcher
}{
Solax: base,
PhaseGetter: &decorateSolaxPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateSolaxPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateSolaxCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateSolaxPhaseGetterImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateSwitchSocket(base *SwitchSocket, meterEnergy func() (float64, error), battery func() (float64, error)) api.Charger {
switch {
case battery == nil && meterEnergy == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateSwitchSocketMeterEnergyImpl{meterEnergy: meterEnergy}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateSwitchSocketBatteryImpl{battery: battery}
}
if len(caps) == 0 {
return base
}
case battery == nil && meterEnergy != nil:
return &struct {
return &decorateSwitchSocketCapable{SwitchSocket: base, caps: caps}
}
type decorateSwitchSocketCapable struct {
*SwitchSocket
api.MeterEnergy
}{
SwitchSocket: base,
MeterEnergy: &decorateSwitchSocketMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case battery != nil && meterEnergy == nil:
return &struct {
*SwitchSocket
api.Battery
}{
SwitchSocket: base,
Battery: &decorateSwitchSocketBatteryImpl{
battery: battery,
},
}
case battery != nil && meterEnergy != nil:
return &struct {
*SwitchSocket
api.Battery
api.MeterEnergy
}{
SwitchSocket: base,
Battery: &decorateSwitchSocketBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateSwitchSocketMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
}
return nil
func (d *decorateSwitchSocketCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateSwitchSocketBatteryImpl struct {

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateTasmota(base *Tasmota, phaseVoltages func() (float64, float64, float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Charger {
switch {
case phaseCurrents == nil && phaseVoltages == nil:
caps := make(map[reflect.Type]any)
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateTasmotaPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateTasmotaPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case phaseCurrents == nil && phaseVoltages != nil:
return &struct {
return &decorateTasmotaCapable{Tasmota: base, caps: caps}
}
type decorateTasmotaCapable struct {
*Tasmota
api.PhaseVoltages
}{
Tasmota: base,
PhaseVoltages: &decorateTasmotaPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
caps map[reflect.Type]any
}
case phaseCurrents != nil && phaseVoltages == nil:
return &struct {
*Tasmota
api.PhaseCurrents
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case phaseCurrents != nil && phaseVoltages != nil:
return &struct {
*Tasmota
api.PhaseCurrents
api.PhaseVoltages
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateTasmotaPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateTasmotaCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateTasmotaPhaseCurrentsImpl struct {

View file

@ -118,7 +118,7 @@ func (c *Twc3) Enable(enable bool) error {
return nil
}
v, ok := c.lp.GetVehicle().(api.ChargeController)
v, ok := api.Cap[api.ChargeController](c.lp.GetVehicle())
if !ok {
return errors.New("vehicle not capable of start/stop")
}
@ -137,7 +137,7 @@ func (c *Twc3) MaxCurrent(current int64) error {
return ErrLoadpointNotInitialized
}
v, ok := c.lp.GetVehicle().(api.CurrentController)
v, ok := api.Cap[api.CurrentController](c.lp.GetVehicle())
if !ok {
return errors.New("vehicle not capable of current control")
}
@ -149,7 +149,7 @@ var _ api.CurrentGetter = (*Twc3)(nil)
// GetMaxCurrent implements the api.CurrentGetter interface
func (c *Twc3) GetMaxCurrent() (float64, error) {
v, ok := c.lp.GetVehicle().(api.CurrentGetter)
v, ok := api.Cap[api.CurrentGetter](c.lp.GetVehicle())
if !ok {
return 0, api.ErrNotAvailable
}

View file

@ -3,53 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateVaillant(base *Vaillant, meter func() (float64, error), battery func() (float64, error)) api.Charger {
switch {
case battery == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateVaillantMeterImpl{meter: meter}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateVaillantBatteryImpl{battery: battery}
}
if len(caps) == 0 {
return base
}
case battery == nil && meter != nil:
return &struct {
return &decorateVaillantCapable{Vaillant: base, caps: caps}
}
type decorateVaillantCapable struct {
*Vaillant
api.Meter
}{
Vaillant: base,
Meter: &decorateVaillantMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case battery != nil && meter == nil:
return &struct {
*Vaillant
api.Battery
}{
Vaillant: base,
Battery: &decorateVaillantBatteryImpl{
battery: battery,
},
}
case battery != nil && meter != nil:
return &struct {
*Vaillant
api.Battery
api.Meter
}{
Vaillant: base,
Battery: &decorateVaillantBatteryImpl{
battery: battery,
},
Meter: &decorateVaillantMeterImpl{
meter: meter,
},
}
}
return nil
func (d *decorateVaillantCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateVaillantBatteryImpl struct {

View file

@ -55,7 +55,7 @@ func (c *VehicleApi) isVehicleAtHome(vehicle api.Vehicle) (bool, error) {
return true, nil // Assume at charger if geofencing is disabled
}
v, ok := vehicle.(api.VehiclePosition)
v, ok := api.Cap[api.VehiclePosition](vehicle)
if !ok {
return false, errors.New("vehicle must support position tracking if geofence is enabled")
}
@ -97,7 +97,7 @@ func (c *VehicleApi) Status() (api.ChargeStatus, error) {
}
}
v, ok := vehicle.(api.ChargeState)
v, ok := api.Cap[api.ChargeState](vehicle)
if !ok {
return api.StatusA, errors.New("vehicle not capable of reporting charging status")
}
@ -136,7 +136,7 @@ func (c *VehicleApi) Enable(enable bool) error {
return nil
}
v, ok := c.lp.GetVehicle().(api.ChargeController)
v, ok := api.Cap[api.ChargeController](c.lp.GetVehicle())
if !ok {
return errors.New("vehicle not capable of start/stop")
}
@ -158,7 +158,7 @@ func (c *VehicleApi) MaxCurrent(current int64) error {
return ErrLoadpointNotInitialized
}
v, ok := c.lp.GetVehicle().(api.CurrentController)
v, ok := api.Cap[api.CurrentController](c.lp.GetVehicle())
if !ok {
// If we cannot control the current, we just pretend that we do
return nil
@ -175,7 +175,7 @@ func (c *VehicleApi) WakeUp() error {
return ErrLoadpointNotInitialized
}
v, ok := c.lp.GetVehicle().(api.Resurrector)
v, ok := api.Cap[api.Resurrector](c.lp.GetVehicle())
if !ok {
return nil
}

View file

@ -3,87 +3,41 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateVestel(base *Vestel, phaseSwitcher func(int) error, phaseGetter func() (int, error), identifier func() (string, error)) api.Charger {
switch {
case identifier == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateVestelPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateVestelPhaseGetterImpl{phaseGetter: phaseGetter}
}
if identifier != nil {
caps[reflect.TypeFor[api.Identifier]()] = &decorateVestelIdentifierImpl{identifier: identifier}
}
if len(caps) == 0 {
return base
}
case identifier == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateVestelCapable{Vestel: base, caps: caps}
}
type decorateVestelCapable struct {
*Vestel
api.PhaseSwitcher
}{
Vestel: base,
PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case identifier == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Vestel
api.PhaseGetter
api.PhaseSwitcher
}{
Vestel: base,
PhaseGetter: &decorateVestelPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case identifier != nil && phaseSwitcher == nil:
return &struct {
*Vestel
api.Identifier
}{
Vestel: base,
Identifier: &decorateVestelIdentifierImpl{
identifier: identifier,
},
}
case identifier != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
*Vestel
api.Identifier
api.PhaseSwitcher
}{
Vestel: base,
Identifier: &decorateVestelIdentifierImpl{
identifier: identifier,
},
PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case identifier != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Vestel
api.Identifier
api.PhaseGetter
api.PhaseSwitcher
}{
Vestel: base,
Identifier: &decorateVestelIdentifierImpl{
identifier: identifier,
},
PhaseGetter: &decorateVestelPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateVestelPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateVestelCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateVestelIdentifierImpl struct {

View file

@ -3,42 +3,37 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateVictron(base *Victron, phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateVictronPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateVictronPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case phaseGetter == nil && phaseSwitcher != nil:
return &struct {
return &decorateVictronCapable{Victron: base, caps: caps}
}
type decorateVictronCapable struct {
*Victron
api.PhaseSwitcher
}{
Victron: base,
PhaseSwitcher: &decorateVictronPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
caps map[reflect.Type]any
}
case phaseGetter != nil && phaseSwitcher != nil:
return &struct {
*Victron
api.PhaseGetter
api.PhaseSwitcher
}{
Victron: base,
PhaseGetter: &decorateVictronPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateVictronPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateVictronCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateVictronPhaseGetterImpl struct {

View file

@ -3,163 +3,45 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateWallbe(base *Wallbe, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), chargerEx func(float64) error) api.Charger {
switch {
case chargerEx == nil && meter == nil:
caps := make(map[reflect.Type]any)
if meter != nil {
caps[reflect.TypeFor[api.Meter]()] = &decorateWallbeMeterImpl{meter: meter}
}
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateWallbeMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateWallbePhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if chargerEx != nil {
caps[reflect.TypeFor[api.ChargerEx]()] = &decorateWallbeChargerExImpl{chargerEx: chargerEx}
}
if len(caps) == 0 {
return base
}
case chargerEx == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil:
return &struct {
return &decorateWallbeCapable{Wallbe: base, caps: caps}
}
type decorateWallbeCapable struct {
*Wallbe
api.Meter
}{
Wallbe: base,
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
caps map[reflect.Type]any
}
case chargerEx == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil:
return &struct {
*Wallbe
api.Meter
api.MeterEnergy
}{
Wallbe: base,
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
MeterEnergy: &decorateWallbeMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil:
return &struct {
*Wallbe
api.Meter
api.PhaseCurrents
}{
Wallbe: base,
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateWallbePhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil:
return &struct {
*Wallbe
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
Wallbe: base,
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
MeterEnergy: &decorateWallbeMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateWallbePhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && meter == nil:
return &struct {
*Wallbe
api.ChargerEx
}{
Wallbe: base,
ChargerEx: &decorateWallbeChargerExImpl{
chargerEx: chargerEx,
},
}
case chargerEx != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil:
return &struct {
*Wallbe
api.ChargerEx
api.Meter
}{
Wallbe: base,
ChargerEx: &decorateWallbeChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
}
case chargerEx != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil:
return &struct {
*Wallbe
api.ChargerEx
api.Meter
api.MeterEnergy
}{
Wallbe: base,
ChargerEx: &decorateWallbeChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
MeterEnergy: &decorateWallbeMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case chargerEx != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil:
return &struct {
*Wallbe
api.ChargerEx
api.Meter
api.PhaseCurrents
}{
Wallbe: base,
ChargerEx: &decorateWallbeChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
PhaseCurrents: &decorateWallbePhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case chargerEx != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil:
return &struct {
*Wallbe
api.ChargerEx
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
Wallbe: base,
ChargerEx: &decorateWallbeChargerExImpl{
chargerEx: chargerEx,
},
Meter: &decorateWallbeMeterImpl{
meter: meter,
},
MeterEnergy: &decorateWallbeMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateWallbePhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decorateWallbeCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateWallbeChargerExImpl struct {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateWeidmüller(base *Weidmüller, meterEnergy func() (float64, error)) api.Charger {
switch {
case meterEnergy == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateWeidmüllerMeterEnergyImpl{meterEnergy: meterEnergy}
}
if len(caps) == 0 {
return base
}
case meterEnergy != nil:
return &struct {
return &decorateWeidmüllerCapable{Weidmüller: base, caps: caps}
}
type decorateWeidmüllerCapable struct {
*Weidmüller
api.MeterEnergy
}{
Weidmüller: base,
MeterEnergy: &decorateWeidmüllerMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateWeidmüllerCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateWeidmüllerMeterEnergyImpl struct {

View file

@ -3,27 +3,33 @@ package charger
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateZaptec(base *Zaptec, phaseSwitcher func(int) error) api.Charger {
switch {
case phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateZaptecPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if len(caps) == 0 {
return base
}
case phaseSwitcher != nil:
return &struct {
return &decorateZaptecCapable{Zaptec: base, caps: caps}
}
type decorateZaptecCapable struct {
*Zaptec
api.PhaseSwitcher
}{
Zaptec: base,
PhaseSwitcher: &decorateZaptecPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateZaptecCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateZaptecPhaseSwitcherImpl struct {

View file

@ -70,7 +70,7 @@ func runCharger(cmd *cobra.Command, args []string) {
log.ERROR.Fatalln(err)
}
if vv, ok := v.(api.ChargerEx); ok {
if vv, ok := api.Cap[api.ChargerEx](v); ok {
if err := vv.MaxCurrentMillis(current); err != nil {
log.ERROR.Println("set current:", err)
}
@ -100,7 +100,7 @@ func runCharger(cmd *cobra.Command, args []string) {
if cmd.Flag(flagWakeup).Changed {
flagUsed = true
if vv, ok := v.(api.Resurrector); ok {
if vv, ok := api.Cap[api.Resurrector](v); ok {
if err := vv.WakeUp(); err != nil {
log.ERROR.Println("wakeup:", err)
}
@ -112,7 +112,7 @@ func runCharger(cmd *cobra.Command, args []string) {
if phases > 0 {
flagUsed = true
if vv, ok := v.(api.PhaseSwitcher); ok {
if vv, ok := api.Cap[api.PhaseSwitcher](v); ok {
if err := vv.Phases1p3p(phases); err != nil {
log.ERROR.Println("set phases:", err)
}

View file

@ -42,7 +42,7 @@ func ramp(c api.Charger, digits int, delay time.Duration) {
for i := 6.0; i <= 16; {
var err error
if cc, ok := c.(api.ChargerEx); ok {
if cc, ok := api.Cap[api.ChargerEx](c); ok {
err = cc.MaxCurrentMillis(i)
} else {
err = c.MaxCurrent(int64(i))
@ -51,7 +51,7 @@ func ramp(c api.Charger, digits int, delay time.Duration) {
time.Sleep(delay)
var p float64
if cc, ok := c.(api.Meter); err == nil && ok {
if cc, ok := api.Cap[api.Meter](c); err == nil && ok {
p, err = cc.CurrentPower()
}
@ -93,7 +93,7 @@ func runChargerRamp(cmd *cobra.Command, args []string) {
chargers := config.Chargers().Devices()
for _, v := range config.Instances(chargers) {
if _, ok := v.(api.ChargerEx); digits > 0 && !ok {
if digits > 0 && !api.HasCap[api.ChargerEx](v) {
log.ERROR.Fatalln("charger does not support mA control")
}
ramp(v, digits, delay)

View file

@ -7,18 +7,14 @@ import (
"fmt"
"go/format"
"io"
"maps"
"os"
"reflect"
"slices"
"strconv"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/evcc-io/evcc/api"
combinations "github.com/mxschmitt/golang-combinations"
"github.com/samber/lo"
"github.com/spf13/pflag"
"golang.org/x/tools/imports"
)
@ -35,7 +31,7 @@ var srcTmpl string
var header string
type funcStruct struct {
Signature, Function, VarName, ReturnTypes string
Signature, Function, VarName, ReturnTypes, BaseType, ShortType string
Params []string
}
@ -45,30 +41,29 @@ type typeStruct struct {
}
var interfaces = make(map[string]reflect.Type)
var dependents = make(map[string][]string)
func init() {
reflectTypes := map[reflect.Type][]reflect.Type{
reflect.TypeFor[api.Meter](): {reflect.TypeFor[api.MeterEnergy](), reflect.TypeFor[api.PhaseCurrents](), reflect.TypeFor[api.PhaseVoltages](), reflect.TypeFor[api.MaxACPowerGetter]()},
reflect.TypeFor[api.PhaseCurrents](): {reflect.TypeFor[api.PhasePowers]()}, // phase powers are only used to determine currents sign
reflect.TypeFor[api.PhaseSwitcher](): {reflect.TypeFor[api.PhaseGetter]()},
reflect.TypeFor[api.Battery](): {reflect.TypeFor[api.BatteryCapacity](), reflect.TypeFor[api.SocLimiter](), reflect.TypeFor[api.BatteryController](), reflect.TypeFor[api.BatterySocLimiter](), reflect.TypeFor[api.BatteryPowerLimiter]()},
reflect.TypeFor[api.ChargeState](): {reflect.TypeFor[api.ChargeController](), reflect.TypeFor[api.CurrentController]()},
reflect.TypeFor[api.CurrentController](): {reflect.TypeFor[api.CurrentGetter]()},
}
for typ, types := range reflectTypes {
interfaces[typ.String()] = typ
for _, t := range types {
interfaces[t.String()] = t
}
dependents[typ.String()] = lo.Map(types, func(typ reflect.Type, _ int) string {
return typ.String()
})
}
for _, typ := range []reflect.Type{
reflect.TypeFor[api.BatteryCapacity](),
reflect.TypeFor[api.SocLimiter](),
reflect.TypeFor[api.BatteryController](),
reflect.TypeFor[api.BatterySocLimiter](),
reflect.TypeFor[api.BatteryPowerLimiter](),
reflect.TypeFor[api.PhasePowers](),
reflect.TypeFor[api.PhaseGetter](),
reflect.TypeFor[api.CurrentController](),
reflect.TypeFor[api.ChargeController](),
reflect.TypeFor[api.CurrentController](),
reflect.TypeFor[api.PhaseCurrents](),
reflect.TypeFor[api.PhaseSwitcher](),
reflect.TypeFor[api.Battery](),
reflect.TypeFor[api.ChargeState](),
reflect.TypeFor[api.MeterEnergy](),
reflect.TypeFor[api.PhaseCurrents](),
reflect.TypeFor[api.PhaseVoltages](),
reflect.TypeFor[api.MaxACPowerGetter](),
reflect.TypeFor[api.Meter](),
reflect.TypeFor[api.CurrentGetter](),
reflect.TypeFor[api.Curtailer](),
reflect.TypeFor[api.Resurrector](),
reflect.TypeFor[api.VehicleOdometer](),
@ -84,80 +79,17 @@ func init() {
}
}
// hasIntersection returns if the slices intersect
func hasIntersection[T comparable](a, b []T) bool {
for _, el := range a {
if slices.Contains(b, el) {
return true
}
}
return false
}
func getCombinations(combos []string) [][]string {
validCombos := make([][]string, 0)
sortedDependents := slices.Sorted(maps.Keys(dependents))
COMBO:
for _, c := range combinations.All(combos) {
// order the cases for generation
for _, master := range sortedDependents {
details := dependents[master]
// prune combinations where ...
// - master is part of the decorators
// - master is not part of the currently evaluated combination
// - details are part of the currently evaluated combination
// ... and remove details from the combination
if slices.Contains(combos, master) && !slices.Contains(c, master) && hasIntersection(c, details) {
c = lo.Without(c, details...)
if len(c) == 0 {
continue COMBO
}
}
}
// prune duplicates
for _, v := range validCombos {
if slices.Equal(v, c) {
continue COMBO
}
}
validCombos = append(validCombos, c)
}
return validCombos
}
func getTemplate(dtypes []reflect.Type, types map[string]typeStruct, combos []string) *template.Template {
func getTemplate(dtypes []reflect.Type, types map[string]typeStruct) *template.Template {
tmpl, err := template.New("gen").Funcs(sprig.FuncMap()).Funcs(template.FuncMap{
// contains checks if slice contains string
"contains": slices.Contains[[]string, string],
// ordered returns a slice of funcStruct ordered by dynamicType
"ordered": func() []funcStruct {
ordered := make([]funcStruct, 0)
// orderedParams returns a slice of funcStruct ordered by dynamicType
"orderedParams": func() []funcStruct {
orderedParams := make([]funcStruct, 0)
for _, t := range dtypes {
for _, f := range types[getTypeImport(t)].Functions {
ordered = append(ordered, f)
orderedParams = append(orderedParams, f)
}
}
return ordered
},
"requiredType": func(c []string, typ string) bool {
for master, details := range dependents {
// exclude combinations where ...
// - master is part of the decorators
// - master is not part of the currently evaluated combination
// - details are part of the currently evaluated combination
if slices.Contains(combos, master) && !slices.Contains(c, master) && slices.Contains(details, typ) {
return false
}
}
return true
},
"empty": func() []string {
return nil
return orderedParams
},
}).Parse(srcTmpl)
@ -182,13 +114,11 @@ func getTypeImport(t reflect.Type) string {
}
func generate(out io.Writer, functionName, baseType string, dtypes []reflect.Type) error {
var combos []string
types := make(map[string]typeStruct)
for _, t := range dtypes {
lastPart := t.Name()
var funcs []funcStruct
lastPart := t.Name()
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
@ -214,6 +144,8 @@ func generate(out io.Writer, functionName, baseType string, dtypes []reflect.Typ
Function: m.Name,
Params: params,
ReturnTypes: fmt.Sprintf("(%s)", strings.Join(returns, ",")),
BaseType: t.String(),
ShortType: t.Name(),
})
}
@ -222,8 +154,6 @@ func generate(out io.Writer, functionName, baseType string, dtypes []reflect.Typ
ShortType: lastPart,
Functions: funcs,
}
combos = append(combos, getTypeImport(t))
}
returnType := *ret
@ -248,10 +178,9 @@ func generate(out io.Writer, functionName, baseType string, dtypes []reflect.Typ
ShortBase: shortBase,
ReturnType: returnType,
Types: types,
Combinations: getCombinations(combos),
}
return getTemplate(dtypes, types, combos).Execute(out, vars)
return getTemplate(dtypes, types).Execute(out, vars)
}
type decorationSet struct {

View file

@ -1,56 +1,28 @@
{{define "case"}}
{{- $combo := .Combo}}
{{- $prefix := .Prefix}}
{{- $and := false}}
{{- range $typ, $def := .Types}}
{{- if requiredType $combo $typ}}
{{- range $def.Functions}}
{{- if $and}} &&{{else}}{{$and = true}}{{end}} {{.VarName}} {{if contains $combo $typ}}!={{else}}=={{end}} nil
{{- end}}
{{- end}}
{{- end}}:
return &struct {
{{.BaseType}}
{{- range $typ, $def := .Types}}
{{- if contains $combo $typ}}
{{$typ}}
{{- end}}
{{- end}}
}{
{{.ShortBase}}: base,
{{- range $typ, $def := .Types}}
{{- if contains $combo $typ}}
{{$def.ShortType}}: &{{$prefix}}{{$def.ShortType}}Impl{
{{- range $def.Functions}}
{{.VarName}}: {{.VarName}},
{{- end}}
},
{{- end}}
{{- end}}
}
{{- end -}}
func {{.Function}}(base {{.BaseType}}{{range ordered}}, {{.VarName}} {{.Signature}}{{end}}) {{.ReturnType}} {
{{- $basetype := .BaseType}}
{{- $shortbase := .ShortBase}}
{{- $prefix := .Function}}
{{- $types := .Types}}
{{- $and := false}}
switch {
case {{- range $typ, $def := .Types}}
{{- if requiredType empty $typ}}
{{- range $def.Functions}}
{{- if $and}} &&{{else}}{{$and = true}}{{end}} {{.VarName}} == nil
{{- end}}
{{- end}}
{{- end}}:
return base
{{range $combo := .Combinations}}
case {{- template "case" dict "BaseType" $basetype "Prefix" $prefix "ShortBase" $shortbase "Types" $types "Combo" $combo}}
{{end}} }
func {{.Function}}(base {{.BaseType}}{{range orderedParams}}, {{.VarName}} {{.Signature}}{{end}}) {{.ReturnType}} {
caps := make(map[reflect.Type]any)
return nil
{{range orderedParams}}
if {{.VarName}} != nil {
caps[reflect.TypeFor[{{.BaseType}}]()] = &{{$prefix}}{{.ShortType}}Impl{ {{.VarName}}: {{.VarName}} }
}
{{end}}
if len(caps) == 0 {
return base
}
return &{{.Function}}Capable{ {{.ShortBase}}: base, caps: caps}
}
type {{.Function}}Capable struct {
{{.BaseType}}
caps map[reflect.Type]any
}
func (d *{{.Function}}Capable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
{{range $element := .Types -}}

View file

@ -3,87 +3,41 @@ package main
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateTest(base api.Charger, meterEnergy func() (float64, error), phaseSwitcher func(int) error, phaseGetter func() (int, error)) api.Charger {
switch {
case meterEnergy == nil && phaseSwitcher == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateTestMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseSwitcher != nil {
caps[reflect.TypeFor[api.PhaseSwitcher]()] = &decorateTestPhaseSwitcherImpl{phaseSwitcher: phaseSwitcher}
}
if phaseGetter != nil {
caps[reflect.TypeFor[api.PhaseGetter]()] = &decorateTestPhaseGetterImpl{phaseGetter: phaseGetter}
}
if len(caps) == 0 {
return base
}
case meterEnergy != nil && phaseSwitcher == nil:
return &struct {
return &decorateTestCapable{Charger: base, caps: caps}
}
type decorateTestCapable struct {
api.Charger
api.MeterEnergy
}{
Charger: base,
MeterEnergy: &decorateTestMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case meterEnergy == nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
api.Charger
api.PhaseSwitcher
}{
Charger: base,
PhaseSwitcher: &decorateTestPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meterEnergy != nil && phaseGetter == nil && phaseSwitcher != nil:
return &struct {
api.Charger
api.MeterEnergy
api.PhaseSwitcher
}{
Charger: base,
MeterEnergy: &decorateTestMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseSwitcher: &decorateTestPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meterEnergy == nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
api.Charger
api.PhaseGetter
api.PhaseSwitcher
}{
Charger: base,
PhaseGetter: &decorateTestPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateTestPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
case meterEnergy != nil && phaseGetter != nil && phaseSwitcher != nil:
return &struct {
api.Charger
api.MeterEnergy
api.PhaseGetter
api.PhaseSwitcher
}{
Charger: base,
MeterEnergy: &decorateTestMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseGetter: &decorateTestPhaseGetterImpl{
phaseGetter: phaseGetter,
},
PhaseSwitcher: &decorateTestPhaseSwitcherImpl{
phaseSwitcher: phaseSwitcher,
},
}
}
return nil
func (d *decorateTestCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateTestMeterEnergyImpl struct {

View file

@ -1,30 +0,0 @@
package main
import (
"testing"
"github.com/evcc-io/evcc/api"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)
func TestDecorator(t *testing.T) {
ctrl := gomock.NewController(t)
c := api.NewMockCharger(ctrl)
enG := func() (float64, error) { return 0, nil }
phS := func(int) error { return nil }
phG := func() (int, error) { return 0, nil }
_ = enG
_ = phS
_ = phG
assert.NotNil(t, decorateTest(c, nil, nil, nil))
assert.NotNil(t, decorateTest(c, nil, nil, phG))
assert.NotNil(t, decorateTest(c, nil, phS, nil))
assert.NotNil(t, decorateTest(c, nil, phS, phG))
assert.NotNil(t, decorateTest(c, enG, nil, nil))
assert.NotNil(t, decorateTest(c, enG, nil, phG))
assert.NotNil(t, decorateTest(c, enG, phS, nil))
assert.NotNil(t, decorateTest(c, enG, phS, phG))
}

View file

@ -3,5 +3,7 @@ package {{.Package}}
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)

View file

@ -66,7 +66,7 @@ func (d *dumper) Dump(name string, v any) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
var isHeating bool
if fd, ok := v.(api.FeatureDescriber); ok {
if fd, ok := api.Cap[api.FeatureDescriber](v); ok {
isHeating = slices.Contains(fd.Features(), api.Heating)
}
@ -75,7 +75,7 @@ func (d *dumper) Dump(name string, v any) {
// meter
if v, ok := v.(api.Meter); ok {
if v, ok := api.Cap[api.Meter](v); ok {
d.measureTime(w, "Power", func() (string, error) {
power, err := backoff.RetryWithData(func() (float64, error) {
f, err := v.CurrentPower()
@ -85,35 +85,35 @@ func (d *dumper) Dump(name string, v any) {
})
}
if v, ok := v.(api.MeterEnergy); ok {
if v, ok := api.Cap[api.MeterEnergy](v); ok {
d.measureTime(w, "Energy", func() (string, error) {
energy, err := v.TotalEnergy()
return fmt.Sprintf("%.1fkWh", energy), err
})
}
if v, ok := v.(api.PhaseCurrents); ok {
if v, ok := api.Cap[api.PhaseCurrents](v); ok {
d.measureTime(w, "Current L1..L3", func() (string, error) {
i1, i2, i3, err := v.Currents()
return fmt.Sprintf("%.3gA %.3gA %.3gA", i1, i2, i3), err
})
}
if v, ok := v.(api.PhaseVoltages); ok {
if v, ok := api.Cap[api.PhaseVoltages](v); ok {
d.measureTime(w, "Voltage L1..L3", func() (string, error) {
u1, u2, u3, err := v.Voltages()
return fmt.Sprintf("%.3gV %.3gV %.3gV", u1, u2, u3), err
})
}
if v, ok := v.(api.PhasePowers); ok {
if v, ok := api.Cap[api.PhasePowers](v); ok {
d.measureTime(w, "Power L1..L3", func() (string, error) {
p1, p2, p3, err := v.Powers()
return fmt.Sprintf("%.0fW %.0fW %.0fW", p1, p2, p3), err
})
}
if v, ok := v.(api.Battery); ok {
if v, ok := api.Cap[api.Battery](v); ok {
label := "Soc"
format := "%.0f%%"
if isHeating {
@ -144,36 +144,36 @@ func (d *dumper) Dump(name string, v any) {
}
}
if v, ok := v.(api.BatteryCapacity); ok {
if v, ok := api.Cap[api.BatteryCapacity](v); ok {
fmt.Fprintf(w, "Capacity:\t%.1fkWh\t\t\n", v.Capacity())
}
if v, ok := v.(api.BatterySocLimiter); ok {
if v, ok := api.Cap[api.BatterySocLimiter](v); ok {
min, max := v.GetSocLimits()
fmt.Fprintf(w, "Min soc:\t%.0f%%\t\t\n", min)
fmt.Fprintf(w, "Max soc:\t%.0f%%\t\t\n", max)
}
if v, ok := v.(api.BatteryPowerLimiter); ok {
if v, ok := api.Cap[api.BatteryPowerLimiter](v); ok {
charge, discharge := v.GetPowerLimits()
fmt.Fprintf(w, "Charge power:\t%.0fW\t\t\n", charge)
fmt.Fprintf(w, "Discharge power:\t%.0fW\t\t\n", discharge)
}
if v, ok := v.(api.MaxACPowerGetter); ok {
if v, ok := api.Cap[api.MaxACPowerGetter](v); ok {
fmt.Fprintf(w, "Max AC power:\t%.0fW\t\t\n", v.MaxACPower())
}
// charger
if v, ok := v.(api.ChargeState); ok {
if v, ok := api.Cap[api.ChargeState](v); ok {
d.measureTime(w, "Charge status", func() (string, error) {
status, err := v.Status()
return fmt.Sprintf("%v", status), err
})
}
if v, ok := v.(api.StatusReasoner); ok {
if v, ok := api.Cap[api.StatusReasoner](v); ok {
d.measureTime(w, "Status reason", func() (string, error) {
status, err := v.StatusReason()
return fmt.Sprintf("%v", status), err
@ -181,32 +181,32 @@ func (d *dumper) Dump(name string, v any) {
}
// controllable battery
if _, ok := v.(api.BatteryController); ok {
if api.HasCap[api.BatteryController](v) {
fmt.Fprintf(w, "Controllable:\ttrue\t\t\n")
}
if v, ok := v.(api.Charger); ok {
if v, ok := api.Cap[api.Charger](v); ok {
d.measureTime(w, "Enabled", func() (string, error) {
enabled, err := v.Enabled()
return fmt.Sprintf("%t", enabled), err
})
}
if v, ok := v.(api.ChargeRater); ok {
if v, ok := api.Cap[api.ChargeRater](v); ok {
d.measureTime(w, "Charged", func() (string, error) {
energy, err := v.ChargedEnergy()
return fmt.Sprintf("%.1fkWh", energy), err
})
}
if v, ok := v.(api.ChargeTimer); ok {
if v, ok := api.Cap[api.ChargeTimer](v); ok {
d.measureTime(w, "Duration", func() (string, error) {
chargeDuration, err := v.ChargeDuration()
return fmt.Sprintf("%v", chargeDuration.Truncate(time.Second)), err
})
}
if v, ok := v.(api.CurrentLimiter); ok {
if v, ok := api.Cap[api.CurrentLimiter](v); ok {
d.measureTime(w, "Mix/Max Current", func() (string, error) {
min, max, err := v.GetMinMaxCurrent()
return fmt.Sprintf("%.1f/%.1fA", min, max), err
@ -215,42 +215,42 @@ func (d *dumper) Dump(name string, v any) {
// vehicle
if v, ok := v.(api.VehicleRange); ok {
if v, ok := api.Cap[api.VehicleRange](v); ok {
d.measureTime(w, "Range", func() (string, error) {
rng, err := v.Range()
return fmt.Sprintf("%vkm", rng), err
})
}
if v, ok := v.(api.VehicleOdometer); ok {
if v, ok := api.Cap[api.VehicleOdometer](v); ok {
d.measureTime(w, "Odometer", func() (string, error) {
odo, err := v.Odometer()
return fmt.Sprintf("%.0fkm", odo), err
})
}
if v, ok := v.(api.VehicleFinishTimer); ok {
if v, ok := api.Cap[api.VehicleFinishTimer](v); ok {
d.measureTime(w, "Finish time", func() (string, error) {
ft, err := v.FinishTime()
return fmt.Sprintf("%v", ft.Truncate(time.Minute).In(time.Local)), err
})
}
if v, ok := v.(api.VehicleClimater); ok {
if v, ok := api.Cap[api.VehicleClimater](v); ok {
d.measureTime(w, "Climate active", func() (string, error) {
active, err := v.Climater()
return fmt.Sprintf("%v", active), err
})
}
if v, ok := v.(api.VehiclePosition); ok {
if v, ok := api.Cap[api.VehiclePosition](v); ok {
d.measureTime(w, "Position", func() (string, error) {
lat, lon, err := v.Position()
return fmt.Sprintf("%v,%v", lat, lon), err
})
}
if v, ok := v.(api.SocLimiter); ok {
if v, ok := api.Cap[api.SocLimiter](v); ok {
label := "Limit Soc"
format := "%d%%"
if isHeating {
@ -263,7 +263,7 @@ func (d *dumper) Dump(name string, v any) {
})
}
if v, ok := v.(api.Vehicle); ok {
if v, ok := api.Cap[api.Vehicle](v); ok {
if len(v.Identifiers()) > 0 {
fmt.Fprintf(w, "Identifiers:\t%v\t\t\n", v.Identifiers())
}
@ -274,14 +274,14 @@ func (d *dumper) Dump(name string, v any) {
// currents and phases
if v, ok := v.(api.CurrentGetter); ok {
if v, ok := api.Cap[api.CurrentGetter](v); ok {
d.measureTime(w, "Max Current", func() (string, error) {
f, err := v.GetMaxCurrent()
return fmt.Sprintf("%.1fA", f), err
})
}
if v, ok := v.(api.PhaseGetter); ok {
if v, ok := api.Cap[api.PhaseGetter](v); ok {
d.measureTime(w, "Phases", func() (string, error) {
f, err := v.GetPhases()
return fmt.Sprintf("%d", f), err
@ -290,7 +290,7 @@ func (d *dumper) Dump(name string, v any) {
// Identity
if v, ok := v.(api.Identifier); ok {
if v, ok := api.Cap[api.Identifier](v); ok {
d.measureTime(w, "Identifier", func() (string, error) {
id, err := v.Identify()
if err == nil && id == "" {
@ -302,7 +302,7 @@ func (d *dumper) Dump(name string, v any) {
// features
if v, ok := v.(api.FeatureDescriber); ok {
if v, ok := api.Cap[api.FeatureDescriber](v); ok {
if ff := v.Features(); len(ff) > 0 {
fmt.Fprintf(w, "Features:\t%v\t\t\n", ff)
}
@ -318,7 +318,7 @@ func (d *dumper) Dump(name string, v any) {
func (d *dumper) DumpDiagnosis(v any) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
if v, ok := v.(api.Diagnosis); ok {
if v, ok := api.Cap[api.Diagnosis](v); ok {
fmt.Fprintln(w, "Diagnostic dump:")
v.Diagnose()
}

View file

@ -60,7 +60,7 @@ func runMeter(cmd *cobra.Command, args []string) {
flagUsed = true
for _, v := range config.Instances(meters) {
if b, ok := v.(api.BatteryController); ok {
if b, ok := api.Cap[api.BatteryController](v); ok {
if err := b.SetBatteryMode(mode); err != nil {
log.FATAL.Fatalln("set battery mode:", err)
}

View file

@ -72,16 +72,15 @@ func main() {
switch action {
case "wakeup":
switch vv := v.(type) {
case api.Resurrector:
if vv, ok := api.Cap[api.Resurrector](v); ok {
if err := vv.WakeUp(); err != nil {
log.Fatal(err)
}
case api.ChargeController:
} else if vv, ok := api.Cap[api.ChargeController](v); ok {
if err := vv.ChargeEnable(true); err != nil {
log.Fatal(err)
}
default:
} else {
log.Fatal("not supported:", action)
}

View file

@ -64,11 +64,11 @@ func runVehicle(cmd *cobra.Command, args []string) {
if err != nil {
log.ERROR.Println("max current:", err)
} else {
if vv, ok := v.(api.ChargerEx); ok {
if vv, ok := api.Cap[api.ChargerEx](v); ok {
if err := vv.MaxCurrentMillis(f); err != nil {
log.ERROR.Println("max current:", err)
}
} else if vv, ok := v.(api.CurrentController); ok {
} else if vv, ok := api.Cap[api.CurrentController](v); ok {
if err := vv.MaxCurrent(int64(f)); err != nil {
log.ERROR.Println("max current:", err)
}
@ -81,7 +81,7 @@ func runVehicle(cmd *cobra.Command, args []string) {
if cmd.Flag(flagWakeup).Changed {
flagUsed = true
if vv, ok := v.(api.Resurrector); ok {
if vv, ok := api.Cap[api.Resurrector](v); ok {
if err := vv.WakeUp(); err != nil {
log.ERROR.Println("wakeup:", err)
}
@ -93,7 +93,7 @@ func runVehicle(cmd *cobra.Command, args []string) {
if cmd.Flag(flagStart).Changed {
flagUsed = true
if vv, ok := v.(api.ChargeController); ok {
if vv, ok := api.Cap[api.ChargeController](v); ok {
if err := vv.ChargeEnable(true); err != nil {
log.ERROR.Println("start charge:", err)
}
@ -105,7 +105,7 @@ func runVehicle(cmd *cobra.Command, args []string) {
if cmd.Flag(flagStop).Changed {
flagUsed = true
if vv, ok := v.(api.ChargeController); ok {
if vv, ok := api.Cap[api.ChargeController](v); ok {
if err := vv.ChargeEnable(false); err != nil {
log.ERROR.Println("stop charge:", err)
}

View file

@ -121,7 +121,7 @@ func New(log *util.Logger, title string, maxCurrent, maxPower float64, meter api
if maxCurrent == 0 {
c.log.DEBUG.Printf("validation of max phase current disabled")
} else if _, ok := meter.(api.PhaseCurrents); meter != nil && !ok {
} else if meter != nil && !api.HasCap[api.PhaseCurrents](meter) {
return nil, errors.New("meter does not support phase currents")
}
@ -263,7 +263,7 @@ func (c *Circuit) updateMeters() error {
return fmt.Errorf("circuit power: %w", err)
}
if phaseMeter, ok := c.meter.(api.PhaseCurrents); ok {
if phaseMeter, ok := api.Cap[api.PhaseCurrents](c.meter); ok {
var i1, i2, i3 float64
if err := backoff.Retry(func() error {
var err error
@ -275,7 +275,7 @@ func (c *Circuit) updateMeters() error {
}
var p1, p2, p3 float64
if phaseMeter, ok := c.meter.(api.PhasePowers); ok {
if phaseMeter, ok := api.Cap[api.PhasePowers](c.meter); ok {
var err error // phases needed for signed currents
if p1, p2, p3, err = phaseMeter.Powers(); err != nil {
return fmt.Errorf("circuit powers: %w", err)

View file

@ -116,7 +116,7 @@ func (c *Coordinator) availableDetectibleVehicles(owner loadpoint.API) []api.Veh
for _, vv := range c.vehicles {
// status api available
if _, ok := vv.(api.ChargeState); ok {
if api.HasCap[api.ChargeState](vv) {
// available or associated to current loadpoint
if o, ok := c.tracked[vv]; o == owner || !ok {
res = append(res, vv)
@ -135,7 +135,7 @@ func (c *Coordinator) identifyVehicleByStatus(available []api.Vehicle) api.Vehic
defer c.mu.RUnlock()
for _, vehicle := range available {
if vs, ok := vehicle.(api.ChargeState); ok {
if vs, ok := api.Cap[api.ChargeState](vehicle); ok {
status, err := vs.Status()
if err != nil {
if !loadpoint.AcceptableError(err) {

View file

@ -50,7 +50,7 @@ func ptrValueEqual[T comparable](a, b *T) bool {
// hasFeature returns true if features are supported and given feature present
func hasFeature(a any, f api.Feature) bool {
c, ok := a.(api.FeatureDescriber)
c, ok := api.Cap[api.FeatureDescriber](a)
return ok && slices.Contains(c.Features(), f)
}

View file

@ -403,7 +403,7 @@ func (lp *Loadpoint) configureChargerType(charger api.Charger) {
if lp.chargeMeter == nil {
integrated = true
if mt, ok := charger.(api.Meter); ok {
if mt, ok := api.Cap[api.Meter](charger); ok {
lp.chargeMeter = mt
} else {
mt := new(wrapper.ChargeMeter)
@ -416,7 +416,7 @@ func (lp *Loadpoint) configureChargerType(charger api.Charger) {
// ensure charge rater exists
// measurement are obtained from separate charge meter if defined
// (https://github.com/evcc-io/evcc/issues/2469)
if rt, ok := charger.(api.ChargeRater); ok && integrated {
if rt, ok := api.Cap[api.ChargeRater](charger); ok && integrated {
lp.chargeRater = rt
// when restarting in the middle of charging session, use this as negative offset
@ -433,7 +433,7 @@ func (lp *Loadpoint) configureChargerType(charger api.Charger) {
}
// ensure charge timer exists
if ct, ok := charger.(api.ChargeTimer); ok {
if ct, ok := api.Cap[api.ChargeTimer](charger); ok {
lp.chargeTimer = ct
} else {
ct := wrapper.NewChargeTimer()
@ -674,7 +674,7 @@ func (lp *Loadpoint) Prepare(site site.API, uiChan chan<- util.Param, pushChan c
}
// charger icon
if c, ok := lp.charger.(api.IconDescriber); ok {
if c, ok := api.Cap[api.IconDescriber](lp.charger); ok {
lp.publish(keys.ChargerIcon, c.Icon())
} else {
lp.publish(keys.ChargerIcon, nil)
@ -777,7 +777,7 @@ func (lp *Loadpoint) syncCharger() error {
)
// use chargers actual set current if available
cg, isCg := lp.charger.(api.CurrentGetter)
cg, isCg := api.Cap[api.CurrentGetter](lp.charger)
if isCg {
if current, err = cg.GetMaxCurrent(); err == nil {
// smallest adjustment most PWM-Controllers can do is: 100%÷256×0,6A = 0.234A
@ -806,7 +806,7 @@ func (lp *Loadpoint) syncCharger() error {
}
// sync phases
_, isPs := lp.charger.(api.PhaseSwitcher)
_, isPs := api.Cap[api.PhaseSwitcher](lp.charger)
if phases := lp.GetPhases(); isPs && shouldBeConsistent && phases > 0 {
// fallback to active phases from measured phases
chargerPhases := lp.measuredPhases
@ -814,7 +814,7 @@ func (lp *Loadpoint) syncCharger() error {
chargerPhases = 3
}
pg, isPg := lp.charger.(api.PhaseGetter)
pg, isPg := api.Cap[api.PhaseGetter](lp.charger)
if isPg {
if chargerPhases, err = pg.GetPhases(); err == nil {
if chargerPhases > 0 && chargerPhases != phases {
@ -858,8 +858,7 @@ func (lp *Loadpoint) syncCharger() error {
// coarseCurrent returns true if charger or vehicle require full amp steps
func (lp *Loadpoint) coarseCurrent() bool {
_, ok := lp.charger.(api.ChargerEx)
return !ok || lp.vehicleHasFeature(api.CoarseCurrent)
return !api.HasCap[api.ChargerEx](lp.charger) || lp.vehicleHasFeature(api.CoarseCurrent)
}
// roundedCurrent rounds current down to full amps if charger or vehicle require it
@ -902,7 +901,7 @@ func (lp *Loadpoint) setLimit(current float64) error {
// set current
if current != lp.offeredCurrent && current >= effMinCurrent {
var err error
if charger, ok := lp.charger.(api.ChargerEx); ok {
if charger, ok := api.Cap[api.ChargerEx](lp.charger); ok {
err = charger.MaxCurrentMillis(current)
} else {
err = lp.charger.MaxCurrent(int64(current))
@ -910,7 +909,7 @@ func (lp *Loadpoint) setLimit(current float64) error {
if err != nil {
v := lp.GetVehicle()
if vv, ok := v.(api.Resurrector); ok && errors.Is(err, api.ErrAsleep) {
if vv, ok := api.Cap[api.Resurrector](v); ok && errors.Is(err, api.ErrAsleep) {
// https://github.com/evcc-io/evcc/issues/8254
// wakeup vehicle
lp.log.DEBUG.Printf("set charge current limit: waking up vehicle")
@ -931,7 +930,7 @@ func (lp *Loadpoint) setLimit(current float64) error {
if enabled := current >= effMinCurrent; enabled != lp.enabled {
if err := lp.charger.Enable(enabled); err != nil {
v := lp.GetVehicle()
if vv, ok := v.(api.Resurrector); enabled && ok && errors.Is(err, api.ErrAsleep) {
if vv, ok := api.Cap[api.Resurrector](v); enabled && ok && errors.Is(err, api.ErrAsleep) {
// https://github.com/evcc-io/evcc/issues/8254
// wakeup vehicle
lp.log.DEBUG.Printf("charger %s: waking up vehicle", status[enabled])
@ -1140,7 +1139,7 @@ func (lp *Loadpoint) getStatusChanges() ([]api.ChargeStatus, error) {
}
// check charger connection duration
if ct, ok := lp.charger.(api.ConnectionTimer); ok {
if ct, ok := api.Cap[api.ConnectionTimer](lp.charger); ok {
d, err := ct.ConnectionDuration()
if err != nil {
return nil, fmt.Errorf("connection duration: %w", err)
@ -1252,7 +1251,7 @@ func (lp *Loadpoint) scalePhasesIfAvailable(phases int) error {
// scalePhases adjusts the number of active phases and returns the appropriate charging current.
// Returns api.ErrNotAvailable if api.PhaseSwitcher is not available.
func (lp *Loadpoint) scalePhases(phases int) error {
cp, ok := lp.charger.(api.PhaseSwitcher)
cp, ok := api.Cap[api.PhaseSwitcher](lp.charger)
if !ok {
panic("charger does not implement api.PhaseSwitcher")
}
@ -1589,7 +1588,7 @@ func (lp *Loadpoint) UpdateChargePowerAndCurrents() float64 {
// update charge currents
lp.chargeCurrents = nil
if phaseMeter, ok := lp.chargeMeter.(api.PhaseCurrents); ok {
if phaseMeter, ok := api.Cap[api.PhaseCurrents](lp.chargeMeter); ok {
if err := backoff.Retry(func() error {
i1, i2, i3, err := phaseMeter.Currents()
if err != nil {
@ -1642,7 +1641,7 @@ func (lp *Loadpoint) phasesFromChargeCurrents() {
// updateChargeVoltages uses PhaseVoltages interface to count phases with nominal grid voltage
func (lp *Loadpoint) updateChargeVoltages() {
phaseMeter, ok := lp.chargeMeter.(api.PhaseVoltages)
phaseMeter, ok := api.Cap[api.PhaseVoltages](lp.chargeMeter)
if !ok {
return // don't guess
}
@ -1716,7 +1715,7 @@ func (lp *Loadpoint) publishChargeProgress() {
// TODO deprecated: use sessionEnergy instead
lp.publish(keys.ChargedEnergy, lp.GetChargedEnergy())
lp.publish(keys.ChargeDuration, lp.chargeDuration)
if _, ok := lp.chargeMeter.(api.MeterEnergy); ok {
if api.HasCap[api.MeterEnergy](lp.chargeMeter) {
lp.publish(keys.ChargeTotalImport, lp.chargeMeterTotal())
}
}
@ -1739,14 +1738,14 @@ func (lp *Loadpoint) publishSocAndRange() {
var socR *float64
var limitR *int64
if battery, ok := dev.(api.Battery); ok {
if battery, ok := api.Cap[api.Battery](dev); ok {
if soc, err := soc.Guard(battery.Soc()); err == nil {
socR = &soc
// don't publish here in case it needs be updated by the estimator
lp.log.DEBUG.Printf("%s soc: %.0f%%", typ, soc)
if socLimiter, ok := dev.(api.SocLimiter); ok {
if socLimiter, ok := api.Cap[api.SocLimiter](dev); ok {
if limit, err := socLimiter.GetLimitSoc(); err == nil {
limitR = &limit
@ -1771,7 +1770,7 @@ func (lp *Loadpoint) publishSocAndRange() {
socR, limitR = socAndLimit("vehicle", lp.GetVehicle())
// range
if vs, ok := lp.GetVehicle().(api.VehicleRange); ok {
if vs, ok := api.Cap[api.VehicleRange](lp.GetVehicle()); ok {
if rng, err := vs.Range(); err == nil {
lp.log.DEBUG.Printf("vehicle range: %dkm", rng)
lp.publish(keys.VehicleRange, rng)
@ -1915,7 +1914,7 @@ func (lp *Loadpoint) Update(sitePower, batteryBoostPower float64, consumption, f
lp.PublishEffectiveValues()
// §14a
if dimmer, ok := lp.charger.(api.Dimmer); ok {
if dimmer, ok := api.Cap[api.Dimmer](lp.charger); ok {
dimmed, err := dimmer.Dimmed()
if err != nil {
lp.log.ERROR.Printf("dimmed: %v", err)
@ -1952,7 +1951,7 @@ func (lp *Loadpoint) Update(sitePower, batteryBoostPower float64, consumption, f
lp.resetHeatingSession()
if sr, ok := lp.charger.(api.StatusReasoner); ok && lp.GetStatus() == api.StatusB {
if sr, ok := api.Cap[api.StatusReasoner](lp.charger); ok && lp.GetStatus() == api.StatusB {
if r, err := sr.StatusReason(); err == nil {
lp.publish(keys.ChargerStatusReason, r)
} else {

View file

@ -155,7 +155,7 @@ func (lp *Loadpoint) effectiveMinCurrent() float64 {
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if c, ok := api.Cap[api.CurrentLimiter](lp.charger); ok {
if res, _, err := c.GetMinMaxCurrent(); err == nil {
chargerMin = res
}
@ -181,7 +181,7 @@ func (lp *Loadpoint) effectiveMaxCurrent() float64 {
}
}
if c, ok := lp.charger.(api.CurrentLimiter); ok {
if c, ok := api.Cap[api.CurrentLimiter](lp.charger); ok {
if _, res, err := c.GetMinMaxCurrent(); err == nil && res > 0 {
maxCurrent = min(maxCurrent, res)
}

View file

@ -151,7 +151,7 @@ func (lp *Loadpoint) getVehiclePhases() int {
}
func (lp *Loadpoint) getChargerPhysicalPhases() int {
if cc, ok := lp.charger.(api.PhaseDescriber); ok {
if cc, ok := api.Cap[api.PhaseDescriber](lp.charger); ok {
return cc.Phases()
}
@ -159,6 +159,5 @@ func (lp *Loadpoint) getChargerPhysicalPhases() int {
}
func (lp *Loadpoint) hasPhaseSwitching() bool {
_, ok := lp.charger.(api.PhaseSwitcher)
return ok
return api.HasCap[api.PhaseSwitcher](lp.charger)
}

View file

@ -11,7 +11,7 @@ import (
)
func (lp *Loadpoint) chargeMeterTotal() float64 {
m, ok := lp.chargeMeter.(api.MeterEnergy)
m, ok := api.Cap[api.MeterEnergy](lp.chargeMeter)
if !ok {
return 0
}
@ -45,7 +45,7 @@ func (lp *Loadpoint) createSession() {
lp.session.Vehicle = lp.GetTitle()
}
if c, ok := lp.charger.(api.Identifier); ok {
if c, ok := api.Cap[api.Identifier](lp.charger); ok {
if id, err := c.Identify(); err == nil {
lp.session.Identifier = id
}

View file

@ -54,7 +54,7 @@ func (lp *Loadpoint) setVehicleIdentifier(id string) {
// identifyVehicle reads vehicle identification from charger
func (lp *Loadpoint) identifyVehicle() {
identifier, ok := lp.charger.(api.Identifier)
identifier, ok := api.Cap[api.Identifier](lp.charger)
if !ok {
return
}
@ -176,8 +176,8 @@ func (lp *Loadpoint) setActiveVehicle(v api.Vehicle) {
func (lp *Loadpoint) wakeUpVehicle() {
// wake up charger or vehicle. First wakeupAttemptsLeft will be odd.
charger, chargerCanWakeUp := lp.charger.(api.Resurrector)
vehicle, vehicleCanWakeUp := lp.GetVehicle().(api.Resurrector)
charger, chargerCanWakeUp := api.Cap[api.Resurrector](lp.charger)
vehicle, vehicleCanWakeUp := api.Cap[api.Resurrector](lp.GetVehicle())
if lp.wakeUpTimer.wakeupAttemptsLeft%2 != 0 {
if chargerCanWakeUp {
@ -296,14 +296,14 @@ func (lp *Loadpoint) identifyVehicleByStatus() {
}
// remove previous vehicle if status was not confirmed
if _, ok := lp.GetVehicle().(api.ChargeState); ok {
if api.HasCap[api.ChargeState](lp.GetVehicle()) {
lp.setActiveVehicle(nil)
}
}
// vehicleOdometer updates odometer
func (lp *Loadpoint) vehicleOdometer() {
if vs, ok := lp.GetVehicle().(api.VehicleOdometer); ok {
if vs, ok := api.Cap[api.VehicleOdometer](lp.GetVehicle()); ok {
if odo, err := vs.Odometer(); err == nil {
lp.log.DEBUG.Printf("vehicle odometer: %.0fkm", odo)
lp.publish(keys.VehicleOdometer, odo)
@ -361,7 +361,7 @@ func (lp *Loadpoint) vehicleSocPollAllowed() bool {
// vehicleClimateActive checks if vehicle has active climate request
func (lp *Loadpoint) vehicleClimateActive() bool {
if cl, ok := lp.GetVehicle().(api.VehicleClimater); ok && lp.vehicleClimatePollAllowed() {
if cl, ok := api.Cap[api.VehicleClimater](lp.GetVehicle()); ok && lp.vehicleClimatePollAllowed() {
active, err := cl.Climater()
if err == nil {
if active {

View file

@ -346,13 +346,14 @@ func (site *Site) restoreSettings() error {
}
func meterCapabilities(name string, meter any) string {
if _, ok := meter.(api.Meter); !ok {
power := api.HasCap[api.Meter](meter)
if !power {
panic("not a meter: " + name)
}
_, power := meter.(api.Meter)
_, energy := meter.(api.MeterEnergy)
_, currents := meter.(api.PhaseCurrents)
energy := api.HasCap[api.MeterEnergy](meter)
currents := api.HasCap[api.PhaseCurrents](meter)
name += ":"
return fmt.Sprintf(" %-10s power %s energy %s currents %s",
@ -368,7 +369,7 @@ func (site *Site) DumpConfig() {
// verify vehicle detection
if vehicles := site.Vehicles().Instances(); len(vehicles) > 1 {
for _, v := range vehicles {
if _, ok := v.(api.ChargeState); !ok && len(v.Identifiers()) == 0 {
if !api.HasCap[api.ChargeState](v) && len(v.Identifiers()) == 0 {
site.log.INFO.Printf("vehicle '%s' does not support automatic detection", v.GetTitle())
}
}
@ -394,12 +395,12 @@ func (site *Site) DumpConfig() {
if len(site.batteryMeters) > 0 {
for i, dev := range site.batteryMeters {
battery := dev.Instance()
_, ok := battery.(api.Battery)
_, hasCapacity := battery.(api.BatteryCapacity)
isBattery := api.HasCap[api.Battery](battery)
hasCapacity := api.HasCap[api.BatteryCapacity](battery)
site.log.INFO.Println(
meterCapabilities(fmt.Sprintf("battery %d", i+1), battery),
fmt.Sprintf("soc %s capacity %s", presence[ok], presence[hasCapacity]),
fmt.Sprintf("soc %s capacity %s", presence[isBattery], presence[hasCapacity]),
)
}
}
@ -408,11 +409,11 @@ func (site *Site) DumpConfig() {
site.log.INFO.Println(" vehicles:")
for i, v := range vehicles {
_, rng := v.(api.VehicleRange)
_, finish := v.(api.VehicleFinishTimer)
_, status := v.(api.ChargeState)
_, climate := v.(api.VehicleClimater)
_, wakeup := v.(api.Resurrector)
_, rng := api.Cap[api.VehicleRange](v)
_, finish := api.Cap[api.VehicleFinishTimer](v)
_, status := api.Cap[api.ChargeState](v)
_, climate := api.Cap[api.VehicleClimater](v)
_, wakeup := api.Cap[api.Resurrector](v)
site.log.INFO.Printf(" vehicle %d: range %s finish %s status %s climate %s wakeup %s",
i+1, presence[rng], presence[finish], presence[status], presence[climate], presence[wakeup],
)
@ -435,11 +436,11 @@ func (site *Site) DumpConfig() {
lp.log.INFO.Printf("loadpoint %d:", i+1)
lp.log.INFO.Printf(" mode: %s", lp.GetMode())
_, power := lp.charger.(api.Meter)
_, energy := lp.charger.(api.MeterEnergy)
_, currents := lp.charger.(api.PhaseCurrents)
_, phases := lp.charger.(api.PhaseSwitcher)
_, wakeup := lp.charger.(api.Resurrector)
_, power := api.Cap[api.Meter](lp.charger)
_, energy := api.Cap[api.MeterEnergy](lp.charger)
_, currents := api.Cap[api.PhaseCurrents](lp.charger)
_, phases := api.Cap[api.PhaseSwitcher](lp.charger)
_, wakeup := api.Cap[api.Resurrector](lp.charger)
lp.log.INFO.Printf(" charger: power %s energy %s currents %s phases %s wakeup %s",
presence[power],
@ -499,7 +500,7 @@ func (site *Site) collectMeters(key string, meters []config.Device[api.Meter]) [
// energy (production)
var energy float64
if m, ok := meter.(api.MeterEnergy); err == nil && ok {
if m, ok := api.Cap[api.MeterEnergy](meter); err == nil && ok {
energy, err = m.TotalEnergy()
if err != nil {
site.log.ERROR.Printf("%s %d energy: %v", key, i+1, err)
@ -543,7 +544,7 @@ func (site *Site) updatePvMeters() {
site.log.WARN.Printf("pv %d power: %.0fW is negative - check configuration if sign is correct", i+1, power)
}
if m, ok := meter.(api.MaxACPowerGetter); ok {
if m, ok := api.Cap[api.MaxACPowerGetter](meter); ok {
if dc := power - m.MaxACPower(); dc > 0 && power > 0 {
mm[i].ExcessDCPower = dc
site.log.DEBUG.Printf("pv %d excess DC: %.0fW", i+1, dc)
@ -611,13 +612,13 @@ func (site *Site) updateBatteryMeters() {
meter := dev.Instance()
// battery soc and capacity
if m, ok := meter.(api.Battery); ok {
if m, ok := api.Cap[api.Battery](meter); ok {
batSoc, err := soc.Guard(m.Soc())
if err == nil {
mm[i].Soc = new(batSoc)
if m, ok := m.(api.BatteryCapacity); ok {
mm[i].Capacity = new(m.Capacity())
if bc, ok := api.Cap[api.BatteryCapacity](meter); ok {
mm[i].Capacity = new(bc.Capacity())
}
site.log.DEBUG.Printf("battery %d soc: %.0f%%", i+1, batSoc)
@ -626,7 +627,7 @@ func (site *Site) updateBatteryMeters() {
}
}
_, controllable := meter.(api.BatteryController)
_, controllable := api.Cap[api.BatteryController](meter)
mm[i].Controllable = new(controllable)
}
@ -717,10 +718,10 @@ func (site *Site) updateGridMeter() error {
}
// grid phase currents (signed)
if phaseMeter, ok := site.gridMeter.(api.PhaseCurrents); ok {
if phaseMeter, ok := api.Cap[api.PhaseCurrents](site.gridMeter); ok {
// grid phase powers
var p1, p2, p3 float64
if phaseMeter, ok := site.gridMeter.(api.PhasePowers); ok {
if phaseMeter, ok := api.Cap[api.PhasePowers](site.gridMeter); ok {
var err error // phases needed for signed currents
if p1, p2, p3, err = phaseMeter.Powers(); err == nil {
mm.Powers = []float64{p1, p2, p3}
@ -739,7 +740,7 @@ func (site *Site) updateGridMeter() error {
}
// grid energy (import)
if energyMeter, ok := site.gridMeter.(api.MeterEnergy); ok {
if energyMeter, ok := api.Cap[api.MeterEnergy](site.gridMeter); ok {
if f, err := energyMeter.TotalEnergy(); err == nil {
mm.Energy = f
} else {

View file

@ -22,7 +22,7 @@ func (site *Site) hasBatteryControl() bool {
for _, dev := range site.batteryMeters {
meter := dev.Instance()
if _, ok := meter.(api.BatteryController); ok {
if api.HasCap[api.BatteryController](meter) {
return true
}
}
@ -117,12 +117,12 @@ func (site *Site) requiredBatteryMode(batteryGridChargeActive bool, rate api.Rat
func (site *Site) batteryMaxSocReached(dev config.Device[api.Meter]) (bool, error) {
meter := dev.Instance()
batLimiter, ok := meter.(api.BatterySocLimiter)
batLimiter, ok := api.Cap[api.BatterySocLimiter](meter)
if !ok {
return false, nil
}
batSoc, ok := meter.(api.Battery)
batSoc, ok := api.Cap[api.Battery](meter)
if !ok {
return false, errors.New("battery with soc limits must have soc")
}
@ -152,7 +152,7 @@ func (site *Site) applyBatteryMode(mode api.BatteryMode) error {
for _, dev := range site.batteryMeters {
meter := dev.Instance()
batCtrl, ok := meter.(api.BatteryController)
batCtrl, ok := api.Cap[api.BatteryController](meter)
if !ok {
continue
}

View file

@ -62,7 +62,7 @@ func (site *Site) dimMeters(dim bool) error {
var errs error
for _, dev := range slices.Concat(site.auxMeters, site.extMeters) {
m, ok := dev.Instance().(api.Dimmer)
m, ok := api.Cap[api.Dimmer](dev.Instance())
if !ok {
continue
}
@ -92,7 +92,7 @@ func (site *Site) curtailPV(curtail bool) error {
var errs error
for _, dev := range site.pvMeters {
m, ok := dev.Instance().(api.Curtailer)
m, ok := api.Cap[api.Curtailer](dev.Instance())
if !ok {
continue
}

View file

@ -422,17 +422,17 @@ func (site *Site) batteryRequest(dev config.Device[api.Meter], b types.Measureme
instance := dev.Instance()
if _, ok := instance.(api.BatteryController); ok {
if api.HasCap[api.BatteryController](instance) {
bat.ChargeFromGrid = true
}
if m, ok := instance.(api.BatteryPowerLimiter); ok {
if m, ok := api.Cap[api.BatteryPowerLimiter](instance); ok {
charge, discharge := m.GetPowerLimits()
bat.CMax = float32(charge)
bat.DMax = float32(discharge)
}
if m, ok := instance.(api.BatterySocLimiter); ok {
if m, ok := api.Cap[api.BatterySocLimiter](instance); ok {
minSoc, maxSoc := m.GetSocLimits()
bat.SMin = float32(*b.Capacity * minSoc * 10) // Wh
bat.SMax = float32(*b.Capacity * maxSoc * 10) // Wh

View file

@ -49,7 +49,7 @@ func (cr *ChargeRater) StartCharge(continued bool) {
cr.start = cr.clck.Now()
// get end energy amount
if m, ok := cr.meter.(api.MeterEnergy); ok {
if m, ok := api.Cap[api.MeterEnergy](cr.meter); ok {
if f, err := m.TotalEnergy(); err == nil {
cr.startEnergy = f
cr.log.DEBUG.Printf("charge start energy: %.3fkWh", f)
@ -74,7 +74,7 @@ func (cr *ChargeRater) StopCharge() {
cr.charging = false
// get end energy amount
if m, ok := cr.meter.(api.MeterEnergy); ok {
if m, ok := api.Cap[api.MeterEnergy](cr.meter); ok {
if f, err := m.TotalEnergy(); err == nil {
cr.chargedEnergy += f - cr.startEnergy
cr.log.DEBUG.Printf("charge final energy: %.3fkWh", cr.chargedEnergy)
@ -92,7 +92,7 @@ func (cr *ChargeRater) ResetCharge() {
defer cr.Unlock()
// get end energy amount
if m, ok := cr.meter.(api.MeterEnergy); ok {
if m, ok := api.Cap[api.MeterEnergy](cr.meter); ok {
if f, err := m.TotalEnergy(); err == nil {
cr.chargedEnergy += f - cr.startEnergy
cr.log.DEBUG.Printf("charge final energy: %.3fkWh", cr.chargedEnergy)
@ -117,7 +117,7 @@ func (cr *ChargeRater) SetChargePower(power float64) {
}
// update energy amount if not provided by meter
if _, ok := cr.meter.(api.MeterEnergy); !ok {
if !api.HasCap[api.MeterEnergy](cr.meter) {
// convert power to energy in kWh
cr.chargedEnergy += power / 1e3 * float64(cr.clck.Since(cr.start)) / float64(time.Hour)
// move timestamp
@ -137,7 +137,7 @@ func (cr *ChargeRater) ChargedEnergy() (float64, error) {
}
// get current energy amount
if m, ok := cr.meter.(api.MeterEnergy); ok {
if m, ok := api.Cap[api.MeterEnergy](cr.meter); ok {
f, err := m.TotalEnergy()
if err == nil {
return cr.chargedEnergy + f - cr.startEnergy, nil

1
go.mod
View file

@ -74,7 +74,6 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/modelcontextprotocol/go-sdk v1.4.1
github.com/muka/go-bluetooth v0.0.0-20240701044517-04c4f09c514e
github.com/mxschmitt/golang-combinations v1.2.0
github.com/nicholas-fedor/shoutrrr v0.14.0
github.com/nicksnyder/go-i18n/v2 v2.6.1
github.com/olekukonko/tablewriter v1.1.4

2
go.sum
View file

@ -535,8 +535,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxschmitt/golang-combinations v1.2.0 h1:V5E7MncIK8Yr1SL/SpdqMuSquFsfoIs5auI7Y3n8z14=
github.com/mxschmitt/golang-combinations v1.2.0/go.mod h1:RCm5eR03B+JrBOMRDLsKZWShluXdrHu+qwhPEJ0miBM=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=

View file

@ -3,53 +3,37 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateDsmr(base api.Meter, meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error)) api.Meter {
switch {
case meterEnergy == nil && phaseCurrents == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateDsmrMeterEnergyImpl{meterEnergy: meterEnergy}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateDsmrPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case meterEnergy != nil && phaseCurrents == nil:
return &struct {
return &decorateDsmrCapable{Meter: base, caps: caps}
}
type decorateDsmrCapable struct {
api.Meter
api.MeterEnergy
}{
Meter: base,
MeterEnergy: &decorateDsmrMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case meterEnergy == nil && phaseCurrents != nil:
return &struct {
api.Meter
api.PhaseCurrents
}{
Meter: base,
PhaseCurrents: &decorateDsmrPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meterEnergy != nil && phaseCurrents != nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
Meter: base,
MeterEnergy: &decorateDsmrMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateDsmrPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
}
return nil
func (d *decorateDsmrCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateDsmrMeterEnergyImpl struct {

View file

@ -3,699 +3,53 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateE3dc(base *E3dc, battery func() (float64, error), batteryCapacity func() float64, batteryController func(api.BatteryMode) error, batterySocLimiter func() (float64, float64), batteryPowerLimiter func() (float64, float64), maxACPowerGetter func() float64) api.Meter {
switch {
case battery == nil && maxACPowerGetter == nil:
caps := make(map[reflect.Type]any)
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateE3dcBatteryImpl{battery: battery}
}
if batteryCapacity != nil {
caps[reflect.TypeFor[api.BatteryCapacity]()] = &decorateE3dcBatteryCapacityImpl{batteryCapacity: batteryCapacity}
}
if batteryController != nil {
caps[reflect.TypeFor[api.BatteryController]()] = &decorateE3dcBatteryControllerImpl{batteryController: batteryController}
}
if batterySocLimiter != nil {
caps[reflect.TypeFor[api.BatterySocLimiter]()] = &decorateE3dcBatterySocLimiterImpl{batterySocLimiter: batterySocLimiter}
}
if batteryPowerLimiter != nil {
caps[reflect.TypeFor[api.BatteryPowerLimiter]()] = &decorateE3dcBatteryPowerLimiterImpl{batteryPowerLimiter: batteryPowerLimiter}
}
if maxACPowerGetter != nil {
caps[reflect.TypeFor[api.MaxACPowerGetter]()] = &decorateE3dcMaxACPowerGetterImpl{maxACPowerGetter: maxACPowerGetter}
}
if len(caps) == 0 {
return base
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
return &decorateE3dcCapable{E3dc: base, caps: caps}
}
type decorateE3dcCapable struct {
*E3dc
api.Battery
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
caps map[reflect.Type]any
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryPowerLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatteryPowerLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter == nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.MaxACPowerGetter
}{
E3dc: base,
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryPowerLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && maxACPowerGetter != nil:
return &struct {
*E3dc
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MaxACPowerGetter
}{
E3dc: base,
Battery: &decorateE3dcBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateE3dcBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateE3dcBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateE3dcBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateE3dcBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MaxACPowerGetter: &decorateE3dcMaxACPowerGetterImpl{
maxACPowerGetter: maxACPowerGetter,
},
}
}
return nil
func (d *decorateE3dcCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateE3dcBatteryImpl struct {

View file

@ -3,42 +3,37 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateGoodWeWifi(base *goodWeWiFi, battery func() (float64, error), batteryCapacity func() float64) api.Meter {
switch {
case battery == nil:
caps := make(map[reflect.Type]any)
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateGoodWeWifiBatteryImpl{battery: battery}
}
if batteryCapacity != nil {
caps[reflect.TypeFor[api.BatteryCapacity]()] = &decorateGoodWeWifiBatteryCapacityImpl{batteryCapacity: batteryCapacity}
}
if len(caps) == 0 {
return base
}
case battery != nil && batteryCapacity == nil:
return &struct {
return &decorateGoodWeWifiCapable{goodWeWiFi: base, caps: caps}
}
type decorateGoodWeWifiCapable struct {
*goodWeWiFi
api.Battery
}{
goodWeWiFi: base,
Battery: &decorateGoodWeWifiBatteryImpl{
battery: battery,
},
caps map[reflect.Type]any
}
case battery != nil && batteryCapacity != nil:
return &struct {
*goodWeWiFi
api.Battery
api.BatteryCapacity
}{
goodWeWiFi: base,
Battery: &decorateGoodWeWifiBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateGoodWeWifiBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
}
}
return nil
func (d *decorateGoodWeWifiCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateGoodWeWifiBatteryImpl struct {

View file

@ -3,699 +3,53 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateLgEss(base *LgEss, meterEnergy func() (float64, error), batteryCapacity func() float64, battery func() (float64, error), batterySocLimiter func() (float64, float64), batteryPowerLimiter func() (float64, float64), batteryController func(api.BatteryMode) error) api.Meter {
switch {
case battery == nil && meterEnergy == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decorateLgEssMeterEnergyImpl{meterEnergy: meterEnergy}
}
if batteryCapacity != nil {
caps[reflect.TypeFor[api.BatteryCapacity]()] = &decorateLgEssBatteryCapacityImpl{batteryCapacity: batteryCapacity}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decorateLgEssBatteryImpl{battery: battery}
}
if batterySocLimiter != nil {
caps[reflect.TypeFor[api.BatterySocLimiter]()] = &decorateLgEssBatterySocLimiterImpl{batterySocLimiter: batterySocLimiter}
}
if batteryPowerLimiter != nil {
caps[reflect.TypeFor[api.BatteryPowerLimiter]()] = &decorateLgEssBatteryPowerLimiterImpl{batteryPowerLimiter: batteryPowerLimiter}
}
if batteryController != nil {
caps[reflect.TypeFor[api.BatteryController]()] = &decorateLgEssBatteryControllerImpl{batteryController: batteryController}
}
if len(caps) == 0 {
return base
}
case battery == nil && meterEnergy != nil:
return &struct {
return &decorateLgEssCapable{LgEss: base, caps: caps}
}
type decorateLgEssCapable struct {
*LgEss
api.MeterEnergy
}{
LgEss: base,
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryPowerLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryPowerLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatteryPowerLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*LgEss
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
LgEss: base,
Battery: &decorateLgEssBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateLgEssBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decorateLgEssBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decorateLgEssBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateLgEssBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateLgEssMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
}
return nil
func (d *decorateLgEssCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateLgEssBatteryImpl struct {

View file

@ -42,31 +42,31 @@ func NewMovingAverageFromConfig(ctx context.Context, other map[string]any) (api.
// decorate energy reading
var totalEnergy func() (float64, error)
if m, ok := m.(api.MeterEnergy); ok {
if m, ok := api.Cap[api.MeterEnergy](m); ok {
totalEnergy = m.TotalEnergy
}
// decorate battery reading
var batterySoc func() (float64, error)
if m, ok := m.(api.Battery); ok {
if m, ok := api.Cap[api.Battery](m); ok {
batterySoc = m.Soc
}
// decorate currents reading
var currents func() (float64, float64, float64, error)
if m, ok := m.(api.PhaseCurrents); ok {
if m, ok := api.Cap[api.PhaseCurrents](m); ok {
currents = m.Currents
}
// decorate voltages reading
var voltages func() (float64, float64, float64, error)
if m, ok := m.(api.PhaseVoltages); ok {
if m, ok := api.Cap[api.PhaseVoltages](m); ok {
voltages = m.Voltages
}
// decorate powers reading
var powers func() (float64, float64, float64, error)
if m, ok := m.(api.PhasePowers); ok {
if m, ok := api.Cap[api.PhasePowers](m); ok {
powers = m.Powers
}

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,8 @@ func TestPV(t *testing.T) {
require.NoError(t, err)
// must not have soc/capacity
assert.Implements(t, new(api.MaxACPowerGetter), m)
_, ok := api.Cap[api.MaxACPowerGetter](m)
assert.True(t, ok, "MaxACPowerGetter")
}
func TestBattery(t *testing.T) {
m, err := NewConfigurableFromConfig(t.Context(), map[string]any{
@ -35,6 +36,8 @@ func TestBattery(t *testing.T) {
})
require.NoError(t, err)
assert.Implements(t, new(api.Battery), m)
assert.Implements(t, new(api.BatteryCapacity), m)
_, ok := api.Cap[api.Battery](m)
assert.True(t, ok, "Battery")
_, ok = api.Cap[api.BatteryCapacity](m)
assert.True(t, ok, "BatteryCapacity")
}

View file

@ -3,699 +3,53 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decoratePowerWall(base *PowerWall, meterEnergy func() (float64, error), battery func() (float64, error), batteryCapacity func() float64, batterySocLimiter func() (float64, float64), batteryPowerLimiter func() (float64, float64), batteryController func(api.BatteryMode) error) api.Meter {
switch {
case battery == nil && meterEnergy == nil:
caps := make(map[reflect.Type]any)
if meterEnergy != nil {
caps[reflect.TypeFor[api.MeterEnergy]()] = &decoratePowerWallMeterEnergyImpl{meterEnergy: meterEnergy}
}
if battery != nil {
caps[reflect.TypeFor[api.Battery]()] = &decoratePowerWallBatteryImpl{battery: battery}
}
if batteryCapacity != nil {
caps[reflect.TypeFor[api.BatteryCapacity]()] = &decoratePowerWallBatteryCapacityImpl{batteryCapacity: batteryCapacity}
}
if batterySocLimiter != nil {
caps[reflect.TypeFor[api.BatterySocLimiter]()] = &decoratePowerWallBatterySocLimiterImpl{batterySocLimiter: batterySocLimiter}
}
if batteryPowerLimiter != nil {
caps[reflect.TypeFor[api.BatteryPowerLimiter]()] = &decoratePowerWallBatteryPowerLimiterImpl{batteryPowerLimiter: batteryPowerLimiter}
}
if batteryController != nil {
caps[reflect.TypeFor[api.BatteryController]()] = &decoratePowerWallBatteryControllerImpl{batteryController: batteryController}
}
if len(caps) == 0 {
return base
}
case battery == nil && meterEnergy != nil:
return &struct {
return &decoratePowerWallCapable{PowerWall: base, caps: caps}
}
type decoratePowerWallCapable struct {
*PowerWall
api.MeterEnergy
}{
PowerWall: base,
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
caps map[reflect.Type]any
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryPowerLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryPowerLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatteryPowerLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryController != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
*PowerWall
api.Battery
api.BatteryCapacity
api.BatteryController
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
PowerWall: base,
Battery: &decoratePowerWallBatteryImpl{
battery: battery,
},
BatteryCapacity: &decoratePowerWallBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryController: &decoratePowerWallBatteryControllerImpl{
batteryController: batteryController,
},
BatteryPowerLimiter: &decoratePowerWallBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decoratePowerWallBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decoratePowerWallMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
}
return nil
func (d *decoratePowerWallCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decoratePowerWallBatteryImpl struct {

File diff suppressed because it is too large Load diff

View file

@ -3,87 +3,41 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateShelly(base *Shelly, phaseVoltages func() (float64, float64, float64, error), phaseCurrents func() (float64, float64, float64, error), phasePowers func() (float64, float64, float64, error)) api.Meter {
switch {
case phaseCurrents == nil && phaseVoltages == nil:
caps := make(map[reflect.Type]any)
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateShellyPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateShellyPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phasePowers != nil {
caps[reflect.TypeFor[api.PhasePowers]()] = &decorateShellyPhasePowersImpl{phasePowers: phasePowers}
}
if len(caps) == 0 {
return base
}
case phaseCurrents == nil && phaseVoltages != nil:
return &struct {
return &decorateShellyCapable{Shelly: base, caps: caps}
}
type decorateShellyCapable struct {
*Shelly
api.PhaseVoltages
}{
Shelly: base,
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
caps map[reflect.Type]any
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages == nil:
return &struct {
*Shelly
api.PhaseCurrents
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages != nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhaseVoltages
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages == nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhasePowers
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateShellyPhasePowersImpl{
phasePowers: phasePowers,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages != nil:
return &struct {
*Shelly
api.PhaseCurrents
api.PhasePowers
api.PhaseVoltages
}{
Shelly: base,
PhaseCurrents: &decorateShellyPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateShellyPhasePowersImpl{
phasePowers: phasePowers,
},
PhaseVoltages: &decorateShellyPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateShellyCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateShellyPhaseCurrentsImpl struct {

View file

@ -3,87 +3,41 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateTasmota(base *Tasmota, phaseVoltages func() (float64, float64, float64, error), phaseCurrents func() (float64, float64, float64, error), phasePowers func() (float64, float64, float64, error)) api.Meter {
switch {
case phaseCurrents == nil && phaseVoltages == nil:
caps := make(map[reflect.Type]any)
if phaseVoltages != nil {
caps[reflect.TypeFor[api.PhaseVoltages]()] = &decorateTasmotaPhaseVoltagesImpl{phaseVoltages: phaseVoltages}
}
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateTasmotaPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if phasePowers != nil {
caps[reflect.TypeFor[api.PhasePowers]()] = &decorateTasmotaPhasePowersImpl{phasePowers: phasePowers}
}
if len(caps) == 0 {
return base
}
case phaseCurrents == nil && phaseVoltages != nil:
return &struct {
return &decorateTasmotaCapable{Tasmota: base, caps: caps}
}
type decorateTasmotaCapable struct {
*Tasmota
api.PhaseVoltages
}{
Tasmota: base,
PhaseVoltages: &decorateTasmotaPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
caps map[reflect.Type]any
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages == nil:
return &struct {
*Tasmota
api.PhaseCurrents
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case phaseCurrents != nil && phasePowers == nil && phaseVoltages != nil:
return &struct {
*Tasmota
api.PhaseCurrents
api.PhaseVoltages
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateTasmotaPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages == nil:
return &struct {
*Tasmota
api.PhaseCurrents
api.PhasePowers
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateTasmotaPhasePowersImpl{
phasePowers: phasePowers,
},
}
case phaseCurrents != nil && phasePowers != nil && phaseVoltages != nil:
return &struct {
*Tasmota
api.PhaseCurrents
api.PhasePowers
api.PhaseVoltages
}{
Tasmota: base,
PhaseCurrents: &decorateTasmotaPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateTasmotaPhasePowersImpl{
phasePowers: phasePowers,
},
PhaseVoltages: &decorateTasmotaPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
func (d *decorateTasmotaCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateTasmotaPhaseCurrentsImpl struct {

View file

@ -3,27 +3,33 @@ package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateTqEm(base api.Meter, phaseCurrents func() (float64, float64, float64, error)) api.Meter {
switch {
case phaseCurrents == nil:
caps := make(map[reflect.Type]any)
if phaseCurrents != nil {
caps[reflect.TypeFor[api.PhaseCurrents]()] = &decorateTqEmPhaseCurrentsImpl{phaseCurrents: phaseCurrents}
}
if len(caps) == 0 {
return base
}
case phaseCurrents != nil:
return &struct {
return &decorateTqEmCapable{Meter: base, caps: caps}
}
type decorateTqEmCapable struct {
api.Meter
api.PhaseCurrents
}{
Meter: base,
PhaseCurrents: &decorateTqEmPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
caps map[reflect.Type]any
}
return nil
func (d *decorateTqEmCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateTqEmPhaseCurrentsImpl struct {

View file

@ -55,11 +55,11 @@ func (o *meterPlugin) FloatGetter() (func() (float64, error), error) {
switch o.method {
case Energy:
if _, ok := o.meter.(api.MeterEnergy); !ok {
if !api.HasCap[api.MeterEnergy](o.meter) {
return nil, err
}
case Soc:
if _, ok := o.meter.(api.Battery); !ok {
if !api.HasCap[api.Battery](o.meter) {
return nil, err
}
}
@ -67,10 +67,12 @@ func (o *meterPlugin) FloatGetter() (func() (float64, error), error) {
return func() (float64, error) {
switch o.method {
case Energy:
f, err := o.meter.(api.MeterEnergy).TotalEnergy()
m, _ := api.Cap[api.MeterEnergy](o.meter)
f, err := m.TotalEnergy()
return f * o.scale, err
case Soc:
f, err := o.meter.(api.Battery).Soc()
m, _ := api.Cap[api.Battery](o.meter)
f, err := m.Soc()
return f * o.scale, err
default:
f, err := o.meter.CurrentPower()

View file

@ -218,7 +218,7 @@ type testResult = struct {
}
func hasFeature(instance any, f api.Feature) bool {
fd, ok := instance.(api.FeatureDescriber)
fd, ok := api.Cap[api.FeatureDescriber](instance)
return ok && slices.Contains(fd.Features(), f)
}
@ -238,17 +238,17 @@ func testInstance(instance any) map[string]testResult {
res[key] = tr
}
if dev, ok := instance.(api.Meter); ok {
if dev, ok := api.Cap[api.Meter](instance); ok {
val, err := dev.CurrentPower()
makeResult("power", val, err)
}
if dev, ok := instance.(api.MeterEnergy); ok {
if dev, ok := api.Cap[api.MeterEnergy](instance); ok {
val, err := dev.TotalEnergy()
makeResult("energy", val, err)
}
if dev, ok := instance.(api.Battery); ok {
if dev, ok := api.Cap[api.Battery](instance); ok {
val, err := dev.Soc()
key := "soc"
if hasFeature(instance, api.Heating) {
@ -257,51 +257,51 @@ func testInstance(instance any) map[string]testResult {
makeResult(key, val, err)
}
if _, ok := instance.(api.BatteryController); ok {
if api.HasCap[api.BatteryController](instance) {
makeResult("controllable", true, nil)
}
if dev, ok := instance.(api.VehicleOdometer); ok {
if dev, ok := api.Cap[api.VehicleOdometer](instance); ok {
val, err := dev.Odometer()
makeResult("odometer", val, err)
}
if dev, ok := instance.(api.BatteryCapacity); ok {
if dev, ok := api.Cap[api.BatteryCapacity](instance); ok {
val := dev.Capacity()
makeResult("capacity", val, nil)
}
if dev, ok := instance.(api.PhaseCurrents); ok {
if dev, ok := api.Cap[api.PhaseCurrents](instance); ok {
i1, i2, i3, err := dev.Currents()
makeResult("phaseCurrents", []float64{i1, i2, i3}, err)
}
if dev, ok := instance.(api.PhaseVoltages); ok {
if dev, ok := api.Cap[api.PhaseVoltages](instance); ok {
u1, u2, u3, err := dev.Voltages()
makeResult("phaseVoltages", []float64{u1, u2, u3}, err)
}
if dev, ok := instance.(api.PhasePowers); ok {
if dev, ok := api.Cap[api.PhasePowers](instance); ok {
p1, p2, p3, err := dev.Powers()
makeResult("phasePowers", []float64{p1, p2, p3}, err)
}
if dev, ok := instance.(api.ChargeState); ok {
if dev, ok := api.Cap[api.ChargeState](instance); ok {
val, err := dev.Status()
makeResult("chargeStatus", val, err)
}
if dev, ok := instance.(api.Charger); ok {
if dev, ok := api.Cap[api.Charger](instance); ok {
val, err := dev.Enabled()
makeResult("enabled", val, err)
}
if dev, ok := instance.(api.ChargeRater); ok {
if dev, ok := api.Cap[api.ChargeRater](instance); ok {
val, err := dev.ChargedEnergy()
makeResult("chargedEnergy", val, err)
}
if _, ok := instance.(api.PhaseSwitcher); ok {
if api.HasCap[api.PhaseSwitcher](instance) {
makeResult("phases1p3p", true, nil)
}
@ -313,20 +313,20 @@ func testInstance(instance any) map[string]testResult {
makeResult("integratedDevice", true, nil)
}
if dev, ok := instance.(api.IconDescriber); ok && dev.Icon() != "" {
if dev, ok := api.Cap[api.IconDescriber](instance); ok && dev.Icon() != "" {
makeResult("icon", dev.Icon(), nil)
}
if cc, ok := instance.(api.PhaseDescriber); ok && cc.Phases() == 1 {
if cc, ok := api.Cap[api.PhaseDescriber](instance); ok && cc.Phases() == 1 {
makeResult("singlePhase", true, nil)
}
if dev, ok := instance.(api.VehicleRange); ok {
if dev, ok := api.Cap[api.VehicleRange](instance); ok {
val, err := dev.Range()
makeResult("range", val, err)
}
if dev, ok := instance.(api.SocLimiter); ok {
if dev, ok := api.Cap[api.SocLimiter](instance); ok {
val, err := dev.GetLimitSoc()
key := "vehicleLimitSoc"
if hasFeature(instance, api.Heating) {
@ -335,17 +335,17 @@ func testInstance(instance any) map[string]testResult {
makeResult(key, val, err)
}
if dev, ok := instance.(api.Dimmer); ok {
if dev, ok := api.Cap[api.Dimmer](instance); ok {
val, err := dev.Dimmed()
makeResult("dimmed", val, err)
}
if dev, ok := instance.(api.Identifier); ok {
if dev, ok := api.Cap[api.Identifier](instance); ok {
val, err := dev.Identify()
makeResult("identifier", val, err)
}
if dev, ok := instance.(api.Tariff); ok {
if dev, ok := api.Cap[api.Tariff](instance); ok {
rates, err := dev.Rates()
// Determine field names based on tariff type

View file

@ -21,7 +21,7 @@ func csvResult(ctx context.Context, w http.ResponseWriter, res any, filename str
w.Header().Set("Content-Type", "text/csv")
w.Header().Set("Content-Disposition", `attachment; filename="`+filename+`.csv"`)
if ww, ok := res.(api.CsvWriter); ok {
if ww, ok := api.Cap[api.CsvWriter](res); ok {
_ = ww.WriteCsv(ctx, w)
} else {
w.WriteHeader(http.StatusInternalServerError)

View file

@ -3,87 +3,41 @@ package vehicle
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"reflect"
"github.com/evcc-io/evcc/api"
)
func decorateTronity(base *Tronity, chargeState func() (api.ChargeStatus, error), vehicleOdometer func() (float64, error), chargeController func(bool) error) api.Vehicle {
switch {
case chargeState == nil && vehicleOdometer == nil:
caps := make(map[reflect.Type]any)
if chargeState != nil {
caps[reflect.TypeFor[api.ChargeState]()] = &decorateTronityChargeStateImpl{chargeState: chargeState}
}
if vehicleOdometer != nil {
caps[reflect.TypeFor[api.VehicleOdometer]()] = &decorateTronityVehicleOdometerImpl{vehicleOdometer: vehicleOdometer}
}
if chargeController != nil {
caps[reflect.TypeFor[api.ChargeController]()] = &decorateTronityChargeControllerImpl{chargeController: chargeController}
}
if len(caps) == 0 {
return base
}
case chargeController == nil && chargeState != nil && vehicleOdometer == nil:
return &struct {
return &decorateTronityCapable{Tronity: base, caps: caps}
}
type decorateTronityCapable struct {
*Tronity
api.ChargeState
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
caps map[reflect.Type]any
}
case chargeState == nil && vehicleOdometer != nil:
return &struct {
*Tronity
api.VehicleOdometer
}{
Tronity: base,
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeController == nil && chargeState != nil && vehicleOdometer != nil:
return &struct {
*Tronity
api.ChargeState
api.VehicleOdometer
}{
Tronity: base,
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
case chargeController != nil && chargeState != nil && vehicleOdometer == nil:
return &struct {
*Tronity
api.ChargeController
api.ChargeState
}{
Tronity: base,
ChargeController: &decorateTronityChargeControllerImpl{
chargeController: chargeController,
},
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
}
case chargeController != nil && chargeState != nil && vehicleOdometer != nil:
return &struct {
*Tronity
api.ChargeController
api.ChargeState
api.VehicleOdometer
}{
Tronity: base,
ChargeController: &decorateTronityChargeControllerImpl{
chargeController: chargeController,
},
ChargeState: &decorateTronityChargeStateImpl{
chargeState: chargeState,
},
VehicleOdometer: &decorateTronityVehicleOdometerImpl{
vehicleOdometer: vehicleOdometer,
},
}
}
return nil
func (d *decorateTronityCapable) Capability(typ reflect.Type) (any, bool) {
c, ok := d.caps[typ]
return c, ok
}
type decorateTronityChargeControllerImpl struct {

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more