Storing energy data

Well, yes kind of.

If i attach my mqtt node to your function node, its having a strange behaivor:

Its reporting numbers like: "8000210270260101", then "80002102702601010" then "8000210270260101026" and so on. Every 30 seconds.

But every 30 seconds there are numbers like "101", then "127" then "154" and so on.

Thats the increasing energyconsumption in "Wattseconds"

Do you mean the big numbers are on the output and the small ones are on the input? If so then you have started with a large number in the total in the global context (which is persistent remember, so will have whatever it had following earlier experiments).
You can clear them from the context tab I think, or here is a little flow you can use.

[{"id":"975f0758.d6e53","type":"function","z":"514a90a5.c7bae8","name":"Clear history","func":"// Clears the energy context variables\nglobal.set(\"previousShellyValue\", 0, \"storeInFile\")\nglobal.set(\"runningTotalEnergy\",0, \"storeInFile\")\n","outputs":1,"noerr":0,"x":384,"y":1276,"wires":[[]]},{"id":"116da10.2a8eedf","type":"inject","z":"514a90a5.c7bae8","name":"Clear","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":193,"y":1276,"wires":[["975f0758.d6e53"]]}]

Its looking like its adding the reportet energy to the total energy at the end of the existing number.

Yes. Small is input whats reportet over mqtt. and bis is the one i get out of your function

Ok i tested it out.

I cleared the context variable. Then i startet.. i took it up tp round about 790. When i powerd off and on my device, and it startet to report from zero again, the total looked like this: After the first 0 came -> 7900 then again a 0 came -> 79000 -> then a 23 came -> 7900023 -> and so on. do you understand?

Edit:

Ok the problem was:

The MQTT Node is giving out strings.

I replaced msg.payload to a local variable called "payload" and did a parseInt() at begin, and before returning it, i did .toString(). Now its working perfect!

1 Like

Thank you very much for all the reports and much help! I would never get this by myself.

I have learned alot about the context programming now with this!

Best not to convert it to a string on output. Keep it as a number. The MQTT Out node will convert it if necessary.
If you are after converting the input to a number with parseInt you should check that the result is a number. If something weird comes through mqtt then you don't want it messing up your total. So maybe something like

// Given current total energy from Shelly in msg.payload as a string
payload = parseInt(msg.payload)
// check that it has converted ok (so it is not not-a-number)
if (!isNaN(payload)) {
    let runningTotalEnergy = global.get("runningTotalEnergy", "storeInFile") || 0
    let previousShellyValue = global.get("previousShellyValue", "storeInFile") || 0
    // test whether the Shelly has reset since last input
    if (payload < previousShellyValue) {
        // yes it has, just add new value to the total
        runningTotalEnergy += payload
    } else {
        // no so add the difference between this and last to the running total
        runningTotalEnergy += payload - previousShellyValue
    }
    global.set("previousShellyValue", payload, "storeInFile")
    global.set("runningTotalEnergy",runningTotalEnergy, "storeInFile")
    msg.payload = runningTotalEnergy
} else {
    // an illegal string passed in so ignore it, don't pass on anything
    msg = null
}
return msg;
1 Like

Thanks. But i cant give it out with an Debugnode or on a Text Output at Dashboard as a number

Both the debug node and the dashboard text out node work perfectly when passed numbers.

but why i always get the error "xx tried to send a number" etc?

What is the exact error and where are you seeing it?
Screenshot if necessary to explain.

Ok i have no clue why its working now... Better forget about it. I tried to get this error back by removing "parseInt" and ".toString" but it still worked.

You need the parseInt at the start, just not the to string at the end.

To set the running energy total to zero, for example at midnight each day.
Simply set the context value 'runningTotalEnergy' back to zero using a inject node set to midnight.

// Sets the running total to zero
global.set("runningTotalEnergy",0, "storeInFile")
1 Like