Add currents to default meter (#267)
This commit is contained in:
parent
21e7356590
commit
ec04b22739
2 changed files with 107 additions and 15 deletions
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/andig/evcc/meter"
|
||||
"github.com/andig/evcc/api"
|
||||
"github.com/andig/evcc/mock"
|
||||
"github.com/andig/evcc/util"
|
||||
"github.com/benbjohnson/clock"
|
||||
|
|
@ -45,7 +45,13 @@ func TestWrappedMeter(t *testing.T) {
|
|||
|
||||
mm := mock.NewMockMeter(ctrl)
|
||||
me := mock.NewMockMeterEnergy(ctrl)
|
||||
cm := &meter.EnergyDecorator{Meter: mm, MeterEnergy: me}
|
||||
|
||||
type EnergyDecorator struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}
|
||||
|
||||
cm := &EnergyDecorator{Meter: mm, MeterEnergy: me}
|
||||
|
||||
me.EXPECT().
|
||||
TotalEnergy().
|
||||
|
|
|
|||
112
meter/meter.go
112
meter/meter.go
|
|
@ -1,6 +1,7 @@
|
|||
package meter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/andig/evcc/api"
|
||||
|
|
@ -8,17 +9,12 @@ import (
|
|||
"github.com/andig/evcc/util"
|
||||
)
|
||||
|
||||
// EnergyDecorator decorates an api.Meter with api.MeterEnergy
|
||||
type EnergyDecorator struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}
|
||||
|
||||
// NewConfigurableFromConfig creates api.Meter from config
|
||||
func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) {
|
||||
cc := struct {
|
||||
Power provider.Config
|
||||
Energy *provider.Config // optional
|
||||
Power provider.Config
|
||||
Energy *provider.Config // optional
|
||||
Currents []provider.Config // optional
|
||||
}{}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
|
|
@ -40,14 +36,54 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
|
||||
// decorate Meter with MeterEnergy
|
||||
if cc.Energy != nil {
|
||||
energy, err := provider.NewFloatGetterFromConfig(*cc.Energy)
|
||||
energy, err := NewMeterEnergy(*cc.Energy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type EnergyDecorator struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}
|
||||
|
||||
m = &EnergyDecorator{
|
||||
Meter: m,
|
||||
MeterEnergy: NewMeterEnergy(energy),
|
||||
MeterEnergy: energy,
|
||||
}
|
||||
}
|
||||
|
||||
// decorate Meter with MeterCurrent
|
||||
if len(cc.Currents) > 0 {
|
||||
currents, err := NewCurrents(cc.Currents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type PowerEnergy interface {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}
|
||||
|
||||
if pe, ok := m.(PowerEnergy); ok {
|
||||
type CurrentDecorator struct {
|
||||
PowerEnergy
|
||||
api.MeterCurrent
|
||||
}
|
||||
|
||||
m = &CurrentDecorator{
|
||||
PowerEnergy: pe,
|
||||
MeterCurrent: currents,
|
||||
}
|
||||
} else {
|
||||
type CurrentDecorator struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
}
|
||||
|
||||
m = &CurrentDecorator{
|
||||
Meter: m,
|
||||
MeterCurrent: currents,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,14 +113,64 @@ type MeterEnergy struct {
|
|||
totalEnergyG func() (float64, error)
|
||||
}
|
||||
|
||||
// NewMeterEnergy creates a new charger
|
||||
func NewMeterEnergy(totalEnergyG func() (float64, error)) api.MeterEnergy {
|
||||
return &MeterEnergy{
|
||||
// NewMeterEnergy creates a new api.MeterEnergy
|
||||
func NewMeterEnergy(ccEnergy provider.Config) (api.MeterEnergy, error) {
|
||||
totalEnergyG, err := provider.NewFloatGetterFromConfig(ccEnergy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e := &MeterEnergy{
|
||||
totalEnergyG: totalEnergyG,
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// TotalEnergy implements the Meter.TotalEnergy interface
|
||||
func (m *MeterEnergy) TotalEnergy() (float64, error) {
|
||||
return m.totalEnergyG()
|
||||
}
|
||||
|
||||
// Currents is an api.MeterCurrent implementation
|
||||
type Currents struct {
|
||||
currentsG []func() (float64, error)
|
||||
}
|
||||
|
||||
// NewCurrents creates a new api.MeterCurrent
|
||||
func NewCurrents(ccCurrents []provider.Config) (api.MeterCurrent, error) {
|
||||
if len(ccCurrents) != 3 {
|
||||
return nil, errors.New("need 3 currents")
|
||||
}
|
||||
|
||||
var currentsG []func() (float64, error)
|
||||
for _, cc := range ccCurrents {
|
||||
c, err := provider.NewFloatGetterFromConfig(cc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
currentsG = append(currentsG, c)
|
||||
}
|
||||
|
||||
c := &Currents{
|
||||
currentsG: currentsG,
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Currents implements the api.Currents interface
|
||||
func (c *Currents) Currents() (float64, float64, float64, error) {
|
||||
var currents []float64
|
||||
for _, currentG := range c.currentsG {
|
||||
c, err := currentG()
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
currents = append(currents, c)
|
||||
}
|
||||
|
||||
return currents[0], currents[1], currents[2], nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue