How to trigger a web page to pop up the minute a serial output satisfies a condition?

I recently made a sensor using my Arduino that essentially displays the distance between an object continuously, it outputs to the serial monitor with no issue whatsoever. I wanted to spice it up by connecting it to my Pi and playing music whenever the distance would be a certain value, and saw that Node Red would be the best option for it, so I connected it, tested it and saw that it picked up on the output from the Arduino straight to the debug screen.

Problem is, I wanted to create a conditional statement that would trigger a web page(Random Youtube Video) to pop up and basically play it but after trying to find tutorials online to see if such had ever been done, I had never found any. No tutorials or anything. Therefore, I would be happy if you could explain the solution plus any learning material I could use for this.

Thank you in advance

If your raspberry pi is not headless you can use an exec node to start chrome on your Raspberry pi.

Can i still do that headless? I connect to it via remote desktop.
So this exec node would basically take in the command of, say "if msg.payload = distance: 20cm, thne pop up browser with video" and work?

yes, although on Rasperry Pi you can also use OmxPlayer and youtube-dl to play videos directly to the frame buffer, see
https://www.raspberrypi.org/forums/viewtopic.php?t=63632
You could also use the Exec node for that.

That's cool I think I almost get it now, just unsure of how one triggers the exec node whenever the condition is true. For example

if (msg.payload = 'Distance 20cm') {
--do something to trigger exec node
}

If that is the only thing happening in the function node, I'd use a switch node and then connect the output to an exec node to run what you want.

Also if you use this
if (msg.payload = 'Distance 20cm') {
in a function node, it will always be true because the single = assignes the variable the value of the string. You want to use ==

here is a simple examle using the switch node:

[{"id":"e2f048968c3d7a0b","type":"inject","z":"e041ef3e956367b4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Distance 20cm","payloadType":"str","x":260,"y":240,"wires":[["35a58c1abb9ccdc9"]]},{"id":"35a58c1abb9ccdc9","type":"switch","z":"e041ef3e956367b4","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Distance 20cm","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":480,"y":300,"wires":[["1808531aabcb9fc2"],["55e42dc49cd65f7e"]]},{"id":"55e42dc49cd65f7e","type":"debug","z":"e041ef3e956367b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":360,"wires":[]},{"id":"1808531aabcb9fc2","type":"exec","z":"e041ef3e956367b4","command":"echo","addpay":"","append":"'hello world'","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":710,"y":280,"wires":[["699a4598a4066475"],["9e2c6190b283ca9f"],["6f48b5d1cb4946a8"]]},{"id":"ab0f9213b4e2682b","type":"inject","z":"e041ef3e956367b4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Distance 99cm","payloadType":"str","x":260,"y":360,"wires":[["35a58c1abb9ccdc9"]]},{"id":"699a4598a4066475","type":"debug","z":"e041ef3e956367b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":240,"wires":[]},{"id":"9e2c6190b283ca9f","type":"debug","z":"e041ef3e956367b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":280,"wires":[]},{"id":"6f48b5d1cb4946a8","type":"debug","z":"e041ef3e956367b4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":870,"y":320,"wires":[]}]

Here's an example with a change node (to extract the number) and a switch node.
The advantage here is you can do things like greater than or less than in the switch node:

[{"id":"169422d2.3157e5","type":"inject","z":"853cfa30.9644a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"\"Distance: 69cm\\n\"","payloadType":"json","x":610,"y":140,"wires":[["9a611463.ab80c8"]]},{"id":"33cb67c6.2c46e8","type":"switch","z":"853cfa30.9644a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"69","vt":"num"},{"t":"gt","v":"60","vt":"num"},{"t":"gt","v":"100","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":1050,"y":140,"wires":[["56c76e80.e86208"],["c242e13a.006e58"],["2c28dfc2.5636d"]]},{"id":"9a611463.ab80c8","type":"change","z":"853cfa30.9644a","name":"convertToNumber","rules":[{"t":"set","p":"payload","pt":"msg","to":"$match(payload, /\\d+/).match ~> $number","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":830,"y":140,"wires":[["33cb67c6.2c46e8"]]},{"id":"4ab23ba8.f66c1c","type":"inject","z":"853cfa30.9644a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"\"Distance: 144cm\\n\"","payloadType":"json","x":610,"y":180,"wires":[["9a611463.ab80c8"]]},{"id":"56c76e80.e86208","type":"debug","z":"853cfa30.9644a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1210,"y":120,"wires":[]},{"id":"c242e13a.006e58","type":"debug","z":"853cfa30.9644a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1210,"y":160,"wires":[]},{"id":"2c28dfc2.5636d","type":"debug","z":"853cfa30.9644a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1210,"y":200,"wires":[]}]

Uh I'm not sure if it's me but I just see this:

I'm new to the site and Node Red, so I'm unsure if that is what I'm supposed to see or not

Did you copy the flow and import it?

If you put your cursor near the end of the line, a copy icon should show up
or you can select the entire line and copy/paste it into your flow.

Oh shoot I did not know that, thank you so much for letting me know. Played around with both your flows and learnt a lot from the nodes.
Several questions however:
I intended on making the switch node pick up the output from my Arduino, but was unsure of how to actually pull out, say "Distance: 20cm" from the Arduino Output. I did add a function inbetween the arduino and an exec output to do something, but it still did not respond with anything. This was the code inside the function:

if (msg.payload === "Distance: 20") {
    msg.payload = "Distance is 20cm, nice"
    return msg;
}

Another question is traversing between directories on raspberry pi: I can easily make a shutdown command with what you guys provided, but cannot for some reason, navigate through directories or make chain commands like this one: image
Like it cannot go to that directory and make a new folder named "hello world" but somehow can make a directory of its own without traversing through directories.

Without seeing the actual data coming from the arduino it is hard to give you an answer.

As for the second question, please provide the flow.

[
    {
        "id": "60cf67e173ed3e74",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "4f56b568bc65e2cd",
        "type": "serial-port",
        "serialport": "/dev/ttyACM0",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": "",
        "responsetimeout": "10000"
    },
    {
        "id": "9fc033063aefec68",
        "type": "function",
        "z": "60cf67e173ed3e74",
        "name": "CONDITION",
        "func": "//var newMsg = {payload:msg.payload.toString()};\nif (msg.payload === \"Distance: 20cm\") {\n    msg.payload = \"Distance: 20cm\"\n    return msg;\n}\n\n\n//Make a delimiter that splits the string into just the number then turn the numver into a variable which then acquires the variable data as the distance\n\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 470,
        "y": 340,
        "wires": [
            [
                "a327079557ed0ecf"
            ]
        ]
    },
    {
        "id": "880192a506a1f490",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 350,
        "y": 160,
        "wires": []
    },
    {
        "id": "6fb6e8da868a6199",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "youtube-dl --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=guf9R6qLpo4",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "Download video",
        "x": 820,
        "y": 640,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "4f762555f2e0498b",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "cd discord-bot-one",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 510,
        "y": 500,
        "wires": [
            [],
            [
                "e603bb071891dc24"
            ],
            []
        ]
    },
    {
        "id": "e603bb071891dc24",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "python3 musicPlayer.py",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 750,
        "y": 500,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "169422d2.3157e5",
        "type": "inject",
        "z": "60cf67e173ed3e74",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"Distance: 69cm\\n\"",
        "payloadType": "json",
        "x": 350,
        "y": 720,
        "wires": [
            [
                "9a611463.ab80c8"
            ]
        ]
    },
    {
        "id": "33cb67c6.2c46e8",
        "type": "switch",
        "z": "60cf67e173ed3e74",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "20",
                "vt": "num"
            },
            {
                "t": "gt",
                "v": "60",
                "vt": "num"
            },
            {
                "t": "gt",
                "v": "100",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 790,
        "y": 720,
        "wires": [
            [
                "56c76e80.e86208"
            ],
            [
                "c242e13a.006e58"
            ],
            [
                "2c28dfc2.5636d"
            ]
        ]
    },
    {
        "id": "9a611463.ab80c8",
        "type": "change",
        "z": "60cf67e173ed3e74",
        "name": "convertToNumber",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$match(payload, /\\d+/).match ~> $number",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 570,
        "y": 720,
        "wires": [
            [
                "33cb67c6.2c46e8"
            ]
        ]
    },
    {
        "id": "4ab23ba8.f66c1c",
        "type": "inject",
        "z": "60cf67e173ed3e74",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"Distance: 144cm\\n\"",
        "payloadType": "json",
        "x": 350,
        "y": 760,
        "wires": [
            [
                "9a611463.ab80c8"
            ]
        ]
    },
    {
        "id": "56c76e80.e86208",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 950,
        "y": 700,
        "wires": []
    },
    {
        "id": "c242e13a.006e58",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 950,
        "y": 740,
        "wires": []
    },
    {
        "id": "2c28dfc2.5636d",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 950,
        "y": 780,
        "wires": []
    },
    {
        "id": "e2f048968c3d7a0b",
        "type": "inject",
        "z": "60cf67e173ed3e74",
        "name": "Shutdown",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Distance: 20cm",
        "payloadType": "str",
        "x": 160,
        "y": 1000,
        "wires": [
            [
                "35a58c1abb9ccdc9"
            ]
        ]
    },
    {
        "id": "35a58c1abb9ccdc9",
        "type": "switch",
        "z": "60cf67e173ed3e74",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "Distance: 20cm",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 290,
        "y": 1000,
        "wires": [
            [
                "5ced84db8af8c5b7"
            ],
            []
        ]
    },
    {
        "id": "1808531aabcb9fc2",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "mkdir ayoo",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 590,
        "y": 1180,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "5ced84db8af8c5b7",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "sudo shutdown now",
        "addpay": "",
        "append": " ",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 460,
        "y": 980,
        "wires": [
            [],
            [],
            []
        ]
    },
    {
        "id": "830ee7b453faecee",
        "type": "serial in",
        "z": "60cf67e173ed3e74",
        "name": "Arduino Uno",
        "serial": "4f56b568bc65e2cd",
        "x": 290,
        "y": 340,
        "wires": [
            [
                "9fc033063aefec68"
            ]
        ]
    },
    {
        "id": "327d4cdc2343bd8b",
        "type": "inject",
        "z": "60cf67e173ed3e74",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Distance: 20cm",
        "payloadType": "str",
        "x": 680,
        "y": 140,
        "wires": [
            [
                "a327079557ed0ecf"
            ]
        ]
    },
    {
        "id": "a327079557ed0ecf",
        "type": "switch",
        "z": "60cf67e173ed3e74",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "Distance: 20cm",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 920,
        "y": 200,
        "wires": [
            [
                "55930c3cd6880ad0"
            ],
            [
                "a9084ac8e452b4cc"
            ]
        ]
    },
    {
        "id": "a9084ac8e452b4cc",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1170,
        "y": 260,
        "wires": []
    },
    {
        "id": "490d9ee71c4b326f",
        "type": "inject",
        "z": "60cf67e173ed3e74",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "Distance: 99cm",
        "payloadType": "str",
        "x": 700,
        "y": 260,
        "wires": [
            [
                "a327079557ed0ecf"
            ]
        ]
    },
    {
        "id": "f5a24019efb82879",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 140,
        "wires": []
    },
    {
        "id": "43aa5375e45afe7f",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 180,
        "wires": []
    },
    {
        "id": "8eaeac2f8fa14fbb",
        "type": "debug",
        "z": "60cf67e173ed3e74",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 220,
        "wires": []
    },
    {
        "id": "55930c3cd6880ad0",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "mkdir helloworld",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 1000,
        "y": 80,
        "wires": [
            [],
            [
                "8175d9847bf2ee44"
            ],
            []
        ]
    },
    {
        "id": "8175d9847bf2ee44",
        "type": "switch",
        "z": "60cf67e173ed3e74",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "cd discord-bot-one",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1190,
        "y": 80,
        "wires": [
            [
                "f20226285ae307ed"
            ],
            []
        ]
    },
    {
        "id": "f20226285ae307ed",
        "type": "exec",
        "z": "60cf67e173ed3e74",
        "command": "mkdir helloworld",
        "addpay": "",
        "append": "",
        "useSpawn": "false",
        "timer": "",
        "winHide": false,
        "oldrc": false,
        "name": "",
        "x": 1360,
        "y": 80,
        "wires": [
            [],
            [],
            [ ]
        ]
    }
]

Any issues with my flow?

Put a debug on the output of the first mkdir helloworld and also put a seperate debug node on each the outputs of the switch node and take a ook at wht your flow is doing.

Each exec is independent of any other exec node. i.e. what you do in one - like issuing a 'cd' command -will have no effect on any other exec node. You must provide the full path to directories you want to use in any command. Note, you can build a command and pass it to the exec node in msg.payload and leave the 'command' option empty and check the + Append option.

You also need to pass the path to a program you want to run. If you have a python program in /home/pi/mypython/helloworld.py and want to run it then you have to use python3 /home/pi/mypython/helloworld.py

Thank you, I did that and tested my thing further to see where the problem was coming from, and I saw that it stemmed from the condition function that I had setup, holding this code inside:

if (msg.payload == "Distance: 20cm↵") {
    msg.payload = "Distance: 20cm"
    //return msg;
}
return msg;

It would return this:
image

As you saw in that flow export, I have a switch that checks if "distance == 20cm", yet the problem is that even though this is satisfied all the time, the exec code is not executed. This is not the case, however, when using the inject button, as it straight away executes the code in the exec node(making some directory named "helloworld")
image

EDIT: I removed the function and connected straight from the Arduino serial into the switch, yet it still does not want to register that its satisfying the given requirements. Why is this the case?

Arduino output:
image

Inject Output
image

Of course, you'll see the difference here being the "↵" symbol. I'm unsure as to how once can compensate for this, maybe node red not working well with Arduino's new line maker but I do not understand what to do here.

What can I do to make this work? Because I'm not seeing what i'm missing here.

msg.payload has a `return at the end so it will not match the string in the if statement.

And with that I’m off to bed.

Use a switch node within the condition to check if the string “contains” rather than equals

2 Likes

It's moments like this that make me feel dumb as hell for not seeing that the answer is simpler than it is. Thank you so much man, I switched it to "contains" as you mentioned and it worked flawlessly! Thank you so much

9 posts were split to a new topic: Exec node calling python running pulse audio getting 'connection refused