diff --git a/charger/bender.go b/charger/bender.go index 007544da97..f26e7b238f 100644 --- a/charger/bender.go +++ b/charger/bender.go @@ -82,7 +82,7 @@ func NewBenderCCFromConfig(other map[string]interface{}) (api.Charger, error) { return NewBenderCC(cc.URI, cc.ID) } -//go:generate go run ../cmd/tools/decorate.go -f decorateBenderCC -b *BenderCC -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.ChargeRater,ChargedEnergy,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" +//go:generate go run ../cmd/tools/decorate.go -f decorateBenderCC -b *BenderCC -r api.Charger -t "api.Meter,CurrentPower,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.ChargeRater,ChargedEnergy,func() (float64, error)" -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.Identifier,Identify,func() (string, error)" // NewBenderCC creates BenderCC charger func NewBenderCC(uri string, id uint8) (api.Charger, error) { @@ -108,6 +108,14 @@ func NewBenderCC(uri string, id uint8) (api.Charger, error) { wb.legacy = true } + var ( + currentPower func() (float64, error) + currents func() (float64, float64, float64, error) + chargedEnergy func() (float64, error) + totalEnergy func() (float64, error) + identify func() (string, error) + ) + // check presence of metering reg := uint16(bendRegActivePower) if wb.legacy { @@ -115,10 +123,18 @@ func NewBenderCC(uri string, id uint8) (api.Charger, error) { } if b, err := wb.conn.ReadHoldingRegisters(reg, 2); err == nil && binary.BigEndian.Uint32(b) != math.MaxUint32 { - return decorateBenderCC(wb, wb.currentPower, wb.currents, wb.chargedEnergy, wb.totalEnergy), nil + currentPower = wb.currentPower + currents = wb.currents + chargedEnergy = wb.chargedEnergy + totalEnergy = wb.totalEnergy + } + + // check rfid + if _, err := wb.identify(); err == nil { + identify = wb.identify } - return wb, err + return decorateBenderCC(wb, currentPower, currents, chargedEnergy, totalEnergy, identify), nil } // Status implements the api.Charger interface @@ -277,10 +293,8 @@ func (wb *BenderCC) currents() (float64, float64, float64, error) { return curr[0], curr[1], curr[2], nil } -var _ api.Identifier = (*BenderCC)(nil) - -// Identify implements the api.Identifier interface -func (wb *BenderCC) Identify() (string, error) { +// identify implements the api.Identifier interface +func (wb *BenderCC) identify() (string, error) { if !wb.legacy { var id []byte diff --git a/charger/bender_decorators.go b/charger/bender_decorators.go index efbd54330f..ed1f397140 100644 --- a/charger/bender_decorators.go +++ b/charger/bender_decorators.go @@ -6,12 +6,12 @@ import ( "github.com/evcc-io/evcc/api" ) -func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurrent func() (float64, float64, float64, error), chargeRater func() (float64, error), meterEnergy func() (float64, error)) api.Charger { +func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurrent func() (float64, float64, float64, error), chargeRater func() (float64, error), meterEnergy func() (float64, error), identifier func() (string, error)) api.Charger { switch { - case chargeRater == nil && meter == nil && meterCurrent == nil && meterEnergy == nil: + case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil: return base - case chargeRater == nil && meter != nil && meterCurrent == nil && meterEnergy == nil: + case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil: return &struct { *BenderCC api.Meter @@ -22,7 +22,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter == nil && meterCurrent != nil && meterEnergy == nil: + case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil: return &struct { *BenderCC api.MeterCurrent @@ -33,7 +33,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter != nil && meterCurrent != nil && meterEnergy == nil: + case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil: return &struct { *BenderCC api.Meter @@ -48,7 +48,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter == nil && meterCurrent == nil && meterEnergy == nil: + case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil: return &struct { *BenderCC api.ChargeRater @@ -59,7 +59,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter != nil && meterCurrent == nil && meterEnergy == nil: + case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil: return &struct { *BenderCC api.ChargeRater @@ -74,7 +74,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter == nil && meterCurrent != nil && meterEnergy == nil: + case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil: return &struct { *BenderCC api.ChargeRater @@ -89,7 +89,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter != nil && meterCurrent != nil && meterEnergy == nil: + case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil: return &struct { *BenderCC api.ChargeRater @@ -108,7 +108,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter == nil && meterCurrent == nil && meterEnergy != nil: + case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil: return &struct { *BenderCC api.MeterEnergy @@ -119,7 +119,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter != nil && meterCurrent == nil && meterEnergy != nil: + case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil: return &struct { *BenderCC api.Meter @@ -134,7 +134,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter == nil && meterCurrent != nil && meterEnergy != nil: + case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil: return &struct { *BenderCC api.MeterCurrent @@ -149,7 +149,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater == nil && meter != nil && meterCurrent != nil && meterEnergy != nil: + case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil: return &struct { *BenderCC api.Meter @@ -168,7 +168,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter == nil && meterCurrent == nil && meterEnergy != nil: + case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil: return &struct { *BenderCC api.ChargeRater @@ -183,7 +183,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter != nil && meterCurrent == nil && meterEnergy != nil: + case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil: return &struct { *BenderCC api.ChargeRater @@ -202,7 +202,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter == nil && meterCurrent != nil && meterEnergy != nil: + case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil: return &struct { *BenderCC api.ChargeRater @@ -221,7 +221,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren }, } - case chargeRater != nil && meter != nil && meterCurrent != nil && meterEnergy != nil: + case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil: return &struct { *BenderCC api.ChargeRater @@ -243,6 +243,310 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren meterEnergy: meterEnergy, }, } + + case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil: + return &struct { + *BenderCC + api.Identifier + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + } + + case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil: + return &struct { + *BenderCC + api.Identifier + api.Meter + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + } + + case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil: + return &struct { + *BenderCC + api.Identifier + api.MeterCurrent + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + } + + case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil: + return &struct { + *BenderCC + api.Identifier + api.Meter + api.MeterCurrent + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + } + + case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + } + + case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.Meter + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + } + + case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.MeterCurrent + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + } + + case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.Meter + api.MeterCurrent + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + } + + case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil: + return &struct { + *BenderCC + api.Identifier + api.MeterEnergy + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil: + return &struct { + *BenderCC + api.Identifier + api.Meter + api.MeterEnergy + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil: + return &struct { + *BenderCC + api.Identifier + api.MeterCurrent + api.MeterEnergy + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil: + return &struct { + *BenderCC + api.Identifier + api.Meter + api.MeterCurrent + api.MeterEnergy + }{ + BenderCC: base, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.MeterEnergy + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.Meter + api.MeterEnergy + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.MeterCurrent + api.MeterEnergy + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } + + case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil: + return &struct { + *BenderCC + api.ChargeRater + api.Identifier + api.Meter + api.MeterCurrent + api.MeterEnergy + }{ + BenderCC: base, + ChargeRater: &decorateBenderCCChargeRaterImpl{ + chargeRater: chargeRater, + }, + Identifier: &decorateBenderCCIdentifierImpl{ + identifier: identifier, + }, + Meter: &decorateBenderCCMeterImpl{ + meter: meter, + }, + MeterCurrent: &decorateBenderCCMeterCurrentImpl{ + meterCurrent: meterCurrent, + }, + MeterEnergy: &decorateBenderCCMeterEnergyImpl{ + meterEnergy: meterEnergy, + }, + } } return nil @@ -256,6 +560,14 @@ func (impl *decorateBenderCCChargeRaterImpl) ChargedEnergy() (float64, error) { return impl.chargeRater() } +type decorateBenderCCIdentifierImpl struct { + identifier func() (string, error) +} + +func (impl *decorateBenderCCIdentifierImpl) Identify() (string, error) { + return impl.identifier() +} + type decorateBenderCCMeterImpl struct { meter func() (float64, error) }