diff --git a/README.md b/README.md index 2de8b6bb4..f063da2ee 100644 --- a/README.md +++ b/README.md @@ -203,8 +203,8 @@ Meters provide data about power and energy consumption. Available meter implemen model: sdm uri: rs485.fritz.box:23 id: 2 - power: PowerL1 - energy: Export + power: Power # reading as understood by MBMD, leave empty for power default value + energy: Export # optional reading for total energy values, specify for charge meter ``` - `sma`: SMA Home Manager and SMA Energy Meter. Power reading is configured out of the box but can be customizied if necessary. To obtain energy readings define the desired Obis code (Import Energy: "1:1.8.0", Export Energy: "1:2.8.0"): @@ -214,7 +214,7 @@ Meters provide data about power and energy consumption. Available meter implemen type: sdm uri: 192.168.1.4 power: # leave empty for mixed import/export energy - energy: # leave empty to disable or chose obis 1:1.8.0/1:2.8.0 + energy: # leave empty to disable or choose obis 1:1.8.0/1:2.8.0 ``` - `default`: default meter implementation where meter readings- `power` and `energy` are configured using [plugin](#plugins) diff --git a/meter/modbus.go b/meter/modbus.go index 9b5c014b2..18cccc5d3 100644 --- a/meter/modbus.go +++ b/meter/modbus.go @@ -81,24 +81,24 @@ func NewModbusFromConfig(log *util.Logger, other map[string]interface{}) api.Met } } - // energy reading - if cc.Energy == "" { - cc.Energy = "Sum" - } - - energyM, err := meters.MeasurementString(cc.Energy) - if err != nil { - log.FATAL.Fatalf("invalid measurement for energy: %s", cc.Energy) - } - - // for RS485 check if producer supports the measurement - m.opEnergy = rs485.Operation{IEC61850: energyM} - if dev, ok := device.(*rs485.RS485); ok { - m.opEnergy = modbus.RS485FindDeviceOp(dev, energyM) - - if m.opEnergy.IEC61850 == 0 { - log.FATAL.Fatalf("unsupported measurement for energy: %s", cc.Energy) + // decorate energy reading + if cc.Energy != "" { + energyM, err := meters.MeasurementString(cc.Energy) + if err != nil { + log.FATAL.Fatalf("invalid measurement for energy: %s", cc.Energy) } + + // for RS485 check if producer supports the measurement + m.opEnergy = rs485.Operation{IEC61850: energyM} + if dev, ok := device.(*rs485.RS485); ok { + m.opEnergy = modbus.RS485FindDeviceOp(dev, energyM) + + if m.opEnergy.IEC61850 == 0 { + log.FATAL.Fatalf("unsupported measurement for energy: %s", cc.Energy) + } + } + + return &ModbusEnergy{m} } return m @@ -131,7 +131,12 @@ func (m *Modbus) CurrentPower() (float64, error) { return m.floatGetter(m.opPower) } +// ModbusEnergy decorates Modbus with api.MeterEnergy interface +type ModbusEnergy struct { + *Modbus +} + // TotalEnergy implements the Meter.TotalEnergy interface -func (m *Modbus) TotalEnergy() (float64, error) { +func (m *ModbusEnergy) TotalEnergy() (float64, error) { return m.floatGetter(m.opEnergy) } diff --git a/provider/modbus.go b/provider/modbus.go index 122f640ec..47cefcf80 100644 --- a/provider/modbus.go +++ b/provider/modbus.go @@ -19,6 +19,7 @@ type Modbus struct { op rs485.Operation } +// ModbusSettings combine physical modbus configuration and MBMD model type ModbusSettings struct { Model string modbus.Connection `mapstructure:",squash"` @@ -49,7 +50,7 @@ func NewModbusFromConfig(log *util.Logger, typ string, other map[string]interfac conn.Slave(cc.ID) err = device.Initialize(conn.ModbusClient()) - // silence Kostal implementation errors + // silence KOSTAL implementation errors if _, partial := err.(meters.SunSpecPartiallyInitialized); partial { err = nil }