Add phase powers and currents (#5539)
This commit is contained in:
parent
b0c03705cb
commit
aed17532b0
23 changed files with 2060 additions and 151 deletions
16
api/api.go
16
api/api.go
|
|
@ -92,21 +92,31 @@ func (a ActionConfig) String() string {
|
|||
return strings.Join(s, ", ")
|
||||
}
|
||||
|
||||
// Meter is able to provide current power in W
|
||||
// Meter is able to provide total active power in W
|
||||
type Meter interface {
|
||||
CurrentPower() (float64, error)
|
||||
}
|
||||
|
||||
// MeterEnergy is able to provide current energy in kWh
|
||||
// MeterEnergy is able to provide total energy in kWh
|
||||
type MeterEnergy interface {
|
||||
TotalEnergy() (float64, error)
|
||||
}
|
||||
|
||||
// MeterCurrent is able to provide per-line current A
|
||||
// MeterCurrent is able to provide per-phase current A
|
||||
type MeterCurrent interface {
|
||||
Currents() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
// MeterVoltage is able to provide per-phase voltage V
|
||||
type MeterVoltage interface {
|
||||
Voltages() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
// MeterPower is able to provide signed per-phase power W
|
||||
type MeterPower interface {
|
||||
Powers() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
// Battery is able to provide battery Soc in %
|
||||
type Battery interface {
|
||||
Soc() (float64, error)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ const (
|
|||
abbRegStatus = 0x400C // Charging state 2 unsigned RO available
|
||||
abbRegGetCurrent = 0x400E // Current charging current limit 2 0.001 A unsigned RO
|
||||
abbRegCurrents = 0x4010 // Charging current phases 6 0.001 A unsigned RO available
|
||||
abbRegVoltages = 0x4016 // Voltage phases 6 0.1 V unsigned RO available
|
||||
abbRegPower = 0x401C // Active power 2 1 W unsigned RO available
|
||||
abbRegEnergy = 0x401E // Energy delivered in charging session 2 1 Wh unsigned RO available
|
||||
abbRegSetCurrent = 0x4100 // Set charging current limit 2 0.001 A unsigned WO available
|
||||
|
|
@ -225,6 +226,23 @@ func (wb *ABB) Currents() (float64, float64, float64, error) {
|
|||
return curr[0], curr[1], curr[2], nil
|
||||
}
|
||||
|
||||
var _ api.MeterVoltage = (*ABB)(nil)
|
||||
|
||||
// Voltages implements the api.MeterVoltage interface
|
||||
func (wb *ABB) Voltages() (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(abbRegVoltages, 6)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
var volt [3]float64
|
||||
for l := 0; l < 3; l++ {
|
||||
volt[l] = float64(binary.BigEndian.Uint32(b[4*l:])) / 10
|
||||
}
|
||||
|
||||
return volt[0], volt[1], volt[2], nil
|
||||
}
|
||||
|
||||
// var _ api.PhaseSwitcher = (*ABB)(nil)
|
||||
|
||||
// // Phases1p3p implements the api.PhaseSwitcher interface
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ const (
|
|||
bendRegCurrents = 212 // Currents from primary meter (mA)
|
||||
bendRegTotalEnergy = 218 // Total Energy from primary meter (Wh)
|
||||
bendRegActivePower = 220 // Active Power from primary meter (W)
|
||||
bendRegVoltages = 222 // Voltages of the ocpp meter (V)
|
||||
bendRegChargedEnergyLegacy = 705 // Sum of charged energy for the current session (Wh)
|
||||
bendRegChargingDurationLegacy = 709 // Duration since beginning of charge (Seconds)
|
||||
bendRegChargedEnergy = 716 // Sum of charged energy for the current session (Wh)
|
||||
|
|
@ -81,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)" -t "api.Identifier,Identify,func() (string, 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.MeterVoltage,Voltages,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) {
|
||||
|
|
@ -110,6 +111,7 @@ func NewBenderCC(uri string, id uint8) (api.Charger, error) {
|
|||
var (
|
||||
currentPower func() (float64, error)
|
||||
currents func() (float64, float64, float64, error)
|
||||
voltages func() (float64, float64, float64, error)
|
||||
chargedEnergy func() (float64, error)
|
||||
totalEnergy func() (float64, error)
|
||||
identify func() (string, error)
|
||||
|
|
@ -124,6 +126,7 @@ 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 {
|
||||
currentPower = wb.currentPower
|
||||
currents = wb.currents
|
||||
voltages = wb.voltages
|
||||
chargedEnergy = wb.chargedEnergy
|
||||
totalEnergy = wb.totalEnergy
|
||||
}
|
||||
|
|
@ -133,7 +136,7 @@ func NewBenderCC(uri string, id uint8) (api.Charger, error) {
|
|||
identify = wb.identify
|
||||
}
|
||||
|
||||
return decorateBenderCC(wb, currentPower, currents, chargedEnergy, totalEnergy, identify), nil
|
||||
return decorateBenderCC(wb, currentPower, currents, voltages, chargedEnergy, totalEnergy, identify), nil
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
|
|
@ -277,7 +280,7 @@ func (wb *BenderCC) totalEnergy() (float64, error) {
|
|||
return float64(binary.BigEndian.Uint32(b)) / 1e3, nil
|
||||
}
|
||||
|
||||
// Currents implements the api.MeterCurrent interface
|
||||
// currents implements the api.MeterCurrent interface
|
||||
func (wb *BenderCC) currents() (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegCurrents, 6)
|
||||
if err != nil {
|
||||
|
|
@ -292,6 +295,21 @@ func (wb *BenderCC) currents() (float64, float64, float64, error) {
|
|||
return curr[0], curr[1], curr[2], nil
|
||||
}
|
||||
|
||||
// voltages implements the api.MeterVoltage interface
|
||||
func (wb *BenderCC) voltages() (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadHoldingRegisters(bendRegVoltages, 6)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
var volt [3]float64
|
||||
for l := 0; l < 3; l++ {
|
||||
volt[l] = float64(binary.BigEndian.Uint32(b[4*l : 4*(l+1)]))
|
||||
}
|
||||
|
||||
return volt[0], volt[1], volt[2], nil
|
||||
}
|
||||
|
||||
// identify implements the api.Identifier interface
|
||||
func (wb *BenderCC) identify() (string, error) {
|
||||
if !wb.legacy {
|
||||
|
|
|
|||
|
|
@ -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), identifier func() (string, error)) api.Charger {
|
||||
func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurrent func() (float64, float64, float64, error), meterVoltage func() (float64, float64, float64, error), chargeRater func() (float64, error), meterEnergy func() (float64, error), identifier func() (string, error)) api.Charger {
|
||||
switch {
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return base
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
|
|
@ -22,7 +22,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
|
|
@ -33,7 +33,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
|
|
@ -48,7 +48,67 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -59,7 +119,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -74,7 +134,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -89,7 +149,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -108,7 +168,83 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterEnergy
|
||||
|
|
@ -119,7 +255,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
|
|
@ -134,7 +270,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
|
|
@ -149,7 +285,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
|
|
@ -168,7 +304,83 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -183,7 +395,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -202,7 +414,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -221,7 +433,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -244,7 +456,99 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier == nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -255,7 +559,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -270,7 +574,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -285,7 +589,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -304,7 +608,83 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -319,7 +699,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -338,7 +718,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -357,7 +737,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -380,7 +760,99 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -395,7 +867,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -414,7 +886,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -433,7 +905,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
|
|
@ -456,7 +928,99 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater == nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -475,7 +1039,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -498,7 +1062,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -521,7 +1085,7 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
|
|
@ -547,6 +1111,114 @@ func decorateBenderCC(base *BenderCC, meter func() (float64, error), meterCurren
|
|||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent == nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter == nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case chargeRater != nil && identifier != nil && meter != nil && meterCurrent != nil && meterEnergy != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
*BenderCC
|
||||
api.ChargeRater
|
||||
api.Identifier
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
BenderCC: base,
|
||||
ChargeRater: &decorateBenderCCChargeRaterImpl{
|
||||
chargeRater: chargeRater,
|
||||
},
|
||||
Identifier: &decorateBenderCCIdentifierImpl{
|
||||
identifier: identifier,
|
||||
},
|
||||
Meter: &decorateBenderCCMeterImpl{
|
||||
meter: meter,
|
||||
},
|
||||
MeterCurrent: &decorateBenderCCMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateBenderCCMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateBenderCCMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -591,3 +1263,11 @@ type decorateBenderCCMeterEnergyImpl struct {
|
|||
func (impl *decorateBenderCCMeterEnergyImpl) TotalEnergy() (float64, error) {
|
||||
return impl.meterEnergy()
|
||||
}
|
||||
|
||||
type decorateBenderCCMeterVoltageImpl struct {
|
||||
meterVoltage func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateBenderCCMeterVoltageImpl) Voltages() (float64, float64, float64, error) {
|
||||
return impl.meterVoltage()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ type HeidelbergEC struct {
|
|||
|
||||
const (
|
||||
hecRegVehicleStatus = 5 // Input
|
||||
hecRegCurrents = 6 // Input 6,7,8
|
||||
hecRegTemperature = 9 // Input
|
||||
hecRegVoltages = 10 // Input 10,11,12
|
||||
hecRegPower = 14 // Input
|
||||
hecRegEnergy = 17 // Input
|
||||
hecRegTimeoutConfig = 257 // Holding
|
||||
|
|
@ -49,8 +51,6 @@ const (
|
|||
hecStandbyDisabled = 4 // disable standby
|
||||
)
|
||||
|
||||
var hecRegCurrents = []uint16{6, 7, 8}
|
||||
|
||||
func init() {
|
||||
registry.Add("heidelberg", NewHeidelbergECFromConfig)
|
||||
}
|
||||
|
|
@ -244,17 +244,34 @@ var _ api.MeterCurrent = (*HeidelbergEC)(nil)
|
|||
|
||||
// Currents implements the api.MeterCurrent interface
|
||||
func (wb *HeidelbergEC) Currents() (float64, float64, float64, error) {
|
||||
var currents []float64
|
||||
for _, regCurrent := range hecRegCurrents {
|
||||
b, err := wb.conn.ReadInputRegisters(regCurrent, 1)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
currents = append(currents, float64(binary.BigEndian.Uint16(b))/10)
|
||||
b, err := wb.conn.ReadInputRegisters(abbRegCurrents, 3)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
return currents[0], currents[1], currents[2], nil
|
||||
var curr [3]float64
|
||||
for l := 0; l < 3; l++ {
|
||||
curr[l] = float64(binary.BigEndian.Uint16(b[2*l:])) / 10
|
||||
}
|
||||
|
||||
return curr[0], curr[1], curr[2], nil
|
||||
}
|
||||
|
||||
var _ api.MeterVoltage = (*HeidelbergEC)(nil)
|
||||
|
||||
// Voltages implements the api.MeterVoltage interface
|
||||
func (wb *HeidelbergEC) Voltages() (float64, float64, float64, error) {
|
||||
b, err := wb.conn.ReadInputRegisters(abbRegVoltages, 3)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
var volt [3]float64
|
||||
for l := 0; l < 3; l++ {
|
||||
volt[l] = float64(binary.BigEndian.Uint16(b[2*l:]))
|
||||
}
|
||||
|
||||
return volt[0], volt[1], volt[2], nil
|
||||
}
|
||||
|
||||
var _ api.Diagnosis = (*HeidelbergEC)(nil)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,22 @@ func (d *dumper) Dump(name string, v interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
if v, ok := v.(api.MeterVoltage); ok {
|
||||
if u1, u2, u3, err := v.Voltages(); err != nil {
|
||||
fmt.Fprintf(w, "Voltage L1..L3:\t%v\n", err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "Voltage L1..L3:\t%.3gV %.3gV %.3gV\n", u1, u2, u3)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := v.(api.MeterPower); ok {
|
||||
if p1, p2, p3, err := v.Powers(); err != nil {
|
||||
fmt.Fprintf(w, "Power L1..L3:\t%v\n", err)
|
||||
} else {
|
||||
fmt.Fprintf(w, "Power L1..L3:\t%.3gW %.3gW %.3gW\n", p1, p2, p3)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := v.(api.Battery); ok {
|
||||
var soc float64
|
||||
var err error
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ const (
|
|||
timerInactive = "inactive"
|
||||
|
||||
minActiveCurrent = 1.0 // minimum current at which a phase is treated as active
|
||||
minActiveVoltage = 208 // minimum voltage at which a phase is treated as active
|
||||
vehicleDetectInterval = 1 * time.Minute
|
||||
vehicleDetectDuration = 10 * time.Minute
|
||||
|
||||
|
|
@ -1579,7 +1580,7 @@ func (lp *Loadpoint) updateChargeCurrents() {
|
|||
if lp.charging() {
|
||||
// Quine-McCluskey for (¬L1∧L2∧¬L3) ∨ (¬L1∧¬L2∧L3) ∨ (L1∧¬L2∧L3) ∨ (¬L1∧L2∧L3) -> ¬L1 ∧ L2 ∨ ¬L2 ∧ L3
|
||||
if !(i1 > minActiveCurrent) && (i2 > minActiveCurrent) || !(i2 > minActiveCurrent) && (i3 > minActiveCurrent) {
|
||||
lp.log.WARN.Printf("invalid phase wiring between charge meter and vehicle")
|
||||
lp.log.WARN.Printf("invalid phase wiring between charge meter and charger")
|
||||
}
|
||||
|
||||
var phases int
|
||||
|
|
@ -1600,6 +1601,42 @@ func (lp *Loadpoint) updateChargeCurrents() {
|
|||
}
|
||||
}
|
||||
|
||||
// updateChargeVoltages uses MeterVoltage interface to count phases with nominal grid voltage
|
||||
func (lp *Loadpoint) updateChargeVoltages() {
|
||||
phaseMeter, ok := lp.chargeMeter.(api.MeterVoltage)
|
||||
if !ok {
|
||||
return // don't guess
|
||||
}
|
||||
|
||||
u1, u2, u3, err := phaseMeter.Voltages()
|
||||
if err != nil {
|
||||
lp.log.ERROR.Printf("charge meter: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
chargeVoltages := []float64{u1, u2, u3}
|
||||
lp.log.DEBUG.Printf("charge voltages: %.3gV", chargeVoltages)
|
||||
lp.publish("chargeVoltages", chargeVoltages)
|
||||
|
||||
// Quine-McCluskey for (¬L1∧L2∧¬L3) ∨ (L1∧L2∧¬L3) ∨ (¬L1∧¬L2∧L3) ∨ (L1∧¬L2∧L3) ∨ (¬L1∧L2∧L3) -> ¬L1 ∧ L3 ∨ L2 ∧ ¬L3 ∨ ¬L2 ∧ L3
|
||||
if !(u1 > minActiveVoltage) && (u3 > minActiveVoltage) || (u2 > minActiveVoltage) && !(u3 > minActiveVoltage) || !(u2 > minActiveVoltage) && (u3 > minActiveVoltage) {
|
||||
lp.log.WARN.Printf("invalid phase wiring between charge meter and charger")
|
||||
}
|
||||
|
||||
var phases int
|
||||
if (u1 > minActiveVoltage) || (u2 > minActiveVoltage) || (u3 > minActiveVoltage) {
|
||||
phases = 3
|
||||
}
|
||||
if (u1 > minActiveVoltage) && (u2 < minActiveVoltage) && (u3 < minActiveVoltage) {
|
||||
phases = 1
|
||||
}
|
||||
|
||||
if phases >= 1 {
|
||||
lp.log.DEBUG.Printf("detected phases: %dp", phases)
|
||||
lp.setPhases(phases)
|
||||
}
|
||||
}
|
||||
|
||||
// publish charged energy and duration
|
||||
func (lp *Loadpoint) publishChargeProgress() {
|
||||
if f, err := lp.chargeRater.ChargedEnergy(); err == nil {
|
||||
|
|
@ -1747,6 +1784,7 @@ func (lp *Loadpoint) Update(sitePower float64, batteryBuffered bool) {
|
|||
lp.publish("mode", mode)
|
||||
|
||||
// read and publish meters first- charge power has already been updated by the site
|
||||
lp.updateChargeVoltages()
|
||||
lp.updateChargeCurrents()
|
||||
|
||||
// update ChargeRater here to make sure initial meter update is caught
|
||||
|
|
|
|||
27
core/site.go
27
core/site.go
|
|
@ -437,12 +437,35 @@ func (site *Site) updateMeters() error {
|
|||
|
||||
err := retryMeter("grid", site.gridMeter, &site.gridPower)
|
||||
|
||||
// voltages
|
||||
if phaseMeter, ok := site.gridMeter.(api.MeterVoltage); err == nil && ok {
|
||||
u1, u2, u3, err := phaseMeter.Voltages()
|
||||
if err == nil {
|
||||
site.log.DEBUG.Printf("grid voltages: %.3gV", []float64{u1, u2, u3})
|
||||
site.publish("gridVoltages", []float64{u1, u2, u3})
|
||||
} else {
|
||||
site.log.ERROR.Printf("grid meter voltages: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// powers
|
||||
var p1, p2, p3 float64
|
||||
if phaseMeter, ok := site.gridMeter.(api.MeterPower); err == nil && ok {
|
||||
p1, p2, p3, err = phaseMeter.Powers()
|
||||
if err == nil {
|
||||
site.log.DEBUG.Printf("grid powers: %.3gW", []float64{p1, p2, p3})
|
||||
site.publish("gridPowers", []float64{p1, p2, p3})
|
||||
} else {
|
||||
site.log.ERROR.Printf("grid meter powers: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// currents
|
||||
if phaseMeter, ok := site.gridMeter.(api.MeterCurrent); err == nil && ok {
|
||||
i1, i2, i3, err := phaseMeter.Currents()
|
||||
if err == nil {
|
||||
site.log.DEBUG.Printf("grid currents: %.3gA", []float64{i1, i2, i3})
|
||||
site.publish("gridCurrents", []float64{i1, i2, i3})
|
||||
site.log.DEBUG.Printf("grid currents: %.3gA", []float64{util.SignFromPower(i1, p1), util.SignFromPower(i2, p2), util.SignFromPower(i3, p3)})
|
||||
site.publish("gridCurrents", []float64{util.SignFromPower(i1, p1), util.SignFromPower(i2, p2), util.SignFromPower(i3, p3)})
|
||||
} else {
|
||||
site.log.ERROR.Printf("grid meter currents: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ func init() {
|
|||
registry.Add(api.Custom, NewConfigurableFromConfig)
|
||||
}
|
||||
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateMeter -b api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)"
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateMeter -b api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.MeterVoltage,Voltages,func() (float64, float64, float64, error)" -t "api.MeterPower,Powers,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)"
|
||||
|
||||
// NewConfigurableFromConfig creates api.Meter from config
|
||||
func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error) {
|
||||
|
|
@ -22,6 +22,8 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
Energy *provider.Config // optional
|
||||
Soc *provider.Config // optional
|
||||
Currents []provider.Config // optional
|
||||
Voltages []provider.Config // optional
|
||||
Powers []provider.Config // optional
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
|
|
@ -35,7 +37,7 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
|
||||
m, _ := NewConfigurable(power)
|
||||
|
||||
// decorate Meter with MeterEnergy
|
||||
// decorate energy
|
||||
var totalEnergyG func() (float64, error)
|
||||
if cc.Energy != nil {
|
||||
totalEnergyG, err = provider.NewFloatGetterFromConfig(*cc.Energy)
|
||||
|
|
@ -44,27 +46,25 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
}
|
||||
}
|
||||
|
||||
// decorate Meter with MeterCurrent
|
||||
var currentsG func() (float64, float64, float64, error)
|
||||
if len(cc.Currents) > 0 {
|
||||
if len(cc.Currents) != 3 {
|
||||
return nil, errors.New("need 3 currents")
|
||||
}
|
||||
|
||||
var curr []func() (float64, error)
|
||||
for idx, cc := range cc.Currents {
|
||||
c, err := provider.NewFloatGetterFromConfig(cc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("currents[%d]: %w", idx, err)
|
||||
}
|
||||
|
||||
curr = append(curr, c)
|
||||
}
|
||||
|
||||
currentsG = collectCurrentProviders(curr)
|
||||
// decorate currents
|
||||
currentsG, err := buildPhaseProviders(cc.Currents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("currents: %w", err)
|
||||
}
|
||||
|
||||
// decorate Meter with BatterySoc
|
||||
// decorate voltages
|
||||
voltagesG, err := buildPhaseProviders(cc.Voltages)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("voltages: %w", err)
|
||||
}
|
||||
|
||||
// decorate powers
|
||||
powersG, err := buildPhaseProviders(cc.Powers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("powers: %w", err)
|
||||
}
|
||||
|
||||
// decorate soc
|
||||
var batterySocG func() (float64, error)
|
||||
if cc.Soc != nil {
|
||||
batterySocG, err = provider.NewFloatGetterFromConfig(*cc.Soc)
|
||||
|
|
@ -73,25 +73,48 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
}
|
||||
}
|
||||
|
||||
res := m.Decorate(totalEnergyG, currentsG, batterySocG)
|
||||
res := m.Decorate(totalEnergyG, currentsG, voltagesG, powersG, batterySocG)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// collectCurrentProviders combines phase getters into currents api function
|
||||
func collectCurrentProviders(g []func() (float64, error)) func() (float64, float64, float64, error) {
|
||||
func buildPhaseProviders(providers []provider.Config) (func() (float64, float64, float64, error), error) {
|
||||
var res func() (float64, float64, float64, error)
|
||||
if len(providers) > 0 {
|
||||
if len(providers) != 3 {
|
||||
return nil, errors.New("need one per phase, total three")
|
||||
}
|
||||
|
||||
phases := make([]func() (float64, error), 0, 3)
|
||||
for idx, prov := range providers {
|
||||
c, err := provider.NewFloatGetterFromConfig(prov)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%d] %w", idx, err)
|
||||
}
|
||||
|
||||
phases = append(phases, c)
|
||||
}
|
||||
|
||||
res = collectPhaseProviders(phases)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// collectPhaseProviders combines phase getters into currents api function
|
||||
func collectPhaseProviders(g []func() (float64, error)) func() (float64, float64, float64, error) {
|
||||
return func() (float64, float64, float64, error) {
|
||||
var currents []float64
|
||||
var res []float64
|
||||
for _, currentG := range g {
|
||||
c, err := currentG()
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
currents = append(currents, c)
|
||||
res = append(res, c)
|
||||
}
|
||||
|
||||
return currents[0], currents[1], currents[2], nil
|
||||
return res[0], res[1], res[2], nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,9 +135,11 @@ type Meter struct {
|
|||
func (m *Meter) Decorate(
|
||||
totalEnergy func() (float64, error),
|
||||
currents func() (float64, float64, float64, error),
|
||||
voltages func() (float64, float64, float64, error),
|
||||
powers func() (float64, float64, float64, error),
|
||||
batterySoc func() (float64, error),
|
||||
) api.Meter {
|
||||
return decorateMeter(m, totalEnergy, currents, batterySoc)
|
||||
return decorateMeter(m, totalEnergy, currents, voltages, powers, batterySoc)
|
||||
}
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
|
|
|
|||
|
|
@ -55,7 +55,19 @@ func NewMovingAverageFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
currents = m.Currents
|
||||
}
|
||||
|
||||
res := meter.Decorate(totalEnergy, currents, batterySoc)
|
||||
// decorate voltages reading
|
||||
var voltages func() (float64, float64, float64, error)
|
||||
if m, ok := m.(api.MeterVoltage); ok {
|
||||
voltages = m.Voltages
|
||||
}
|
||||
|
||||
// decorate powers reading
|
||||
var powers func() (float64, float64, float64, error)
|
||||
if m, ok := m.(api.MeterPower); ok {
|
||||
powers = m.Powers
|
||||
}
|
||||
|
||||
res := meter.Decorate(totalEnergy, currents, voltages, powers, batterySoc)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
|
||||
func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error), meterVoltage func() (float64, float64, float64, error), meterPower func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
|
||||
switch {
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return base
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
|
|
@ -22,7 +22,7 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
|
|
@ -33,7 +33,7 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
|
|
@ -48,7 +48,203 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -59,7 +255,7 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -74,7 +270,7 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -89,7 +285,7 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -107,6 +303,250 @@ func decorateMeter(base api.Meter, meterEnergy func() (float64, error), meterCur
|
|||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateMeterBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateMeterMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateMeterMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateMeterMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateMeterMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -135,3 +575,19 @@ type decorateMeterMeterEnergyImpl struct {
|
|||
func (impl *decorateMeterMeterEnergyImpl) TotalEnergy() (float64, error) {
|
||||
return impl.meterEnergy()
|
||||
}
|
||||
|
||||
type decorateMeterMeterPowerImpl struct {
|
||||
meterPower func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateMeterMeterPowerImpl) Powers() (float64, float64, float64, error) {
|
||||
return impl.meterPower()
|
||||
}
|
||||
|
||||
type decorateMeterMeterVoltageImpl struct {
|
||||
meterVoltage func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateMeterMeterVoltageImpl) Voltages() (float64, float64, float64, error) {
|
||||
return impl.meterVoltage()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func init() {
|
|||
registry.Add("modbus", NewModbusFromConfig)
|
||||
}
|
||||
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateModbus -b api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)"
|
||||
//go:generate go run ../cmd/tools/decorate.go -f decorateModbus -b api.Meter -t "api.MeterEnergy,TotalEnergy,func() (float64, error)" -t "api.MeterCurrent,Currents,func() (float64, float64, float64, error)" -t "api.MeterVoltage,Voltages,func() (float64, float64, float64, error)" -t "api.MeterPower,Powers,func() (float64, float64, float64, error)" -t "api.Battery,Soc,func() (float64, error)"
|
||||
|
||||
// NewModbusFromConfig creates api.Meter from config
|
||||
func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
||||
|
|
@ -35,6 +35,8 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
modbus.Settings `mapstructure:",squash"`
|
||||
Power, Energy, Soc string
|
||||
Currents []string
|
||||
Voltages []string
|
||||
Powers []string
|
||||
Delay time.Duration
|
||||
Timeout time.Duration
|
||||
}{
|
||||
|
|
@ -97,7 +99,7 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
return nil, fmt.Errorf("invalid measurement for power: %s", cc.Power)
|
||||
}
|
||||
|
||||
// decorate energy reading
|
||||
// decorate energy
|
||||
var totalEnergy func() (float64, error)
|
||||
if cc.Energy != "" {
|
||||
if err := modbus.ParseOperation(device, cc.Energy, &m.opEnergy); err != nil {
|
||||
|
|
@ -107,32 +109,25 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
totalEnergy = m.totalEnergy
|
||||
}
|
||||
|
||||
// decorate Meter with MeterCurrent
|
||||
var currentsG func() (float64, float64, float64, error)
|
||||
if len(cc.Currents) > 0 {
|
||||
if len(cc.Currents) != 3 {
|
||||
return nil, errors.New("need 3 currents")
|
||||
}
|
||||
|
||||
var curr []func() (float64, error)
|
||||
for _, cc := range cc.Currents {
|
||||
var opCurrent modbus.Operation
|
||||
|
||||
if err := modbus.ParseOperation(device, cc, &opCurrent); err != nil {
|
||||
return nil, fmt.Errorf("invalid measurement for current: %s", cc)
|
||||
}
|
||||
|
||||
c := func() (float64, error) {
|
||||
return m.floatGetter(opCurrent)
|
||||
}
|
||||
|
||||
curr = append(curr, c)
|
||||
}
|
||||
|
||||
currentsG = collectCurrentProviders(curr)
|
||||
// decorate currents
|
||||
currentsG, err := m.buildPhaseProviders(cc.Currents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("currents: %w", err)
|
||||
}
|
||||
|
||||
// decorate soc reading
|
||||
// decorate voltages
|
||||
voltagesG, err := m.buildPhaseProviders(cc.Voltages)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("voltages: %w", err)
|
||||
}
|
||||
|
||||
// decorate powers
|
||||
powersG, err := m.buildPhaseProviders(cc.Powers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("powers: %w", err)
|
||||
}
|
||||
|
||||
// decorate soc
|
||||
var soc func() (float64, error)
|
||||
if cc.Soc != "" {
|
||||
if err := modbus.ParseOperation(device, cc.Soc, &m.opSoc); err != nil {
|
||||
|
|
@ -142,7 +137,35 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
soc = m.soc
|
||||
}
|
||||
|
||||
return decorateModbus(m, totalEnergy, currentsG, soc), nil
|
||||
return decorateModbus(m, totalEnergy, currentsG, voltagesG, powersG, soc), nil
|
||||
}
|
||||
|
||||
func (m *Modbus) buildPhaseProviders(readings []string) (func() (float64, float64, float64, error), error) {
|
||||
var res func() (float64, float64, float64, error)
|
||||
if len(readings) > 0 {
|
||||
if len(readings) != 3 {
|
||||
return nil, errors.New("need one per phase, total three")
|
||||
}
|
||||
|
||||
phases := make([]func() (float64, error), 0, 3)
|
||||
for idx, reading := range readings {
|
||||
var opCurrent modbus.Operation
|
||||
|
||||
if err := modbus.ParseOperation(m.device, reading, &opCurrent); err != nil {
|
||||
return nil, fmt.Errorf("invalid measurement [%d]: %s", idx, reading)
|
||||
}
|
||||
|
||||
c := func() (float64, error) {
|
||||
return m.floatGetter(opCurrent)
|
||||
}
|
||||
|
||||
phases = append(phases, c)
|
||||
}
|
||||
|
||||
res = collectPhaseProviders(phases)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// floatGetter executes configured modbus read operation and implements func() (float64, error)
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import (
|
|||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
|
||||
func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error), meterVoltage func() (float64, float64, float64, error), meterPower func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
|
||||
switch {
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return base
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
|
|
@ -22,7 +22,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
|
|
@ -33,7 +33,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
|
|
@ -48,7 +48,203 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -59,7 +255,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -74,7 +270,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -89,7 +285,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -107,6 +303,250 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCu
|
|||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower == nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil && meterPower != nil && meterVoltage != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
api.MeterPower
|
||||
api.MeterVoltage
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
MeterPower: &decorateModbusMeterPowerImpl{
|
||||
meterPower: meterPower,
|
||||
},
|
||||
MeterVoltage: &decorateModbusMeterVoltageImpl{
|
||||
meterVoltage: meterVoltage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -135,3 +575,19 @@ type decorateModbusMeterEnergyImpl struct {
|
|||
func (impl *decorateModbusMeterEnergyImpl) TotalEnergy() (float64, error) {
|
||||
return impl.meterEnergy()
|
||||
}
|
||||
|
||||
type decorateModbusMeterPowerImpl struct {
|
||||
meterPower func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateModbusMeterPowerImpl) Powers() (float64, float64, float64, error) {
|
||||
return impl.meterPower()
|
||||
}
|
||||
|
||||
type decorateModbusMeterVoltageImpl struct {
|
||||
meterVoltage func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateModbusMeterVoltageImpl) Voltages() (float64, float64, float64, error) {
|
||||
return impl.meterVoltage()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ func NewOpenWBFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
curr = append(curr, current)
|
||||
}
|
||||
|
||||
currents = collectCurrentProviders(curr)
|
||||
currents = collectPhaseProviders(curr)
|
||||
|
||||
case "pv":
|
||||
configuredG := boolG(fmt.Sprintf("%s/pv/1/%s", cc.Topic, openwb.PvConfigured)) // first pv
|
||||
|
|
@ -111,7 +111,7 @@ func NewOpenWBFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
res := m.Decorate(nil, currents, soc)
|
||||
res := m.Decorate(nil, currents, nil, nil, soc)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
|||
40
meter/sma.go
40
meter/sma.go
|
|
@ -117,14 +117,52 @@ var _ api.MeterCurrent = (*SMA)(nil)
|
|||
func (sm *SMA) Currents() (float64, float64, float64, error) {
|
||||
values, err := sm.device.Values()
|
||||
|
||||
var powers [3]float64
|
||||
for i, id := range []sunny.ValueID{sunny.ActivePowerMinusL1, sunny.ActivePowerMinusL2, sunny.ActivePowerMinusL3} {
|
||||
if p := sma.AsFloat(values[id]); p > 0 {
|
||||
powers[i] = -p
|
||||
}
|
||||
}
|
||||
|
||||
var currents [3]float64
|
||||
for i, id := range []sunny.ValueID{sunny.CurrentL1, sunny.CurrentL2, sunny.CurrentL3} {
|
||||
currents[i] = sma.AsFloat(values[id])
|
||||
currents[i] = util.SignFromPower(sma.AsFloat(values[id]), powers[i])
|
||||
}
|
||||
|
||||
return currents[0], currents[1], currents[2], err
|
||||
}
|
||||
|
||||
var _ api.MeterVoltage = (*SMA)(nil)
|
||||
|
||||
// Voltages implements the api.MeterVoltage interface
|
||||
func (sm *SMA) Voltages() (float64, float64, float64, error) {
|
||||
values, err := sm.device.Values()
|
||||
|
||||
var voltages [3]float64
|
||||
for i, id := range []sunny.ValueID{sunny.VoltageL1, sunny.VoltageL2, sunny.VoltageL3} {
|
||||
voltages[i] = sma.AsFloat(values[id])
|
||||
}
|
||||
|
||||
return voltages[0], voltages[1], voltages[2], err
|
||||
}
|
||||
|
||||
var _ api.MeterPower = (*SMA)(nil)
|
||||
|
||||
// Powers implements the api.MeterPower interface
|
||||
func (sm *SMA) Powers() (float64, float64, float64, error) {
|
||||
values, err := sm.device.Values()
|
||||
|
||||
var powers [3]float64
|
||||
for i, id := range []sunny.ValueID{sunny.ActivePowerPlusL1, sunny.ActivePowerPlusL2, sunny.ActivePowerPlusL3} {
|
||||
powers[i] = sma.AsFloat(values[id])
|
||||
}
|
||||
for i, id := range []sunny.ValueID{sunny.ActivePowerMinusL1, sunny.ActivePowerMinusL2, sunny.ActivePowerMinusL3} {
|
||||
powers[i] -= sma.AsFloat(values[id])
|
||||
}
|
||||
|
||||
return powers[0], powers[1], powers[2], err
|
||||
}
|
||||
|
||||
// soc implements the api.Battery interface
|
||||
func (sm *SMA) soc() (float64, error) {
|
||||
values, err := sm.device.Values()
|
||||
|
|
|
|||
|
|
@ -13,14 +13,19 @@ params:
|
|||
choice: ["rs485"]
|
||||
render: |
|
||||
type: modbus
|
||||
{{- include "modbus" . }}
|
||||
model: sdm
|
||||
{{- if eq .usage "charge" }}
|
||||
energy: Sum # only required for charge meter usage
|
||||
{{- end }}
|
||||
{{- if or (eq .usage "charge") (eq .usage "grid") }}
|
||||
power: Power
|
||||
energy: Sum
|
||||
currents:
|
||||
- CurrentL1
|
||||
- CurrentL2
|
||||
- CurrentL3
|
||||
{{- end }}
|
||||
{{- include "modbus" . }}
|
||||
voltages:
|
||||
- VoltageL1
|
||||
- VoltageL2
|
||||
- VoltageL3
|
||||
powers:
|
||||
- PowerL1
|
||||
- PowerL2
|
||||
- PowerL3
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ render: |
|
|||
id: 200
|
||||
model: sunspec
|
||||
power: Power
|
||||
energy: Export
|
||||
currents:
|
||||
energy: Import
|
||||
currents: # currents are signed already
|
||||
- CurrentL1
|
||||
- CurrentL2
|
||||
- CurrentL3
|
||||
|
|
|
|||
|
|
@ -10,14 +10,19 @@ params:
|
|||
choice: ["rs485", "tcpip"]
|
||||
render: |
|
||||
type: modbus
|
||||
model: janitza
|
||||
{{- include "modbus" . }}
|
||||
{{- if eq .usage "charge" }}
|
||||
energy: Import # only required for charge meter usage
|
||||
{{- end }}
|
||||
{{- if or (eq .usage "charge") (eq .usage "grid") }}
|
||||
model: janitza
|
||||
power: Power
|
||||
energy: Import
|
||||
currents:
|
||||
- CurrentL1
|
||||
- CurrentL2
|
||||
- CurrentL3
|
||||
{{- end }}
|
||||
voltages:
|
||||
- VoltageL1
|
||||
- VoltageL2
|
||||
- VoltageL3
|
||||
powers:
|
||||
- PowerL1
|
||||
- PowerL2
|
||||
- PowerL3
|
||||
|
|
|
|||
|
|
@ -16,6 +16,14 @@ render: |
|
|||
power: Power
|
||||
energy: Import
|
||||
currents:
|
||||
- CurrentL1
|
||||
- CurrentL2
|
||||
- CurrentL3
|
||||
- CurrentL1
|
||||
- CurrentL2
|
||||
- CurrentL3
|
||||
voltages:
|
||||
- VoltageL1
|
||||
- VoltageL2
|
||||
- VoltageL3
|
||||
powers:
|
||||
- PowerL1
|
||||
- PowerL2
|
||||
- PowerL3
|
||||
|
|
|
|||
|
|
@ -13,14 +13,11 @@ render: |
|
|||
source: http
|
||||
uri: http://{{ .host }}/status
|
||||
jq: .emeters | map(.power) | add
|
||||
{{- if or (eq .usage "charge") (eq .usage "grid") }}
|
||||
energy:
|
||||
source: http
|
||||
uri: http://{{ .host }}/status
|
||||
jq: .emeters | map(.total) | add
|
||||
scale: 0.001
|
||||
{{ end -}}
|
||||
{{if ne .usage "pv" -}}
|
||||
currents:
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/0
|
||||
|
|
@ -31,4 +28,23 @@ render: |
|
|||
- source: http
|
||||
uri: http://{{ .host }}/emeter/2
|
||||
jq: .current
|
||||
{{ end -}}
|
||||
voltages:
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/0
|
||||
jq: .voltage
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/1
|
||||
jq: .voltage
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/2
|
||||
jq: .voltage
|
||||
powers:
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/0
|
||||
jq: .power
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/1
|
||||
jq: .power
|
||||
- source: http
|
||||
uri: http://{{ .host }}/emeter/2
|
||||
jq: .power
|
||||
|
|
|
|||
|
|
@ -27,17 +27,35 @@ render: |
|
|||
{{- if eq .integer "true" }}
|
||||
# sunspec model 203 (int+sf) meter
|
||||
power: 203:W
|
||||
energy: 203:TotWhImp
|
||||
currents:
|
||||
- 203:AphA
|
||||
- 203:AphB
|
||||
- 203:AphC
|
||||
voltages:
|
||||
- 203:PhVphA
|
||||
- 203:PhVphB
|
||||
- 203:PhVphC
|
||||
powers:
|
||||
- 203:WphA
|
||||
- 203:WphB
|
||||
- 203:WphC
|
||||
{{ else }}
|
||||
# sunspec model 213 (float) meter
|
||||
power: 213:W
|
||||
energy: 213:TotWhImp
|
||||
currents:
|
||||
- 213:AphA
|
||||
- 213:AphB
|
||||
- 213:AphC
|
||||
voltages:
|
||||
- 213:PhVphA
|
||||
- 213:PhVphB
|
||||
- 213:PhVphC
|
||||
powers:
|
||||
- 213:WphA
|
||||
- 213:WphB
|
||||
- 213:WphC
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq .usage "pv" }}
|
||||
|
|
|
|||
|
|
@ -27,17 +27,35 @@ render: |
|
|||
{{- if eq .integer "true" }}
|
||||
# sunspec model 203 (int+sf) meter
|
||||
power: 203:W
|
||||
energy: 203:TotWhImp
|
||||
currents:
|
||||
- 203:AphA
|
||||
- 203:AphB
|
||||
- 203:AphC
|
||||
voltages:
|
||||
- 203:PhVphA
|
||||
- 203:PhVphB
|
||||
- 203:PhVphC
|
||||
powers:
|
||||
- 203:WphA
|
||||
- 203:WphB
|
||||
- 203:WphC
|
||||
{{ else }}
|
||||
# sunspec model 213 (float) meter
|
||||
power: 213:W
|
||||
energy: 213:TotWhImp
|
||||
currents:
|
||||
- 213:AphA
|
||||
- 213:AphB
|
||||
- 213:AphC
|
||||
voltages:
|
||||
- 213:PhVphA
|
||||
- 213:PhVphB
|
||||
- 213:PhVphC
|
||||
powers:
|
||||
- 213:WphA
|
||||
- 213:WphB
|
||||
- 213:WphC
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
model: sunspec
|
||||
|
|
|
|||
9
util/metering.go
Normal file
9
util/metering.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package util
|
||||
|
||||
// SignFromPower is a helper function to create signed current from signed power bypassing already signed current
|
||||
func SignFromPower(current float64, power float64) float64 {
|
||||
if current > 0 && power < 0 {
|
||||
return -current
|
||||
}
|
||||
return current
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue