Is there a better way to query an mqtt topic for most recent message?

711 views
Skip to first unread message

Nick Barnett

unread,
Feb 11, 2017, 1:04:01 AM2/11/17
to Node-RED
I'm looking into trying to create some "complex" flows and wanted to ask the hive if I'm reinventing the wheel. My goal is to make some IF THEN, ELSE IF, ELSE type decisions. 

Short scenario 1: I have a motion sensor on my back porch. If it's dark outside (either with a photo sensor, or maybe using HTTP data to obtain sunrise/senset info) AND I have the stereo on (using a hall effect sensor on a speaker), then fire a relay that turns on the outside speakers when the PIR is activated.

Short scenario 2: I have a momentary switch that when pressed toggles a set of lights in the kitchen. I also have a "scene" on my node-red dashboard called "goodnight" which turns off many devices.  If I press the momentary switch between 11pm and 6am, rather than toggling the set of kitchen lights, I'd like it to run the same goodnight scene I have on the dashboard.

My whole automation system is using MQTT, and I can retain the appropriate messages, but I don't know how to query them. Since I don't know how to query them (not even sure if it's possible...), I'm also storing the messages in a sql database. This starts to get complicated really fast with multiple INSERT, SELECT, UPDATES, etc...  

Am I barking up the wrong tree? Am I going to hit some unforeseen wall that is totally obvious to someone else? Does anyone else have any BETTER ideas?

Thanks!
Nick

Colin Law

unread,
Feb 11, 2017, 4:04:55 AM2/11/17
to node...@googlegroups.com
There should be no need to store them in the db, feed them into the
nodes that need them and save them in context variables. Then they
are immediately available when another input is fed into the node.
This is the pattern I use in numerous function nodes that need to take
action based on a number of inputs. Each time it is used it is only
necessary to setup the contents of requiredInputs. I tried to work
out how to use the merge node to do the same thing but did not manage
to achieve it.

// these are the topics that need to be provided before we can do anything
// and the context var names to save them in
var requiredInputs = {
"some_topic/name1": "name1",
"some_topic/name2": "name2",
"etc": "etc"
};
// see if msg.topic is one of the inputs we have to save
for (var topic in requiredInputs) {
if (msg.topic == topic) {
// yes it is so save it
context.set(requiredInputs[topic], msg.payload);
break;
}
}
// whatever the message was, see if we have all the data we need to carry on
var allOK = true;
for (var topic in requiredInputs) {
if (typeof context.get(requiredInputs[topic]) === 'undefined') {
allOK = false;
break;
}
}
if (allOK) {
// if we get here then we know we have got up to date values for all
the topics in requiredInputs
// available using context.get("name1") etc
...

Colin
> --
> http://nodered.org
>
> Join us on Slack to continue the conversation: http://nodered.org/slack
> ---
> You received this message because you are subscribed to the Google Groups
> "Node-RED" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to node-red+u...@googlegroups.com.
> To post to this group, send email to node...@googlegroups.com.
> Visit this group at https://groups.google.com/group/node-red.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/node-red/9c6e76ff-d3f9-4188-9ede-c5d410ca519b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Julian Knight

unread,
Feb 11, 2017, 11:25:47 AM2/11/17
to Node-RED
You are in the right area certainly. Though, as Colin say's, MQTT is a messaging tool rather than a database so it will send you the data when it is updated as long as you have subscribed to the appropriate topic(s). You can then keep that in a memory variable (context, flow or global). If you specify that the message is "retained" when you send it, the MQTT broker will reissue the message to all subscribed clients when they reconnect after a reset so you always get the last message when the system starts up.

MQTT is a way of keeping functional elements of your logic loosely connected which makes it a lot easier to manage. Especially over time when you need to change some elements or add new sensors.

I have some similar processes to you. In particular, the movement sensor in the hallway just alerts during the day but at night, it issues MQTT messages that result in the hall and landing lights being turned on for a few minutes.

Nick Barnett

unread,
Feb 11, 2017, 1:01:16 PM2/11/17
to Node-RED
Thanks guys! Contexts. That's the thing I didn't know existed. I knew there had to be a better way. I'm (obviously) not a programmer, so when I read that part of the documentaiton, it just dind't CLICK. Now that I know the context of contexts, I think I can figure this out :)

One more quick question. Will the context stay in memory after a "deploy" has been issued?  IE, when I'm writing and debugging my code, will a deploy clear out all of the contexts I have set?

Colin Law

unread,
Feb 11, 2017, 3:52:03 PM2/11/17
to node...@googlegroups.com
Yes, I believe so. But, as Julian said, if you publish the mqtt
topics with Retain true then when you deploy the mqtt in node will
serve the value again even if the mqtt server has been restarted, so
you will be back where you started (at least as far as mqtt topics is
concerned).

Colin

Julian Knight

unread,
Feb 12, 2017, 8:09:21 AM2/12/17
to Node-RED
Yes, it is retained while the Node.JS process containing the Node-RED app is still running.
Reply all
Reply to author
Forward
0 new messages