Write specific value at a certain time (max of day at 23:58)

I am new to NR. I come from time based scripting and this event based stuff gives me headache.
What I read from tutorials is always use flows (instead of function-node).

what it should do:
find the max of day of a power meter (shelly3EM 3xmqtt)
I realized this with a join_to_arry[0-2] and sum it function-node updating if bigger than context

I found a changenode JSONata variant for the sum
$sum(payload)/1000 (in KILO watt)
but I see no point of advantage
neither the change-node nor the function-node is making it abvios from the outside unless I rename the time

in Simulink I would use a max-block
but I new find any node with two input-points

What is best practice in node-red if I should use no function block? (and refuse to use coding in core-nodes)
(I could live with this right now but I have more questions to come up)

There is no reason to avoid the function node. Sometimes it my even be the "right" way. It is recommended to use the regular core & contrib nodes where you can (as opposed to writing complete applications in a function node) so that you get the "visual flow" at a glance.

For example...

I think the below flow (a mix of functions and regular nodes) is a very reasonable solution to my current task...

However I could easily have written it like this...

But I might as well be writing a node.js application in this :point_up_2: case. I also lose the ability to add debug nodes in various locations to understand what is happening.

need to lean to paste code first ...

cannot even quote

what I finally want is to write the 'max_of_the_day' to a database at 23:58 o'clock.
ever time base example triggers a debug
so I can write 23:59 to a debug
I could write a fixed string with a triggered change node to a debug (or database)

but what I want is search_for_max_value (must run continously) and
must run once a day

joining all the information (time and 3 powers) and spliting them inside a function block again and sending two message out of the function block seems weired

Why don't you just write them all to the db and use the db to give you the max when you need it?

What db are you using?

You could do this in a timed manner, but I had a similar type of need, and just do it in a function node using a database (MYSQL) query

msg.topic = "insert into PowerPlugs (`Date`, `PlugId`, `kWh Today`) values ('" + msg.payload["Time"].substring(0,10) +"', '"+ msg.plug +"', " + msg.payload["ENERGY"]["Today"] + ") ON DUPLICATE KEY UPDATE `kWh Today` = GREATEST(`kWh Today`, " + msg.payload["ENERGY"]["Today"] + ");      ";

The database table has 3 fields, Date, PlugId and kWh Today in my case, and the primary key for the table is Date and PlugId. So if a particular plug has a value recorded in the database for a given date, then the stored value will be the biggest between the currently saved value, and the new one.


Here is a no-code approach: an inject node to trigger a flow at 23:58 and a flow variable to retain the maximum value seen that day. For simplicity I have assumed the database automatically adds the timestamp to new records.

[{"id":"edbf92277c2a065b","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"6d2270bd9198cbcb","type":"group","z":"edbf92277c2a065b","name":"Insert into db (MySQL example)","style":{"stroke":"#0070c0","fill":"#bfdbef","fill-opacity":"0.52","label":true},"nodes":["56e196f68da11b69","f71943cb189f095f","7629c42c586946f3"],"x":14,"y":279,"w":672,"h":82},{"id":"25923af295679204","type":"group","z":"edbf92277c2a065b","name":"As readings arrive maintain largest as flow.maxreading","style":{"stroke":"#0070c0","fill":"#bfdbef","fill-opacity":"0.45","label":true},"nodes":["95db38b08620ab31","d13a9934bb100b40","5329268a7b012215","0b6dda8705195704","9c129465334fb50f","af232ceb1dbb0cdd","46ffef4c607e9ec1","d37bde21db120bd4","1958b0d9b0be4ba0"],"x":14,"y":19,"w":972,"h":242},{"id":"56e196f68da11b69","type":"inject","z":"edbf92277c2a065b","g":"6d2270bd9198cbcb","name":"At 23:58","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"58 23 * * *","once":false,"onceDelay":0.1,"topic":"msg.topic = \"INSERT INTO test (maxreading) VALUES(?)\";","payload":"maxreading","payloadType":"flow","x":120,"y":320,"wires":[["f71943cb189f095f"]]},{"id":"f71943cb189f095f","type":"mysql","z":"edbf92277c2a065b","g":"6d2270bd9198cbcb","mydb":"2381cb15.b563bc","name":"MySQL db","x":290,"y":320,"wires":[["7629c42c586946f3"]]},{"id":"95db38b08620ab31","type":"switch","z":"edbf92277c2a065b","g":"25923af295679204","name":"Is flow.maxreading null?","property":"maxreading","propertyType":"flow","rules":[{"t":"null"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":330,"y":120,"wires":[["46ffef4c607e9ec1"],["d37bde21db120bd4"]]},{"id":"7629c42c586946f3","type":"change","z":"edbf92277c2a065b","g":"6d2270bd9198cbcb","name":"","rules":[{"t":"delete","p":"maxreading","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":320,"wires":[[]]},{"id":"d13a9934bb100b40","type":"inject","z":"edbf92277c2a065b","g":"25923af295679204","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":110,"y":60,"wires":[["95db38b08620ab31"]]},{"id":"5329268a7b012215","type":"inject","z":"edbf92277c2a065b","g":"25923af295679204","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"17","payloadType":"num","x":110,"y":100,"wires":[["95db38b08620ab31"]]},{"id":"0b6dda8705195704","type":"inject","z":"edbf92277c2a065b","g":"25923af295679204","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24","payloadType":"num","x":110,"y":140,"wires":[["95db38b08620ab31"]]},{"id":"9c129465334fb50f","type":"inject","z":"edbf92277c2a065b","g":"25923af295679204","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"22","payloadType":"num","x":110,"y":180,"wires":[["95db38b08620ab31"]]},{"id":"af232ceb1dbb0cdd","type":"link in","z":"edbf92277c2a065b","g":"25923af295679204","name":"New Readings Arrive Here","links":[],"x":150,"y":220,"wires":[["95db38b08620ab31"]],"l":true},{"id":"46ffef4c607e9ec1","type":"change","z":"edbf92277c2a065b","g":"25923af295679204","name":"","rules":[{"t":"set","p":"maxreading","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":100,"wires":[[]]},{"id":"d37bde21db120bd4","type":"switch","z":"edbf92277c2a065b","g":"25923af295679204","name":"msg.payload > flow.maxreading?","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"maxreading","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":600,"y":160,"wires":[["46ffef4c607e9ec1"]]},{"id":"1958b0d9b0be4ba0","type":"comment","z":"edbf92277c2a065b","g":"25923af295679204","name":"Must allow for if flow.maxreading is not set","info":"","x":380,"y":80,"wires":[]},{"id":"2381cb15.b563bc","type":"MySQLdatabase","name":"","host":"","port":"3306","db":"espresso","tz":"","charset":"UTF8"}]

I agree with @Colin though, if you store all the data you are ready when the client (you?) demands the daily average, the number of instances in the day above average, the maximum noted during daylight hours, ...

I don't agree to store everything
it's influxDB
and even if storge space is endless N-R does not seem to be optimal for calculations

Doing it the database way is taking advantage of "flow"-wide varables. This also breaks the visible flow.

Then I would rather stick with a functional-node with a continous output for further flowing and one output triggered at the disired time.

My question is not so much about the issue '23:58' itself but all kinds of combination of timed and conditional issues.
Like count the time that the power was above 1000 W.

I still lack understanding and I have to overcome my simulink thinking.

The point is to not do the calculations in node-red. Influx will easily tell you the max for the day, or the accumulated total for the day, or last month or whatever.

The database can be configured to run a Continuous Query each night to calculate the total and store it in another Measurement. If you really have no further use for the rest of the data then the real time Measurement can be configured with a two day Retention Period so only the last two days are kept. The amount of storage space that would take is trivial.

If you are already using Influxdb then this is definitely the right way to do it. It is the right tool for the job.

1 Like

Thanks for the inspirations.
I combined the suggestion to take a value from the 3rd dimension (using 'flow.xx') and querying from influx. So I am usung influx as the 3rd dimension.
running on a pi2_1gb the querys should not be too complex so I still use the function node.
query (energymeter at start of day) and (energymeter at end of day) and do the
(energy of the day calculation) in a node red function block works
query((energymeter at end of day)-(energymeter at start of day)) freezes the system for 40 minutes.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.