Enable modbus meter to read phase currents (#2072)
This commit is contained in:
parent
52852275ff
commit
0de4c93a3a
2 changed files with 102 additions and 7 deletions
|
|
@ -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.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.Battery,SoC,func() (float64, error)"
|
||||
|
||||
// NewModbusFromConfig creates api.Meter from config
|
||||
func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
||||
|
|
@ -34,6 +34,7 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
Model string
|
||||
modbus.Settings `mapstructure:",squash"`
|
||||
Power, Energy, SoC string
|
||||
Currents []string
|
||||
Timeout time.Duration
|
||||
}{
|
||||
Power: "Power",
|
||||
|
|
@ -107,6 +108,32 @@ 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
|
||||
|
||||
cc = modbus.ReadingName(cc)
|
||||
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 soc reading
|
||||
var soc func() (float64, error)
|
||||
if cc.SoC != "" {
|
||||
|
|
@ -118,7 +145,7 @@ func NewModbusFromConfig(other map[string]interface{}) (api.Meter, error) {
|
|||
soc = m.soc
|
||||
}
|
||||
|
||||
return decorateModbus(m, totalEnergy, soc), nil
|
||||
return decorateModbus(m, totalEnergy, currentsG, soc), 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), battery func() (float64, error)) api.Meter {
|
||||
func decorateModbus(base api.Meter, meterEnergy func() (float64, error), meterCurrent func() (float64, float64, float64, error), battery func() (float64, error)) api.Meter {
|
||||
switch {
|
||||
case battery == nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return base
|
||||
|
||||
case battery == nil && meterEnergy != nil:
|
||||
case battery == nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterEnergy
|
||||
|
|
@ -22,7 +22,33 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), battery
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterEnergy == nil:
|
||||
case battery == nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case battery == nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
Meter: base,
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent == nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -33,7 +59,7 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), battery
|
|||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterEnergy != nil:
|
||||
case battery != nil && meterCurrent == nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
|
|
@ -47,6 +73,40 @@ func decorateModbus(base api.Meter, meterEnergy func() (float64, error), battery
|
|||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy == nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && meterCurrent != nil && meterEnergy != nil:
|
||||
return &struct {
|
||||
api.Meter
|
||||
api.Battery
|
||||
api.MeterCurrent
|
||||
api.MeterEnergy
|
||||
}{
|
||||
Meter: base,
|
||||
Battery: &decorateModbusBatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
MeterCurrent: &decorateModbusMeterCurrentImpl{
|
||||
meterCurrent: meterCurrent,
|
||||
},
|
||||
MeterEnergy: &decorateModbusMeterEnergyImpl{
|
||||
meterEnergy: meterEnergy,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -60,6 +120,14 @@ func (impl *decorateModbusBatteryImpl) SoC() (float64, error) {
|
|||
return impl.battery()
|
||||
}
|
||||
|
||||
type decorateModbusMeterCurrentImpl struct {
|
||||
meterCurrent func() (float64, float64, float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateModbusMeterCurrentImpl) Currents() (float64, float64, float64, error) {
|
||||
return impl.meterCurrent()
|
||||
}
|
||||
|
||||
type decorateModbusMeterEnergyImpl struct {
|
||||
meterEnergy func() (float64, error)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue