Understanding Shelly aenergy vs apower for daily power consumption?

Hey people!

I've read the docu and also made some calculations, but nevertheless I come to no right solution.

The Tasmota sends my out of the box a "kWh" which was exactly what I needed. I made query in influxdb and got my daily power consumption.

Example: If I save every 10 seconds the aenergy value, I can i roughly calculate the average for one hour. The Watt-hours / 1000 and I should have the kWh - right?

Thanks for you thoughts

Can you show what a sequence of a few of the messages from the device look like please.

These are the out of th ebox "apower" values from Shelly!

2022-12-17 08:16:26
122
2022-12-17 08:16:46
140
2022-12-17 08:17:06
128
2022-12-17 08:17:26
129
2022-12-17 08:17:46
138
2022-12-17 08:18:06
125
2022-12-17 08:18:26
121
2022-12-17 08:18:46
156
2022-12-17 08:19:06
136
2022-12-17 08:19:26
119
2022-12-17 08:19:46
127
2022-12-17 08:20:06
120
2022-12-17 08:20:26
157
2022-12-17 08:20:46
128
2022-12-17 08:21:06
129

Can you point me to the docs where is says what apower is supposed to represent?

1 Like

Hey

It`s GEN2 Device (1PM) and under status you can find all the values what I get from the shelly

  • apower: Last measured instantaneous active power (in Watts) delivered to the attached load (shown if applicable)

  • aenergy is not really what I want because its a cummulative sum since the device started

thanks and greetings

If it's energy that you are wishing to record, you need to use a aenergy, and not epower.
Even though the Shelly counts energy since the device was started, you can still use that data in node-RED, by for example comparing the current reading with the previous reading.
Also you can detect when the device has been restarted, because the current reading will be less than the previous.
It is possible to use the apower reading, but aenergy IMO would be the way to go.
But if you really want to use apower, take a look at node-red-contrib-watt2kwh although it won't be as accurate as using aenergy.

2 Likes

I prefer to use the energy instantaneous power figure (watts) as anything you want can be calculated from that, usually via influxdb queries. If you use the accumulated energy then you have to allow for it being reset, which may not be simple.

Yes. However, you can use the query
SELECT cumulative_sum("power")/3600000 FROM ...
to give you the total usage over a period. I think the divisor is correct, see whether it gives sensible values.

If you want to show the accumulated usage in a grafana chart, to show it for a day, or a month or whatever then use
SELECT cumulative_sum(integral("power"))/3600000 FROM "wherever" WHERE $timeFilter GROUP BY time($__interval) fill(null)
Which calculates the usage under each pixel (that's the integral(power) bit) then accumulates it across the chart.

2 Likes

Should that be 'power'?

If so, the problem is that the power data produced by the Shelly is an instantaneous snapshot made at that moment. If it updates, say every 10 seconds, what power is being used in the remaining 9.999999 seconds, it could vary enormously and therefore not present a true and accurate representation.

Shelly quote:

Last measured instantaneous active power (in Watts) delivered to the attached load (shown if applicable)

2 Likes

Yes, thanks. Corrected.

1 Like

True, though I would expect it to average out. The Shelley will be averaging over some period itself, it would be interesting to know what that is. I don't use that device I monitor it myself using a current transformer and measure it every three seconds. My totals agree with the meter totals extremely well.

1 Like

It is impossible to measure that, it has to be averaged over at least one complete mains cycle. In practice it is probably measured over a significant period. Possibly several seconds. It would be interesting to monitor the figure from the shelley at the maximum rate that it will run at and then switch on a simple resistive load and see what it shows.

1 Like

I don't think Shelly would stress 'instantaneous' if it was an averaged value.
Have you read somewhere that it is an averaged value?

That of course would report accurate, but in real life we rarely get constant resistive loads, we have different devices being constantly switched on and off, such as ovens, heaters, hobs etc, plus devices that pulse power - induction hobs, microwaves, etc.

1 Like

It is not mathematically possible to measure it instantaneously, it has to be measured over at least one mains cycle. In practice, in order to get an accurate figure, it will be calculated over a period.

I was meaning in order to see how quickly the Shelley responds.

1 Like

Let's agree to disagree about that😉
I'm going to leave this here.

1 Like

I agree that storing the accumulated total would make the queries on the database simpler. But how to you cope with it resetting to zero occasionally?

1 Like

Isn't that just some extra math to account for the value suddenly going less-than the previous value? Of course, you would probably have to make an assumption about when the reset happened but assuming that your reporting period is no more than about a minute, unless you are REALLY stressing about every erg of energy used, would it really matter?

2 Likes

Do you mean on the way into the influx database? I can't see how to do it in a query. Doing it after the query would mean fetching all the intermediate values in order to step through and find where it reset, which would be painful if wanting to know the usage over a year for example.

1 Like

Yes, on input. Easier to do it in node-red anyway.

Maybe someone would like to do a comparison of the two methods? Ultimately, for me, it isn't really about trying to be massively accurate but rather simply getting a feel for the worst-case cost.

I need to get my Shelly 1PM fired back up clearly. Though to be honest, I've never bothered to do recordings of individual device power consumption since all I need to know is roughly how much power it is using so I know whether it is worth using and how long for. I don't need a DB for that.

1 Like

Calculate it before writing to the database.
Save the reading to context, then when another reading arrives compare it with the previous reading to determine how much energy has been used between those times, and write that to the database, and then save the current reading to context, etc, etc.
You can determine and deal with the device being reset because the current data would be less than the previous.

To then read it in influx, just sum the values over whatever time period that you wish.

Something like this would do, but I'm sure @Colin could improve this further;

let lastReading = context.get('energy') || 0
let currentReading = msg.payload
let energy
if (currentReading < lastReading) {
energy = currentReading
} else {
energy = currentReading - lastReading
}
context.set ('energy', currentReading)
msg.payload = energy
return msg
[{"id":"5525c984cfe71ca1","type":"inject","z":"8ec88bd9c36c3f6b","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"50","payloadType":"num","x":195,"y":1035,"wires":[["17c5b3c05d36205b"]]},{"id":"17c5b3c05d36205b","type":"function","z":"8ec88bd9c36c3f6b","name":"Energy calcs","func":"const lastReading = context.get('energy') || 0\nconst currentReading = msg.payload\nlet energy\nif (currentReading < lastReading) {\n    energy = currentReading\n} else {\n    energy = currentReading - lastReading\n}\ncontext.set ('energy', currentReading)\nmsg.payload = energy\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":375,"y":1035,"wires":[["7b5f5791bb689fba"]]},{"id":"7b5f5791bb689fba","type":"debug","z":"8ec88bd9c36c3f6b","name":"Energy","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":555,"y":1035,"wires":[]},{"id":"a9a85d45b0853b19","type":"inject","z":"8ec88bd9c36c3f6b","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"60","payloadType":"num","x":194.8958282470703,"y":1076.3333740234375,"wires":[["17c5b3c05d36205b"]]},{"id":"5452cde97709f5cd","type":"inject","z":"8ec88bd9c36c3f6b","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"100","payloadType":"num","x":196.8958282470703,"y":1120.3333740234375,"wires":[["17c5b3c05d36205b"]]}]
1 Like

I had misunderstood what you intended. I thought you wanted to store the accumulated energy in the database, but you actually mean to store the difference in usage since the last reading. Yes, that would work, and indeed has some advantages. I might be persuaded that that is better.

I don't think that code is sufficient though. Suppose that the context value was lost. It would be tricky recovering. I think it would be safer to store the accumulated reading from the device in the db too. Then on node-red startup fetch the latest value from the db to prime the context variable.

Finally on the instantaneous measurement issue. The power factor is needed in order to know the power, and it takes a full cycle to determine that. Then the RMS voltage and current are needed too, which again needs a full cycle.

1 Like