I have incoming data (e.g. power from a washing machine) at a certain rate (e.g. 1/ 30 sec). I store it in a database (influx).
Sometimes the values do not change over some time, then successive data is all constant.
I use a rbe-node to avoid writing redundant data into the DB. So far, so good.
However, when visualising the data from the DB, I run into a problem: There may be no recent data in the DB when it has not changed recently. But of course, there was data.
Therefore I want to
store each single data item when it differs from the previous one
store data at a certain rate when all the data are constant
Off course, I do not want to have a single data item twice in the DB.
I could not figure out how to achieve this with "standard" nodes, rbe and throttle the obvious suspects. A quick search in the unfathomable universe of contributed nodes did not yield anything usable for my use case.
Of course, I could achieve what I want it with my own function node, but I think I have to learn more about the built-in nodes and their possibilities.
Any help appreciated, Uwe
Happy New Year 2021. Only one person can sit in front of a keyboard ... stay there!
Just figured out that I can reset the rbe at the desired frequency ... I think that will do the trick.
Always nice to find out how thoughtfully designed these little things are!
Uwe
There is a slight imperfection in that technique, that occasionally it will inject extra unnecessary values. Suppose the RBE passes on a changed value and then just after that the inject resets the RBE then it will unnecessarily pass on the next one too. I opted for a function node for this. This also allows a change threshold to be specified, but setting that to 0 will disable it.
// limits the message rate to one every resendInterval, except if value has changed by more than threshold
const resendInterval = 15000 // max interval between outputs, msec
const threshold = 10 // send if change is more that this value
const previous = context.get("previous") || {timestamp: 0, value: -9999}
const now = new Date().getTime()
if ( Math.abs(msg.payload - previous.value) < threshold && (now - previous.timestamp) < resendInterval )
{
// same value as last one (within deadband) and too soon to send again, so send nothing
msg = null
} else {
previous.timestamp = now
previous.value = msg.payload
context.set("previous", previous)
}
return msg;
personally I would use an RBE node followed by a trigger node set to resend last message every x seconds - that sends any new message right away then repeats at the given rate.
Resending the previous message has the disadvantage that if there is a problem fetching the data then it continues to send the previous data as if all was well. This may or may not be an issue in any particular situation. It can be coped with by detecting the failure and resetting the trigger, but that adds some additional complexity.