Asynchronous button?

Hello everyone,

I got the new bme688 that has an improved gas sensor. I have set it under the sink where I have the bin/trash. The idea is that if food begins to smell too much I will get an alert message. However, at the moment I am only collecting data, but I need to set a button in the dashboard that send a string such as "bins/trash changed" so I can keep track of any changes after bin/trash has been changed.

I have four MQTTs (temperature, pressure, humidity & gas) that go into a join, from the join to a function and from the function to a database. The readings come every 15 minutes. Is there a way to have an asynchronous button that saves the input (i.e. "bin/trash changed") after pressing the button and then injects it back into the flow when the rest of the readings are ready?

PS. I tried searching for a something similar but could not find anything specific

Many thanks

Not quite sure what you mean - but do you mean you want to add it into the join when that next happens ? - if so you could maybe use msg.complete to trigger the join - and add that to the last of the usual 4 MQTT messages to arrive (say gas) ... then if the button also injects into the join - then next time round you would get 5 entires in your join rather than 4... Is that it ?

You say "gas" I assume this is VSC for your waste food application? Do you read this specifically from the IC2 interface? Are you training the sensor and creating your own algorithm? Maybe why you need the bin empty timestamp?

OK. Apologies. Let me try to re explain.

I have a SQL table with the next columns: Date, temperature, pressure, humidity, gas and binChanged. I have temperature, pressure, humidity and gas coming (individually) from the bme688. The flow has 4x MQTT that go into one JOIN, then a FUNCTION (to collect all the readings and create an INSERT INTO string with the readings) and finally the SQLITE node.

At the moment, the "binChanged" column is not getting filled. My idea is that I have a button that inserts a "YES" string when I press the button into the "binChanged". I have an ESP32 that takes readings every 15 minutes.

I would like a button that inserts a string "YES" and stores the string until the next reading so I get something like this:

"2021-11-01 11:00, 32, 12, 100, 31230, YES"

I hope that is more clear :slight_smile:

Thanks for the help

Apologies. Where is the "msg.complete"? I am a newbie.

it is nowhere until you create it.

e.g. a change node set msg.complete to true

As a new user, I recommend watching this playlist: Node-RED Essentials. The videos are done by the developers of node-red. They're nice & short and to the point. You will understand a whole lot more in about 1 hour. A small investment for a lot of gain.

1 Like

Hi here is an example, when button is pressed a context storage variable is set to yes, when sql query is created it checks for context variable and if not null will add binChanged to the sql query, Then it resets the context variable to null.

[{"id":"491bc432.e6df9c","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/temperature","payload":"20","payloadType":"num","x":170,"y":2900,"wires":[["453a8e19.b837f"]]},{"id":"453a8e19.b837f","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"$split(topic,\"/\")[-1]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":2920,"wires":[["ef28ab87.99c3f"]]},{"id":"2942f0bd.4b7c9","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/pressure","payload":"900","payloadType":"num","x":170,"y":2940,"wires":[["453a8e19.b837f"]]},{"id":"da1f5838.4c3888","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/humidity","payload":"70","payloadType":"num","x":180,"y":2980,"wires":[["453a8e19.b837f"]]},{"id":"9e8536cc.fd8638","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/gas","payload":"27","payloadType":"num","x":160,"y":3020,"wires":[["453a8e19.b837f"]]},{"id":"ef28ab87.99c3f","type":"join","z":"c74669a0.6a34f8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":430,"y":3000,"wires":[["6b4e4ffb.c83298"]]},{"id":"6b4e4ffb.c83298","type":"function","z":"c74669a0.6a34f8","name":"","func":"let binChange = flow.get(\"binChange\") || null,\nvalues=[new Date().valueOf(), \n    msg.payload.temperature,\n    msg.payload.pressure,\n    msg.payload.humidity,\n    msg.payload.gas,\n    `'${binChange}'`]\ncolumns=[\"Date\", \"temperature\", \"pressure\", \"humidity\", \"gas\", \"binChange\"];\nif(binChange=== null){\n    columns.pop();\n    values.pop();\n}else{\n    flow.set(\"binChange\", null);\n}\n\nmsg.topic =`INSERT INTO table_name (${columns.join(\", \")}) VALUES (${values.join(\", \")});`;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":590,"y":3000,"wires":[["327aee38.7d8842"]]},{"id":"327aee38.7d8842","type":"debug","z":"c74669a0.6a34f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":690,"y":2920,"wires":[]},{"id":"dd75a682.36c55","type":"inject","z":"c74669a0.6a34f8","name":"button","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":100,"y":3140,"wires":[["a3859e2b.69456"]]},{"id":"a3859e2b.69456","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"binChange","pt":"flow","to":"yes","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":3140,"wires":[[]]}]

[edit]
And here it is altered so it will enter changed and not changed.

[{"id":"491bc432.e6df9c","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/temperature","payload":"20","payloadType":"num","x":170,"y":2900,"wires":[["453a8e19.b837f"]]},{"id":"453a8e19.b837f","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"$split(topic,\"/\")[-1]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":2920,"wires":[["ef28ab87.99c3f"]]},{"id":"2942f0bd.4b7c9","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/pressure","payload":"900","payloadType":"num","x":170,"y":2940,"wires":[["453a8e19.b837f"]]},{"id":"da1f5838.4c3888","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/humidity","payload":"70","payloadType":"num","x":180,"y":2980,"wires":[["453a8e19.b837f"]]},{"id":"9e8536cc.fd8638","type":"inject","z":"c74669a0.6a34f8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"sensor/gas","payload":"27","payloadType":"num","x":160,"y":3020,"wires":[["453a8e19.b837f"]]},{"id":"ef28ab87.99c3f","type":"join","z":"c74669a0.6a34f8","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":430,"y":3000,"wires":[["6b4e4ffb.c83298"]]},{"id":"6b4e4ffb.c83298","type":"function","z":"c74669a0.6a34f8","name":"","func":"let binChange = flow.get(\"binChange\") || \"not changed\",\nvalues=[new Date().valueOf(), \n    msg.payload.temperature,\n    msg.payload.pressure,\n    msg.payload.humidity,\n    msg.payload.gas,\n    `'${binChange}'`]\ncolumns=[\"Date\", \"temperature\", \"pressure\", \"humidity\", \"gas\", \"binChange\"];\nif(binChange===\"changed\") flow.set(\"binChange\", \"not changed\");\nmsg.topic =`INSERT INTO table_name (${columns.join(\", \")}) VALUES (${values.join(\", \")});`;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":590,"y":3000,"wires":[["327aee38.7d8842"]]},{"id":"327aee38.7d8842","type":"debug","z":"c74669a0.6a34f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":570,"y":2740,"wires":[]},{"id":"dd75a682.36c55","type":"inject","z":"c74669a0.6a34f8","name":"button","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"changed","payloadType":"str","x":100,"y":3140,"wires":[["a3859e2b.69456"]]},{"id":"a3859e2b.69456","type":"change","z":"c74669a0.6a34f8","name":"","rules":[{"t":"set","p":"binChange","pt":"flow","to":"changed","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":3140,"wires":[[]]}]

Thanks for the recommendation. I ended up watching them all and were very helpful. I got a bit of an idea of msg.complete now. In fact, I managed to implement it in the flow. Here is a screenshot:

The issue I have now is that if I do not press the button then nothing comes up in the debug... because the msg is not complete?

This is what the join looks like:

The readings in the ESP32 are set every 5 seconds so if I press the button twice, the first message I get from the debug is correct but the second shows everything as 'undefined' except from the button property I passed. My guess is that the ESP32 hasn't collected yet the new readings so shows as undefined.

I want a flow that simply gets the readings and when I press a button (with the string "changed") the value for binChanged goes from "not changed" to "changed" regardless of the time I press it. In other words, if a reading just occurred and then I press the button, the string "change" waits until next reading and inserts "change". Example below (let's say I pressed the button at 11:46)

1, 2021/06/10 11:00, 20, 53, 80, 1123, "not changed"
2, 2021/06/10 11:15, 21, 55, 83, 1133, "not changed"
3, 2021/06/10 11:30, 22, 53, 85, 1141, "not changed"
4, 2021/06/10 11:45, 23, 51, 89, 1179, "not changed"
5, 2021/06/10 12:00, 23, 52, 90, 1200, "changed"
6, 2021/06/10 12:15, 23, 51, 89, 1179, "not changed"
...

Does that make sense? :crossed_fingers:

1 Like

I would put the "add msg.complete" node in the last to arrive mqtt input path - ie if gas is always the last one to arrive then place it there... That way it will always send whatever the join has at that point - either the 4 mqtt reading - or including the button if it was pressed in the meantime.

That's it. It worked. Thanks!!!

1 Like

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