How to get last message in sequence of unknown length (1-3 messages)

I have a situation where the join node does 90% of what I want, but doesn't do exactly what I want and am hoping someone has a good solution.
As I am showing hear I get Hue, Saturation and Level inputs via 3 separate MQTT topics. I want to send from the join a single message with the 3 readings combined. The exact format doesn't really matter so an array like [85,10,5] or an object {"h":85,"s":10,"l":5} is fine.

configuring the join node like this covers the case where I get all 3 inputs:

My problem is that the source works in an inconsistent way. It only sends an update when the specific setting changes. Thus {"h":85,"s":10,"l":5} to {"h":105,"s":90,"l":15} gets 3 outputs, but {"h":85,"s":100,"l":100} to {"h":205,"s":100,"l":100} only gets a reading from the 116/Hue topic.

I thought my problem might be solved by checking the "and every subsequent message." option. This works for {"h":85,"s":100,"l":100} to {"h":205,"s":100,"l":100}, but for {"h":85,"s":10,"l":5} to {"h":105,"s":90,"l":15}, I get 3 outputs {"h":105,"s":10,"l":5}, {"h":105,"s":10,"l":15}, then {"h":105,"s":90,"l":15},

What I am trying to figure out is how to only get the 3rd in the sequence when there are multiple outputs, but if there are on 1 or 2 get the last in that sequence.

Any approach would be welcome. I want to minimize the delay in getting that item, but think that some delay must be required as it is impossible to know up front how many results will be coming from the join node.

You can use a trigger node to wait for an amount of time and then send last event. You can also use just one mqtt node and use wild cards 116/#

[{"id":"52e50100.510f98","type":"mqtt in","z":"190c8195.72b3be","name":"","topic":"116/#","qos":"2","datatype":"auto","broker":"d675b749.04b9c8","x":150,"y":520,"wires":[["cfb5878c.b33a38"]]},{"id":"cfb5878c.b33a38","type":"function","z":"190c8195.72b3be","name":"","func":"msg.topic = msg.topic.split(\"/\").slice(-1).join(\"\").substr(0,1);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":360,"y":520,"wires":[["fa956e40.56345"]]},{"id":"fa956e40.56345","type":"join","z":"190c8195.72b3be","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":520,"y":520,"wires":[["4a4c9987.bb8f7"]]},{"id":"1a5b2d26.c9ade3","type":"inject","z":"190c8195.72b3be","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"116/hue","payload":"","payloadType":"date","x":170,"y":600,"wires":[["cfb5878c.b33a38"]]},{"id":"626cc0b8.07ff48","type":"inject","z":"190c8195.72b3be","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"116/level","payload":"","payloadType":"date","x":170,"y":640,"wires":[["cfb5878c.b33a38"]]},{"id":"792b7254.a54ce4","type":"inject","z":"190c8195.72b3be","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"116/saturation","payload":"","payloadType":"date","x":220,"y":680,"wires":[["cfb5878c.b33a38"]]},{"id":"4a4c9987.bb8f7","type":"trigger","z":"190c8195.72b3be","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"1","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":680,"y":520,"wires":[["603767ef.3eeb88"]]},{"id":"603767ef.3eeb88","type":"debug","z":"190c8195.72b3be","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":490,"y":580,"wires":[]},{"id":"d675b749.04b9c8","type":"mqtt-broker","name":"Localhost","broker":"localhost","port":"1883","clientid":"","usetls":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
1 Like

Thanks for the pointer. The trigger node is exactly what I was looking for.

Would the Timeout option in the node also do what you want?

I find the trigger to be more efficient.
2 messages 300ms apart with a 1 second delay outcome aprrox 1.3 second, with extend delay
The join node time out would always be 2 seconds, maybe 3 would be safer
The trigger could also be faster but then again also slower. Can't remember does the join also do milliseconds?

I think the key question is, what is the normal timing of the incoming messages?

I have been experimenting and it looks like 130ms is about the max between any 2 of the inputs. So I am finding that the trigger is more efficient. It has the advantage of only extending the wait if another shows up while the timeout under the join requires setting the timeout to a multiple of the max possible interval between the 2.

How are the mqtt publish events triggered at the source? Are they sequential or all from the same event?

The event occurs on my Hubitat hub, but the Hubitat output sends them as separate events. An otherwise irrelevant set of processing moves them to MQTT, but even direct Hubitat to Node-Red is 1-3 seperate events.

Oh, I should say that 130ms is the max, the typically interval between them is ~5ms.

Why are they not always all there?

I suspect it is the way the hubitat nodes were built or the way the hubitat maker interface works, but it does complicate this use case. I would love to just receive the triplet of values on a change.

That said, the hubitat nodes are phenomenal in most ways and so this is more a quibble than a real complaint.

It only sends the values that change, instead of all of them.

Doesn't that mean that actually if there is one missing that you want to use the value from last time in your output?

Yes, and the join node is keeping the old values thanks to the "and every subsequent..." check.

OK, then yes, the trigger node on the output is the way to go. I had missed that you have Every Subsequent selected.

Yes, I didn't show it checked in my screenshot to start this.

Of course if you want to see the really messy thing that I am trying to address, look at this post:
Color Bulb Synch

That makes this issue look easy.

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