Bender: Detect meter availability (#3146)
This commit is contained in:
parent
50652f0833
commit
e3a598add8
2 changed files with 294 additions and 12 deletions
|
|
@ -26,6 +26,7 @@ package charger
|
|||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
|
|
@ -76,6 +77,8 @@ 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)"
|
||||
|
||||
// NewBenderCC creates BenderCC charger
|
||||
func NewBenderCC(uri string, id uint8) (api.Charger, error) {
|
||||
conn, err := modbus.NewConnection(uri, "", "", 0, modbus.Tcp, id)
|
||||
|
|
@ -95,6 +98,12 @@ func NewBenderCC(uri string, id uint8) (api.Charger, error) {
|
|||
current: 6, // assume min current
|
||||
}
|
||||
|
||||
// check presence of metering
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegActivePower, 2)
|
||||
if err == nil && (binary.BigEndian.Uint32(b) != math.MaxUint32) {
|
||||
return decorateBenderCC(wb, wb.currentPower, wb.currents, wb.chargedEnergy, wb.totalEnergy), nil
|
||||
}
|
||||
|
||||
return wb, err
|
||||
}
|
||||
|
||||
|
|
@ -176,10 +185,8 @@ func (wb *BenderCC) ChargingTime() (time.Duration, error) {
|
|||
return time.Duration(binary.BigEndian.Uint32(b)) * time.Second, nil
|
||||
}
|
||||
|
||||
var _ api.Meter = (*BenderCC)(nil)
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (wb *BenderCC) CurrentPower() (float64, error) {
|
||||
func (wb *BenderCC) currentPower() (float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegActivePower, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -188,10 +195,8 @@ func (wb *BenderCC) CurrentPower() (float64, error) {
|
|||
return float64(binary.BigEndian.Uint32(b)), nil
|
||||
}
|
||||
|
||||
var _ api.ChargeRater = (*BenderCC)(nil)
|
||||
|
||||
// ChargedEnergy implements the api.ChargeRater interface
|
||||
func (wb *BenderCC) ChargedEnergy() (float64, error) {
|
||||
func (wb *BenderCC) chargedEnergy() (float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegChargedEnergy, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -200,10 +205,8 @@ func (wb *BenderCC) ChargedEnergy() (float64, error) {
|
|||
return float64(binary.BigEndian.Uint32(b)) / 1e3, nil
|
||||
}
|
||||
|
||||
var _ api.MeterEnergy = (*BenderCC)(nil)
|
||||
|
||||
// TotalEnergy implements the api.MeterEnergy interface
|
||||
func (wb *BenderCC) TotalEnergy() (float64, error) {
|
||||
func (wb *BenderCC) totalEnergy() (float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegTotalEnergy, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
@ -212,10 +215,8 @@ func (wb *BenderCC) TotalEnergy() (float64, error) {
|
|||
return float64(binary.BigEndian.Uint32(b)) / 1e3, nil
|
||||
}
|
||||
|
||||
var _ api.MeterCurrent = (*BenderCC)(nil)
|
||||
|
||||
// Currents implements the api.MeterCurrent interface
|
||||
func (wb *BenderCC) Currents() (float64, float64, float64, error) {
|
||||
func (wb *BenderCC) currents() (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegCurrents, 6)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
|
|
|
|||
281
charger/bender_decorators.go
Normal file
281
charger/bender_decorators.go
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
package charger
|
||||
|
||||
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
|
||||
|
||||
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 {
|
||||
switch {
|
||||
case chargeRater == nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return base
|
||||
|
||||
case chargeRater == nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterCurrent
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type decorateBenderCCChargeRaterImpl struct {
|
||||
chargeRater func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateBenderCCChargeRaterImpl) ChargedEnergy() (float64, error) {
|
||||
return impl.chargeRater()
|
||||
}
|
||||
|
||||
type decorateBenderCCMeterImpl struct {
|
||||
meter func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateBenderCCMeterImpl) CurrentPower() (float64, error) {
|
||||
return impl.meter()
|
||||
}
|
||||
|
||||
type decorateBenderCCMeterCurrentImpl struct {
|
||||
meterCurrent func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateBenderCCMeterCurrentImpl) Currents() (float64, float64, float64, error) {
|
||||
return impl.meterCurrent()
|
||||
}
|
||||
|
||||
type decorateBenderCCMeterEnergyImpl struct {
|
||||
meterEnergy func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateBenderCCMeterEnergyImpl) TotalEnergy() (float64, error) {
|
||||
return impl.meterEnergy()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue