I was curious (and would REALLY appreciate it) if anyone has an elegant solution in Node-RED for the following problem:
I have data coming in messages from my thermostats in different rooms. Temperatures and setpoints for each room come in separate messages both as "value", with type "temp" or "setpoint", but with the same "description"/roomname field. Topics are "home/roomname/temp" or "home/roomname/setpoint".
How can I combine each message with the same "description"/roomname so I can get a message to send to the IFTTT maker channel/webhook where the included "msg.payload.value1" is the "description"/roomname, "msg.payload.value2" is the temperature, and "msg.payload.value3" is the setpoint. And not send one combined message out more often than every 4 seconds.
I understand that I have to combine or join messages filtered/sorted on the "description"/roomname or topic somehow, but can't seem to figure out how to use the join node or contrib-combine to achieve this.
Is there a pattern to the incoming messages (time based or number of messages) ?
The batch node can do this. See documentation.
You could also store the data from each thermostat in a flow context, use a change node or function to modify the properties and use that to send to IFTTT.
"Combine" may have been the wrong word in English, but I meant to get properties from several (2 defines by the same topic) messages and send one message with all the data as new properties.
There's a pattern in that they come around once each 10 minutes. Also that they do come in both of the types but not necessarily in order.
However, I hadn't thought of the flow context variables. I was thinking of retaining MQTT messages (which are also sent per message) with timed reading of these, but may be error prone.
Will a change node store variables to the flow context or do I have to initialise them programmatically ? Also how do I store and retrieve an object where for each key "description"(room name) there are subkeys for "temp" and "setpoint" with a change node ?
Updating current conditions by reading data from sensors or by change of setpoints
Sending out messages to third party (IFTTT)
Those parts are logically connected as the system is one and only but they are different as they deal with different tasks. So it is meaningful to separate them visually and create their logic in different TAB-s (this is just suggestion)
Definitions and data storage.
So you have home. var home = {} (object)
Home has rooms. home.rooms = []
Lets define rooms.var room = {name:"name of room",temperature:0, setpoint:0, updatetime:0}
... there will be more rooms...
but they all end up in rooms array home.rooms[0] = room
By creating such structure and storing it in global context you can then update any of values when they change and store it again as most updated state of your home. Why global context? Because of
Updating current condition
Where ever you'll need to read any of values, or change some of value, you can do it as simple as
var home = global.get("home")
var room = home.rooms["name of room"]
room.temperature = 25
room.updatetime = new Date().getTime()//timestamp
global.set("home",home)
or by using other function type dedicated nodes
Now as you have always up to date home you can create messaging system whatever kind you like. some injector -> read values from home -> combine and create message-> send message
This way your system will be easy to manage and easy to use, it'll be simple to add properties to your objects without need to create all over again and stuff like that.
That's probably a good way to think of the problem. I'm just not into javascript at all so would need hand-holding. For example I don't understand that a room in the structure as in section 1 is findable by "name of room" in section 2 because I would think you have to find it by array number... ?
Also is the whole section 2 equally easy to do in a Change node ?
As I said it is a bit pseudo coding in examples just to bring code and real life close together.
In reality there is many ways to do it and every one has its own pros and cons and it all depends on needs and so on...
But it all is documented well and is worth of a bit reading time JavaScript objects JavaScript Arrays
Basically all of it can be achieved without using the function node. But even then you can understand those nodes better if you understand the structure of your data.
I ended up using contrib-config to make a global object for every room, its temperature and setpoint, and Booleans for both temp and setpoint to signify whether I have gotten new data (they come separately and the booleans are reset when a combined message is sent to IFTTT), whenever NR is restarted.
Also I retained (in Mosquitto) the temps and setpoint already sent via MQTT to make sure my object is quickly populated on restart, and also use an MQTT-in node as input.
I then use a function node to add data to the global object, make adjustments to values, check Booleans and possibly prepare for sending to IFTTT. You were right in preferring function nodes, I just thought this could have been such a common pattern that some kind of generic node existed.