diff --git a/charger/evse/types.go b/charger/evse/types.go index 8556ec2d5..2f5734b17 100644 --- a/charger/evse/types.go +++ b/charger/evse/types.go @@ -27,5 +27,8 @@ type ListEntry struct { CurrentP1 float64 `json:"currentP1"` CurrentP2 float64 `json:"currentP2"` CurrentP3 float64 `json:"currentP3"` + VoltageP1 float64 `json:"voltageP1"` + VoltageP2 float64 `json:"voltageP2"` + VoltageP3 float64 `json:"voltageP3"` RFIDUID *string `json:"RFIDUID"` } diff --git a/charger/evsewifi.go b/charger/evsewifi.go index afab608f0..2ed4a4182 100644 --- a/charger/evsewifi.go +++ b/charger/evsewifi.go @@ -8,6 +8,7 @@ import ( "github.com/evcc-io/evcc/api" "github.com/evcc-io/evcc/charger/evse" + "github.com/evcc-io/evcc/provider" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/request" ) @@ -19,6 +20,7 @@ type EVSEWifi struct { alwaysActive bool current int64 // current will always be the physical value sent to the API hires bool + paramG provider.Cacheable[evse.ListEntry] } func init() { @@ -26,28 +28,31 @@ func init() { registry.Add("evsewifi", NewEVSEWifiFromConfig) } -// go:generate go run ../cmd/tools/decorate.go -f decorateEVSE -b *EVSEWifi -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.ChargerEx,MaxCurrentMillis,func(current float64) error" -t "api.Identifier,Identify,func() (string, error)" +// go:generate go run ../cmd/tools/decorate.go -f decorateEVSE -b *EVSEWifi -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.PhaseCurrents,Currents,func() (float64, float64, float64, error)" -t "api.PhaseVoltages,Voltages,func() (float64, float64, float64, error)" -t "api.ChargerEx,MaxCurrentMillis,func(current float64) error" -t "api.Identifier,Identify,func() (string, error)" // NewEVSEWifiFromConfig creates a EVSEWifi charger from generic config func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { - var cc struct { + cc := struct { URI string Meter struct { - Power, Energy, Currents bool + Power, Energy, Currents, Voltages bool } + Cache time.Duration + }{ + Cache: time.Second, } if err := util.DecodeOther(other, &cc); err != nil { return nil, err } - wb, err := NewEVSEWifi(util.DefaultScheme(cc.URI, "http")) + wb, err := NewEVSEWifi(util.DefaultScheme(cc.URI, "http"), cc.Cache) if err != nil { return wb, err } // auto-detect capabilities - params, err := wb.getParameters() + params, err := wb.paramG.Get() if err != nil { return wb, err } @@ -57,9 +62,10 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { } if params.UseMeter { - cc.Meter.Energy = true + cc.Meter.Power = true cc.Meter.Energy = true cc.Meter.Currents = true + cc.Meter.Voltages = true } if params.ActualCurrentMA != nil { @@ -68,7 +74,7 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { // decorate Charger with Meter var currentPower func() (float64, error) - if cc.Meter.Energy { + if cc.Meter.Power { currentPower = wb.currentPower } @@ -84,6 +90,12 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { currents = wb.currents } + // decorate Charger with PhaseVoltages + var voltages func() (float64, float64, float64, error) + if cc.Meter.Voltages { + voltages = wb.voltages + } + // decorate Charger with MaxCurrentEx var maxCurrentEx func(float64) error if wb.hires { @@ -97,11 +109,11 @@ func NewEVSEWifiFromConfig(other map[string]interface{}) (api.Charger, error) { identify = wb.identify } - return decorateEVSE(wb, currentPower, totalEnergy, currents, maxCurrentEx, identify), nil + return decorateEVSE(wb, currentPower, totalEnergy, currents, voltages, maxCurrentEx, identify), nil } // NewEVSEWifi creates EVSEWifi charger -func NewEVSEWifi(uri string) (*EVSEWifi, error) { +func NewEVSEWifi(uri string, cache time.Duration) (*EVSEWifi, error) { log := util.NewLogger("evse") wb := &EVSEWifi{ @@ -110,31 +122,27 @@ func NewEVSEWifi(uri string) (*EVSEWifi, error) { current: 6, // 6A defined value } + wb.paramG = provider.ResettableCached(func() (evse.ListEntry, error) { + var res evse.ParameterResponse + uri := fmt.Sprintf("%s/getParameters", wb.uri) + if err := wb.GetJSON(uri, &res); err != nil { + return evse.ListEntry{}, err + } + + if len(res.List) != 1 { + return evse.ListEntry{}, fmt.Errorf("unexpected response: %s", res.Type) + } + wb.alwaysActive = res.List[0].AlwaysActive + + return res.List[0], nil + }, cache) + return wb, nil } -// query evse parameters -func (wb *EVSEWifi) getParameters() (evse.ListEntry, error) { - var res evse.ParameterResponse - uri := fmt.Sprintf("%s/getParameters", wb.uri) - err := wb.GetJSON(uri, &res) - if err != nil { - return evse.ListEntry{}, err - } - - if len(res.List) != 1 { - return evse.ListEntry{}, fmt.Errorf("unexpected response: %s", res.Type) - } - - params := res.List[0] - wb.alwaysActive = params.AlwaysActive - - return params, nil -} - // Status implements the api.Charger interface func (wb *EVSEWifi) Status() (api.ChargeStatus, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() if err != nil { return api.StatusNone, err } @@ -157,7 +165,7 @@ func (wb *EVSEWifi) Status() (api.ChargeStatus, error) { // Enabled implements the api.Charger interface func (wb *EVSEWifi) Enabled() (bool, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() return params.EvseState, err } @@ -180,7 +188,13 @@ func (wb *EVSEWifi) Enable(enable bool) error { } uri = fmt.Sprintf("%s/setCurrent?current=%d", wb.uri, current) } - return wb.get(uri) + + err := wb.get(uri) + if err == nil { + wb.paramG.Reset() + } + + return err } // MaxCurrent implements the api.Charger interface @@ -190,7 +204,13 @@ func (wb *EVSEWifi) MaxCurrent(current int64) error { } wb.current = current uri := fmt.Sprintf("%s/setCurrent?current=%d", wb.uri, current) - return wb.get(uri) + + err := wb.get(uri) + if err == nil { + wb.paramG.Reset() + } + + return err } // maxCurrentEx implements the api.ChargerEx interface @@ -200,35 +220,33 @@ func (wb *EVSEWifi) maxCurrentEx(current float64) error { return wb.get(uri) } -var _ api.ChargeTimer = (*EVSEWifi)(nil) - -// ChargingTime implements the api.ChargeTimer interface -func (wb *EVSEWifi) ChargingTime() (time.Duration, error) { - params, err := wb.getParameters() - return time.Duration(params.Duration) * time.Millisecond, err -} - // CurrentPower implements the api.Meter interface func (wb *EVSEWifi) currentPower() (float64, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() return 1000 * params.ActualPower, err } // TotalEnergy implements the api.MeterEnergy interface func (wb *EVSEWifi) totalEnergy() (float64, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() return params.MeterReading, err } // Currents implements the api.PhaseCurrentss interface func (wb *EVSEWifi) currents() (float64, float64, float64, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() return params.CurrentP1, params.CurrentP2, params.CurrentP3, err } +// Voltages implements the api.PhaseCurrentss interface +func (wb *EVSEWifi) voltages() (float64, float64, float64, error) { + params, err := wb.paramG.Get() + return params.VoltageP1, params.VoltageP2, params.VoltageP3, err +} + // Identify implements the api.Identifier interface func (wb *EVSEWifi) identify() (string, error) { - params, err := wb.getParameters() + params, err := wb.paramG.Get() if err != nil { return "", err } @@ -237,12 +255,6 @@ func (wb *EVSEWifi) identify() (string, error) { return *params.RFIDUID, nil } -// // ChargedEnergy implements the ChargeRater interface -// func (wb *EVSEWifi) ChargedEnergy() (float64, error) { -// params, err := wb.getParameters() -// return params.Energy, err -// } - var _ api.Resurrector = (*EVSEWifi)(nil) // WakeUp implements the Resurrector interface diff --git a/charger/evsewifi_decorators.go b/charger/evsewifi_decorators.go index 60d6887a4..d032e0306 100644 --- a/charger/evsewifi_decorators.go +++ b/charger/evsewifi_decorators.go @@ -6,12 +6,12 @@ import ( "github.com/evcc-io/evcc/api" ) -func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy func() (float64, error), phaseCurrents func() (float64, float64, float64, error), chargerEx func(current float64) error, identifier func() (string, error)) api.Charger { +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(current float64) error, identifier func() (string, error)) api.Charger { switch { - case chargerEx == nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx == nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return base - case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Meter @@ -22,7 +22,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx == nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.MeterEnergy @@ -33,7 +33,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Meter @@ -48,7 +48,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx == nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.PhaseCurrents @@ -59,7 +59,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx == nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Meter @@ -74,7 +74,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx == nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.MeterEnergy @@ -89,7 +89,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx == nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Meter @@ -108,7 +108,143 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx == nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil: + return &struct { + *EVSEWifi + api.PhaseVoltages + }{ + EVSEWifi: base, + PhaseVoltages: &decorateEVSEPhaseVoltagesImpl{ + phaseVoltages: phaseVoltages, + }, + } + + 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.MeterEnergy + api.PhaseVoltages + }{ + EVSEWifi: base, + 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.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.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + 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.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.MeterEnergy + api.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + 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 && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -119,7 +255,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -134,7 +270,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx != nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -149,7 +285,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -168,7 +304,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx != nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -183,7 +319,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx != nil && identifier == nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -202,7 +338,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx != nil && identifier == nil && meter == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -221,7 +357,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx != nil && identifier == nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -244,7 +380,175 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx != nil && identifier == nil && meter == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil: + return &struct { + *EVSEWifi + api.ChargerEx + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + 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.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.MeterEnergy + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + 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.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.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + 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.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.MeterEnergy + api.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + 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 && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -255,7 +559,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -270,7 +574,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx == nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -285,7 +589,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -304,7 +608,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx == nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -319,7 +623,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx == nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -338,7 +642,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx == nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -357,7 +661,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx == nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.Identifier @@ -380,7 +684,175 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx == nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil: + return &struct { + *EVSEWifi + api.Identifier + api.PhaseVoltages + }{ + EVSEWifi: base, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.MeterEnergy + api.PhaseVoltages + }{ + EVSEWifi: base, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.MeterEnergy + api.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + 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 && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -395,7 +867,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil: + case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -414,7 +886,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx != nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -433,7 +905,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil: + case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents == nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -456,7 +928,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx != nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -475,7 +947,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil: + case chargerEx != nil && identifier != nil && meter != nil && meterEnergy == nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -498,7 +970,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx != nil && identifier != nil && meter == nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -521,7 +993,7 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun }, } - case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil: + case chargerEx != nil && identifier != nil && meter != nil && meterEnergy != nil && phaseCurrents != nil && phaseVoltages == nil: return &struct { *EVSEWifi api.ChargerEx @@ -547,6 +1019,206 @@ func decorateEVSE(base *EVSEWifi, meter func() (float64, error), meterEnergy fun phaseCurrents: phaseCurrents, }, } + + case chargerEx != nil && identifier != nil && meter == nil && meterEnergy == nil && phaseCurrents == nil && phaseVoltages != nil: + return &struct { + *EVSEWifi + api.ChargerEx + api.Identifier + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.MeterEnergy + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + 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.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.MeterEnergy + api.PhaseCurrents + api.PhaseVoltages + }{ + EVSEWifi: base, + ChargerEx: &decorateEVSEChargerExImpl{ + chargerEx: chargerEx, + }, + Identifier: &decorateEVSEIdentifierImpl{ + identifier: identifier, + }, + MeterEnergy: &decorateEVSEMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + 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 @@ -591,3 +1263,11 @@ type decorateEVSEPhaseCurrentsImpl struct { func (impl *decorateEVSEPhaseCurrentsImpl) Currents() (float64, float64, float64, error) { return impl.phaseCurrents() } + +type decorateEVSEPhaseVoltagesImpl struct { + phaseVoltages func() (float64, float64, float64, error) +} + +func (impl *decorateEVSEPhaseVoltagesImpl) Voltages() (float64, float64, float64, error) { + return impl.phaseVoltages() +} diff --git a/charger/evsewifi_test.go b/charger/evsewifi_test.go index 82625f662..ba09b9a86 100644 --- a/charger/evsewifi_test.go +++ b/charger/evsewifi_test.go @@ -21,13 +21,17 @@ func TestEvseWifi(t *testing.T) { "power": true, "energy": true, "currents": true, + "voltages": true, }, }) - if err != nil { t.Error(err) } + if _, ok := wb.(api.Meter); !ok { + t.Error("missing api.Meter") + } + if _, ok := wb.(api.MeterEnergy); !ok { t.Error("missing api.MeterEnergy") } @@ -36,8 +40,8 @@ func TestEvseWifi(t *testing.T) { t.Error("missing api.PhaseCurrents") } - if _, ok := wb.(api.ChargeTimer); !ok { - t.Error("missing ChargeTimer api") + if _, ok := wb.(api.PhaseVoltages); !ok { + t.Error("missing api.PhaseVoltages") } } @@ -50,7 +54,6 @@ func TestEvseWifiEx(t *testing.T) { wb, err := NewEVSEWifiFromConfig(map[string]interface{}{ "uri": ts.URL, }) - if err != nil { t.Error(err) } diff --git a/templates/definition/charger/smartwb.yaml b/templates/definition/charger/smartwb.yaml index 5dc8d400f..afa7d713d 100644 --- a/templates/definition/charger/smartwb.yaml +++ b/templates/definition/charger/smartwb.yaml @@ -11,3 +11,4 @@ render: | power: true energy: true currents: true + voltages: true