From 71e72c718220eb49a784d8022bc26c6fe2882f61 Mon Sep 17 00:00:00 2001 From: andig Date: Tue, 1 Sep 2020 14:06:20 +0200 Subject: [PATCH] Add evse power reading (#327) --- charger/evsewifi.go | 16 ++++++- charger/evsewifi_decorators.go | 78 +++++++++++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/charger/evsewifi.go b/charger/evsewifi.go index b7ca3bed8..d395b256d 100644 --- a/charger/evsewifi.go +++ b/charger/evsewifi.go @@ -54,7 +54,7 @@ func init() { registry.Add("evsewifi", NewEVSEWifiFromConfig) } -//go:generate go run ../cmd/tools/decorate.go -p charger -f decorateEVSE -b api.Charger -o evsewifi_decorators -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" +//go:generate go run ../cmd/tools/decorate.go -p charger -f decorateEVSE -b api.Charger -o evsewifi_decorators -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" // NewEVSEWifiFromConfig creates a EVSEWifi charger from generic config func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { @@ -73,6 +73,12 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { return evse, err } + // decorate Charger with Meter + var currentPower func() (float64, error) + if cc.Meter.Energy { + currentPower = evse.currentPower + } + // decorate Charger with MeterEnergy var totalEnergy func() (float64, error) if cc.Meter.Energy { @@ -85,7 +91,7 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { currents = evse.currents } - return decorateEVSE(evse, totalEnergy, currents), nil + return decorateEVSE(evse, currentPower, totalEnergy, currents), nil } // NewEVSEWifi creates EVSEWifi charger @@ -187,6 +193,12 @@ func (evse *EVSEWifi) ChargingTime() (time.Duration, error) { return time.Duration(params.Duration) * time.Millisecond, err } +// CurrentPower implements the Meter interface +func (evse *EVSEWifi) currentPower() (float64, error) { + params, err := evse.getParameters() + return 1000 * params.ActualPower, err +} + // TotalEnergy implements the MeterEnergy interface func (evse *EVSEWifi) totalEnergy() (float64, error) { params, err := evse.getParameters() diff --git a/charger/evsewifi_decorators.go b/charger/evsewifi_decorators.go index d7b0c7eda..c573302e4 100644 --- a/charger/evsewifi_decorators.go +++ b/charger/evsewifi_decorators.go @@ -6,12 +6,23 @@ import ( "github.com/andig/evcc/api" ) -func decorateEVSE(base api.Charger, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error)) api.Charger { +func decorateEVSE(base api.Charger, meter func() (float64, error), meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error)) api.Charger { switch { - case meterCurrent == nil && meterEnergy == nil: + case meter == nil && meterCurrent == nil && meterEnergy == nil: return base - case meterCurrent == nil && meterEnergy != nil: + case meter != nil && meterCurrent == nil && meterEnergy == nil: + return &struct{ + api.Charger + api.Meter + }{ + Charger: base, + Meter: &decorateEVSEMeterImpl{ + meter: meter, + }, + } + + case meter == nil && meterCurrent == nil && meterEnergy != nil: return &struct{ api.Charger api.MeterEnergy @@ -22,7 +33,22 @@ func decorateEVSE(base api.Charger, meterEnergy func() (float64, error), meterCu }, } - case meterCurrent != nil && meterEnergy == nil: + case meter != nil && meterCurrent == nil && meterEnergy != nil: + return &struct{ + api.Charger + api.Meter + api.MeterEnergy + }{ + Charger: base, + Meter: &decorateEVSEMeterImpl{ + meter: meter, + }, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case meter == nil && meterCurrent != nil && meterEnergy == nil: return &struct{ api.Charger api.MeterCurrent @@ -33,7 +59,22 @@ func decorateEVSE(base api.Charger, meterEnergy func() (float64, error), meterCu }, } - case meterCurrent != nil && meterEnergy != nil: + case meter != nil && meterCurrent != nil && meterEnergy == nil: + return &struct{ + api.Charger + api.Meter + api.MeterCurrent + }{ + Charger: base, + Meter: &decorateEVSEMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateEVSEMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + } + + case meter == nil && meterCurrent != nil && meterEnergy != nil: return &struct{ api.Charger api.MeterCurrent @@ -47,11 +88,38 @@ func decorateEVSE(base api.Charger, meterEnergy func() (float64, error), meterCu meterEnergy: meterEnergy, }, } + + case meter != nil && meterCurrent != nil && meterEnergy != nil: + return &struct{ + api.Charger + api.Meter + api.MeterCurrent + api.MeterEnergy + }{ + Charger: base, + Meter: &decorateEVSEMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateEVSEMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } } return nil } +type decorateEVSEMeterImpl struct { + meter func() (float64, error) +} + +func (impl *decorateEVSEMeterImpl) CurrentPower() (float64, error) { + return impl.meter() +} + type decorateEVSEMeterCurrentImpl struct { meterCurrent func() (float64, float64, float64, error) }