Can ConsumptionActivePower be negative?

I am a new user of OpenEMS. Thanks for building such a great piece of software, it works like a charm. Time from deployment to being useful was super-short (after I figured out how to build it). If have only a minor issue where I would like to get advise whether this is a misunderstanding or a bug.

My setup:

  • OpenEMS 2020.21, using only edge component, build into a Docker container
  • 1 Smartmeter: Discovergy Two Way Meter, connected through the Discovergy API
  • 1 Inverter: SMA Sunny Tripower with Home Manager, connected through Modbus TCP
  • All data is written into InfluxDB for analytics

My InfluxDB setup is the following: I use Telegraf with an Influx v1 Listener as a Relay. Telegraf forwards all data received into two InfluxDB 2.0 instances (one local, one on InfluxDB Cloud).

I use Grafana with Flux queries against the InfluxDB 2.0 instances to analyze and display data. I mainly use the ‘_sum/[Consumption|Production|Grid]Active[Power|Energy]’ fields right now. Which works nicely most of the time. But today I saw a graph plotting ‘_sum/ConsumptionActicePower’ that went negative. My understanding is that our total consumption could not be negative. We are typically drawing a baseline of at least 300 Watts. Is my understanding of this metric wrong or is this a bug?

Thanks a lot for the great feedback!

Of course you are right, that Consumption power should in theory never be negative. But as Consumption is usually not measured directly, it has to be derived from actually measured values - typically those are Grid (buy+sell), Production and Storage (charge+discharge).

In the source code “_sum/ConsumptionActivePower” is calculated as:

this._setConsumptionActivePower(TypeUtils.sum(//
    essActivePowerSum, gridActivePowerSum, productionAcActivePowerSum));

(https://github.com/OpenEMS/openems/blob/develop/io.openems.edge.core/src/io/openems/edge/core/sum/SumImpl.java#L333-L334)

From your screenshot you have at that point in time

  • GridActivePower = -3291 W (negative, so it’s sell-to-grid)
  • ProductionActivePower = 1762 W
  • EssActivePower = 0 W (no storage)

According to the data you are feeding more power to the grid than you produce. As a result the Consumption is calculated as a negative value.

How can negative Consumption happen?

  1. Unmeasured Producer: there is an additional generating unit in the system that is not measured, like a second PV installation
  2. Timing: the data is not measured at exactly the same time. If e.g. the Discovergy meter is providing data slower than the local SMA inverter. There are internal measures that invalidate old data.
  3. Measurement inaccuracy

Regards,
Stefan

Thanks, Stefan. Very helpful. The Discovery Meters provide an updated reading about every 45-50 seconds on average, but it unfortunately spikes to some minutes (or longer) occassionally. I revied the time elapsed between meter readings for yesterday and saw some of those spikes:


The spikes in the morning were in coincidence with the negative Consumption, so I believe this the root cause of the problem. I rebooted my Internet router which caused this issue in this case (the meter is local, but the used Discovergy API is on the Internet).

Luckily, I use the SMA Inverter with the SMA Home Manager connected to it. The Home Manager sits in my distribution box behind the meter and measures all the energy going through it and sends it to the Inverter. This way the inverter can calculate all relevant parameters like Production, Consumption, Buy/Sell from/to Grid on its own. These measurements are provided locally through Modbus TCP and are updated frequently without being depedent on an internet connection.

The better way than to compute the consumption in my case would be to use the consumption reading from the Inverter. Unfortunately the pvInverter0/ActiveConsumptionEnergy reading is always 0. I will investigate further on the weekend and get back with results.

I dived into the raw data of my Inverter and looked at the points in time when _sum/ConsumptionActivePower went negative

My readings is:
TotW = Power generated
TotWOut = Power fed into the Grid
TotWIn = Power drawn from the Grid

The the consumption would be: TotW - TotWOut + TotWIn (between 300 to 500W in this example)

TotWOut and TotWIn are provided by the Home Manager. The data is always ‘in sync’ with the other readings from the Inverter and has a very good time resolution and accuracy. So it would be better to use this data from Inverter than the potentially delayed or non available data from the Discovergy Meter.

The metrics are exposed though Modbus.
Is there a way that OpenEMS can use this data to calculate ConsumptionActivePower, SellToGrid, BuyFromGrid etc. without any dependence on a separated meter reading?

In this case the Home Manager is the best meter I can could imagine and really would like to leverage it. As the data is available through the Modbus interface of the inverter, my naive imagination is that it should be quite simple :wink:

Unfortunately the current version of Discovergy meters only has a cloud API. I am very surprised, that it is that slow sometimes. I use the API personally and made good experiences till now. From what I know an upcoming version of the Discovergy meters will also have a local API. I am pinging @zoernert - Thorsten, do you have any updated information on that?

The pvInverter0/ActiveConsumptionEnergy will always be zero for a PV-Inverter. This comes from the fact, that PV-Inverter is inheriting a SymmetricMeter; so ActiveConsumptionEnergy would be the energy that is consumed by a PV-Inverter.

What we need instead is a Meter component in your system that replaces the current Discovergy meter with the SMA grid meter. I do not have experience with SMA Sunny Home Manager, but usually SMA is quite good in implementing standard SunSpec protocols. If you are lucky, the SolarEdge Grid-Meter might work out of the box, as it is also using SunSpec.

If not, maybe you can provide some documentation on the Home Manager Modbus specification?

The Discovergy Smart Meter Gateway is coupled to the actual meter through Wireless M-Bus. This communication can’t provide more frequent updates - I have asked this question already to Discovergy’s support team. In general, I’m quite happy with the functionality of the meter and the API, only the update frequency causes sometimes weird effects on Dashboards/Charts.

I have been succesful in reading the values of the fields ‘TotWIn’ and ‘TotWOut’ (the bidirectional meter in the Home Manager) from the Modbus interface using OpenHAB with the Modbus Binding. I gathered the required information from the Modbus documentation available on SMA’s website. Here is part for the Home Manager meter (in German):

If somebody could build a meter for the ‘SMA Sunny Home Manager 2.0’ from this information, I would be more than happy to test it.

[Edit: Of cource, I tested the SolarEdge meter and got the error message: “[modbus0] FC3ReadHoldingRegisters [meter1;unitid=1;ref=40000/0x9c40;length=2] execution failed: Transaction failed: Illegal Data Address: Illegal Data Address”]

Ok, it was worth a try. But the error message already shows, that the ‘SMA Sunny Home Manager 2.0’ does not seem to support a SunSpec protocol. The SunSpec protocol has a “Marker” at register 40000 - which does not seem to be supported as it is throwing an Illegal Data Address error.

Implementing a Meter via Modbus in OpenEMS is very easy. In fact it is even completely documented in the “Implementing a device” guide:

To be a proper meter, there are some more Channels required than ActivePower only - see Javadoc: https://openems.github.io/openems.io/javadoc/io/openems/edge/meter/api/SymmetricMeter.ChannelId.html

Can you provide a link to the full modbus protocol? This would also be a nice very first development project in OpenEMS… :wink:

The Modbus List for SMA Tripower inververters built from 2018 onwards is here:
https://files.sma.de/downloads/MODBUS-HTML_STP8.0-10.0-3AV-40_GG10_V10.zip

There is an exhaustive list of Modbus documentation at (click on “Downloads”, “Hintergrundwissen”)

Okay, you got me - I will tackle this implementation myself. But the last check-in into a public repository has been 20 year ago when git was unknown and cvs ruled the world. I will try my very best not to make a fool of myself, but I may stell need some advice :wink:

The code skeleton bascially works. I’m reading from Modbus register 30865 with the following code

protected ModbusProtocol defineModbusProtocol() {
       return new ModbusProtocol(this, 
        new FC3ReadRegistersTask(30865, Priority.HIGH, 
		m(SymmetricMeter.ChannelId.ACTIVE_POWER, new SignedDoublewordElement(30865)))); 
}

The values always seems to be ‘-1’ while OpenHAB with Modbus binding is reading proper values from this adress. There seems to an error of some kind with the above code. The SMA value at this adress is power in Watts, represented as signed, 32 bit integer value, high endian.

Any ideas? Is there a open-source Modbus TCP test utility to debug this?

Strange, the code seems to be fine. But -1 must be the value, that is actually read from the register, otherwise it would be UNDEFINED/null.

  • Can you share your OpenHAB configuration for the Modbus binding?
  • Which modbus Unit-ID are you using?

If I understand correctly registers 30867 and 30865 will have to be mapped to positive and negative values of meter0/ActivePower. We’ll work on that once you are able to read proper values.

I can recommend QModMaster for testing:

Thanks again for supporting me in your free time. This is the OpenHAB Thing configuration:

The Modbus TCP bridge
UID: modbus:tcp:STP10
label: Modbus Bridge to STP10 inverter
thingTypeUID: modbus:tcp
configuration:

  • timeBetweenTransactionsMillis: 60
  • connectMaxTries: 1
  • reconnectAfterMillis: 0
  • port: 502
  • timeBetweenReconnectMillis: 0
  • host: inverter.gruning.eu
  • connectTimeoutMillis: 10000
  • id: 3
  • enableDiscovery: true

The so called 'Poller’
UID: modbus:poller:d7c74c32b0
label: Poll 30865/20
thingTypeUID: modbus:poller
configuration:

  • start: 30865
  • length: 20
  • refresh: 5000
  • maxTries: 3
  • cacheMillis: 50
  • type: holding
  • bridgeUID: modbus:tcp:STP10

The actual item for TotWIn
UID: modbus:data:189f6aac03
label: GridMs.TotWIn
thingTypeUID: modbus:data
configuration:

  • readValueType: uint32
  • readTransform: default
  • writeTransform: default
  • readStart: “30865”
  • updateUnchangedValuesEveryMillis: 1000
  • writeMultipleEvenWithSingleRegisterOrCoil: false
  • writeMaxTries: 3
  • bridgeUID: modbus:poller:d7c74c32b0

In both cases (OpenHAB and OpenEMS) the Modbus ID is 3.

I have enabled logging in the Modbus bridge for OpenEMS and this is what I get:
[modbus0] FC4ReadInputRegisters [3:0/0x0]: ffff ffff

According to the SMA Modbus docs this hex values represents ‘NaN’ (Not a Number) for U32:

This is really tough to debug without direct access to the device itself. If none of this works out, we should meet on a Teams-/Teamviewer-session.

The only difference I can find is, that you are using uint32 in OpenHAB wheras s32 should be correct according to the protocol. You could try an UnsignedDoublewordElement in OpenEMS.

Did you have success reading data using QModMaster?

You are right. It is difficult to find the root cause of the problem (OpenEMS reads nicely the values from the SunSpec registers of the inverter and seems to have problems reading other Modbus registers from the same Modbus TCP target).

I have tested QModMaster and it reads the values nicely
(registers 30865/30866, drawing 280W from the grid is accurate right now)
Unbenannt

Let me check if I can find the root cause myself first. Thanks for investing so much time to support me.

BTW. This is how I could map the available Modbus Metering Registers to the channels of a SymmetricMeter. Would you suggest to go down that route or would this be more clever to structure as an AsymmetricMeter?

By looking at the code in AbstractReadRask I see a problem:
This should be like FC4ReadInputRegisters [3:30865/0x7891]: value in hex
But it is zero. The right StartAdress seems to get lost, this is why the device returns 0xfffffff all the time.

The code for the Modbus protocol is:
return new ModbusProtocol(this,
new FC3ReadRegistersTask(30865, Priority.HIGH,
m(SymmetricMeter.ChannelId.ACTIVE_POWER, new SignedDoublewordElement(30865))
));

Could this be a bug somewhere in the code?

This is indeed very strange. Can you please share the complete file/bundle that you created, so that I can have a look and let it run against a Modbus simulator?

I pushed it ‘as-is’ to https://github.com/martingruening/openems
The code is in io.openems.edge.meter.sma.shm20

Edit: I don’t know what exactly happened. Today the code worked :slight_smile:

[modbus0 ] INFO [dbus.api.task.AbstractReadTask] [modbus0] FC3ReadHoldingRegisters [3:30865/0x7891]: 0000 0347
[re.Cycle] INFO [e.controller.debuglog.DebugLog] [ctrlDebugLog0] _sum[State:Ok Grid:839 W Consumption:839 W] meter0[L:839 W]

A manual ‘gradlew clean’ removed the problems which seem to be caused by a rookie software engineer in front of the keyboard :wink: Can you please advise on the topic ‘Symmetic vs. Asymmetric’ meter and how to convert Modbus registers available to channels using logic mentioned above?

I have solved my questions by looking at different meter implementations. The code is now complete. I will enter the first pull request of my life :slight_smile:

Thank you for this very high value contribution. The code is very clean. I just merged the pull-request:

I used today to check all the values put into Influx. It all looks good and consistent with one exception - this the graph for the last 12 hours for _sum/ConsumptionActiveEnergy

From my point of view It should be never decreasing, but it is.
Do I have a wrong understanding of this measurement?