chore: simplify

This commit is contained in:
andig 2026-01-09 09:27:36 +01:00
commit 7ade74a5a7
2 changed files with 18 additions and 626 deletions

View file

@ -15,38 +15,18 @@ import (
"github.com/volkszaehler/mbmd/meters/rs485"
)
// ModbusMbmd is an api.Meter implementation with configurable getters and setters.
type ModbusMbmd struct {
// Mbmd is an api.Meter implementation with configurable getters and setters.
type Mbmd struct {
conn *modbus.Connection
device *rs485.RS485
powerG func() (float64, error)
}
func init() {
registry.AddCtx("mbmd", NewModbusMbmdFromConfig)
registry.AddCtx("mbmd", NewMbmdFromConfig)
}
//go:generate go tool decorate
//evcc:function decorateMbmd
//evcc:basetype api.Meter
//evcc:type api.MeterEnergy,TotalEnergy,func() (float64, error)
//evcc:type api.PhaseCurrents,Currents,func() (float64, float64, float64, error)
//evcc:type api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)
//evcc:type api.PhasePowers,Powers,func() (float64, float64, float64, error)
// evcc:type api.MaxACPowerGetter,MaxACPower,func() float64
//evcc:function decorateMbmdBattery
//evcc:basetype api.Meter
//evcc:type api.MeterEnergy,TotalEnergy,func() (float64, error)
//evcc:type api.Battery,Soc,func() (float64, error)
//evcc:type api.BatteryCapacity,Capacity,func() float64
//evcc:type api.BatterySocLimiter,GetSocLimits,func() (float64, float64)
//evcc:type api.BatteryPowerLimiter,GetPowerLimits,func() (float64, float64)
// evcc:type api.BatteryController,SetBatteryMode,func(api.BatteryMode) error
// NewModbusMbmdFromConfig creates api.Meter from config
func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Meter, error) {
// NewMbmdFromConfig creates api.Meter from config
func NewMbmdFromConfig(ctx context.Context, other map[string]any) (api.Meter, error) {
cc := struct {
Model string
batteryCapacity `mapstructure:",squash"`
@ -100,14 +80,14 @@ func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Met
return nil, err
}
m := &ModbusMbmd{
mbmd := &Mbmd{
conn: conn,
device: device,
}
ops := device.Producer().Produce()
m.powerG, err = m.deviceOp(ops, cc.Power)
powerG, err := mbmd.deviceOp(ops, cc.Power)
if err != nil {
return nil, fmt.Errorf("invalid measurement for power: %s", cc.Power)
}
@ -115,7 +95,7 @@ func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Met
// decorate energy
var totalEnergy func() (float64, error)
if cc.Energy != "" {
g, err := m.deviceOp(ops, cc.Energy)
g, err := mbmd.deviceOp(ops, cc.Energy)
if err != nil {
return nil, fmt.Errorf("invalid measurement for energy: %s", cc.Energy)
}
@ -124,19 +104,19 @@ func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Met
}
// decorate currents
currentsG, err := m.buildPhaseProviders(ops, cc.Currents)
currentsG, err := mbmd.buildPhaseProviders(ops, cc.Currents)
if err != nil {
return nil, fmt.Errorf("currents: %w", err)
}
// decorate voltages
voltagesG, err := m.buildPhaseProviders(ops, cc.Voltages)
voltagesG, err := mbmd.buildPhaseProviders(ops, cc.Voltages)
if err != nil {
return nil, fmt.Errorf("voltages: %w", err)
}
// decorate powers
powersG, err := m.buildPhaseProviders(ops, cc.Powers)
powersG, err := mbmd.buildPhaseProviders(ops, cc.Powers)
if err != nil {
return nil, fmt.Errorf("powers: %w", err)
}
@ -144,7 +124,7 @@ func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Met
// decorate soc
var soc func() (float64, error)
if cc.Soc != "" {
g, err := m.deviceOp(ops, cc.Soc)
g, err := mbmd.deviceOp(ops, cc.Soc)
if err != nil {
return nil, fmt.Errorf("invalid measurement for soc: %s", cc.Soc)
}
@ -152,15 +132,17 @@ func NewModbusMbmdFromConfig(ctx context.Context, other map[string]any) (api.Met
soc = g
}
m, _ := NewConfigurable(powerG)
if soc != nil {
return decorateMbmdBattery(m, totalEnergy, soc, cc.batteryCapacity.Decorator(), cc.batterySocLimits.Decorator(), cc.batteryPowerLimits.Decorator()), nil
return m.DecorateBattery(totalEnergy, soc, cc.batteryCapacity.Decorator(), cc.batterySocLimits.Decorator(), cc.batteryPowerLimits.Decorator(), nil), nil
}
return decorateMbmd(m, totalEnergy, currentsG, voltagesG, powersG), nil
return m.Decorate(totalEnergy, currentsG, voltagesG, powersG, nil), nil
}
// deviceOp checks is RS485 device supports operation
func (m *ModbusMbmd) deviceOp(ops []rs485.Operation, name string) (func() (float64, error), error) {
func (m *Mbmd) deviceOp(ops []rs485.Operation, name string) (func() (float64, error), error) {
// leading minus sign?
name, invert := strings.CutPrefix(name, "-")
@ -192,7 +174,7 @@ func (m *ModbusMbmd) deviceOp(ops []rs485.Operation, name string) (func() (float
return nil, fmt.Errorf("unsupported measurement: %s", measurement.String())
}
func (m *ModbusMbmd) buildPhaseProviders(ops []rs485.Operation, readings []string) (func() (float64, float64, float64, error), error) {
func (m *Mbmd) buildPhaseProviders(ops []rs485.Operation, readings []string) (func() (float64, float64, float64, error), error) {
if len(readings) == 0 {
return nil, nil
}
@ -213,8 +195,3 @@ func (m *ModbusMbmd) buildPhaseProviders(ops []rs485.Operation, readings []strin
return measurement.CombinePhases(phases), nil
}
// CurrentPower implements the api.Meter interface
func (m *ModbusMbmd) CurrentPower() (float64, error) {
return m.powerG()
}

View file

@ -1,585 +0,0 @@
package meter
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
import (
"github.com/evcc-io/evcc/api"
)
func decorateMbmd(base api.Meter, meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), phaseVoltages func() (float64, float64, float64, error), phasePowers func() (float64, float64, float64, error)) api.Meter {
switch {
case meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil:
return base
case meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil:
return &struct {
api.Meter
api.MeterEnergy
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case meterEnergy == nil && phaseCurrents != nil && phasePowers == nil && phaseVoltages == nil:
return &struct {
api.Meter
api.PhaseCurrents
}{
Meter: base,
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meterEnergy != nil && phaseCurrents != nil && phasePowers == nil && phaseVoltages == nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
}
case meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
api.Meter
api.PhaseVoltages
}{
Meter: base,
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy != nil && phaseCurrents == nil && phaseVoltages != nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseVoltages
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy == nil && phaseCurrents != nil && phasePowers == nil && phaseVoltages != nil:
return &struct {
api.Meter
api.PhaseCurrents
api.PhaseVoltages
}{
Meter: base,
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy != nil && phaseCurrents != nil && phasePowers == nil && phaseVoltages != nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhaseVoltages
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy == nil && phaseCurrents != nil && phasePowers != nil && phaseVoltages == nil:
return &struct {
api.Meter
api.PhaseCurrents
api.PhasePowers
}{
Meter: base,
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateMbmdPhasePowersImpl{
phasePowers: phasePowers,
},
}
case meterEnergy != nil && phaseCurrents != nil && phasePowers != nil && phaseVoltages == nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhasePowers
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateMbmdPhasePowersImpl{
phasePowers: phasePowers,
},
}
case meterEnergy == nil && phaseCurrents != nil && phasePowers != nil && phaseVoltages != nil:
return &struct {
api.Meter
api.PhaseCurrents
api.PhasePowers
api.PhaseVoltages
}{
Meter: base,
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateMbmdPhasePowersImpl{
phasePowers: phasePowers,
},
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
case meterEnergy != nil && phaseCurrents != nil && phasePowers != nil && phaseVoltages != nil:
return &struct {
api.Meter
api.MeterEnergy
api.PhaseCurrents
api.PhasePowers
api.PhaseVoltages
}{
Meter: base,
MeterEnergy: &decorateMbmdMeterEnergyImpl{
meterEnergy: meterEnergy,
},
PhaseCurrents: &decorateMbmdPhaseCurrentsImpl{
phaseCurrents: phaseCurrents,
},
PhasePowers: &decorateMbmdPhasePowersImpl{
phasePowers: phasePowers,
},
PhaseVoltages: &decorateMbmdPhaseVoltagesImpl{
phaseVoltages: phaseVoltages,
},
}
}
return nil
}
type decorateMbmdMeterEnergyImpl struct {
meterEnergy func() (float64, error)
}
func (impl *decorateMbmdMeterEnergyImpl) TotalEnergy() (float64, error) {
return impl.meterEnergy()
}
type decorateMbmdPhaseCurrentsImpl struct {
phaseCurrents func() (float64, float64, float64, error)
}
func (impl *decorateMbmdPhaseCurrentsImpl) Currents() (float64, float64, float64, error) {
return impl.phaseCurrents()
}
type decorateMbmdPhasePowersImpl struct {
phasePowers func() (float64, float64, float64, error)
}
func (impl *decorateMbmdPhasePowersImpl) Powers() (float64, float64, float64, error) {
return impl.phasePowers()
}
type decorateMbmdPhaseVoltagesImpl struct {
phaseVoltages func() (float64, float64, float64, error)
}
func (impl *decorateMbmdPhaseVoltagesImpl) Voltages() (float64, float64, float64, error) {
return impl.phaseVoltages()
}
func decorateMbmdBattery(base api.Meter, meterEnergy func() (float64, error), battery func() (float64, error), batteryCapacity func() float64, batterySocLimiter func() (float64, float64), batteryPowerLimiter func() (float64, float64)) api.Meter {
switch {
case battery == nil && meterEnergy == nil:
return base
case battery == nil && meterEnergy != nil:
return &struct {
api.Meter
api.MeterEnergy
}{
Meter: base,
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter == nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatterySocLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatterySocLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter == nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatterySocLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryPowerLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryPowerLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter != nil && batterySocLimiter == nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity == nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy == nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
}
case battery != nil && batteryCapacity != nil && batteryPowerLimiter != nil && batterySocLimiter != nil && meterEnergy != nil:
return &struct {
api.Meter
api.Battery
api.BatteryCapacity
api.BatteryPowerLimiter
api.BatterySocLimiter
api.MeterEnergy
}{
Meter: base,
Battery: &decorateMbmdBatteryBatteryImpl{
battery: battery,
},
BatteryCapacity: &decorateMbmdBatteryBatteryCapacityImpl{
batteryCapacity: batteryCapacity,
},
BatteryPowerLimiter: &decorateMbmdBatteryBatteryPowerLimiterImpl{
batteryPowerLimiter: batteryPowerLimiter,
},
BatterySocLimiter: &decorateMbmdBatteryBatterySocLimiterImpl{
batterySocLimiter: batterySocLimiter,
},
MeterEnergy: &decorateMbmdBatteryMeterEnergyImpl{
meterEnergy: meterEnergy,
},
}
}
return nil
}
type decorateMbmdBatteryBatteryImpl struct {
battery func() (float64, error)
}
func (impl *decorateMbmdBatteryBatteryImpl) Soc() (float64, error) {
return impl.battery()
}
type decorateMbmdBatteryBatteryCapacityImpl struct {
batteryCapacity func() float64
}
func (impl *decorateMbmdBatteryBatteryCapacityImpl) Capacity() float64 {
return impl.batteryCapacity()
}
type decorateMbmdBatteryBatteryPowerLimiterImpl struct {
batteryPowerLimiter func() (float64, float64)
}
func (impl *decorateMbmdBatteryBatteryPowerLimiterImpl) GetPowerLimits() (float64, float64) {
return impl.batteryPowerLimiter()
}
type decorateMbmdBatteryBatterySocLimiterImpl struct {
batterySocLimiter func() (float64, float64)
}
func (impl *decorateMbmdBatteryBatterySocLimiterImpl) GetSocLimits() (float64, float64) {
return impl.batterySocLimiter()
}
type decorateMbmdBatteryMeterEnergyImpl struct {
meterEnergy func() (float64, error)
}
func (impl *decorateMbmdBatteryMeterEnergyImpl) TotalEnergy() (float64, error) {
return impl.meterEnergy()
}