Help simplifying flow

I have been using node-red for several years, but I've only learned just enough to get by. I've attached a screenshot of my flow that does the following:

Captures wifi probe requests (lower left which is a pcap node)
Publishes detected MAC addresses to MQTT Topic
Listens to same MQTT Topic (upper left)
Routes message by MAC address, one output is my phone, one output is my wife's phone, all other MAC addresses are ignored
Forwards to watchdog timers - one each for Jeff and Tracey that after 5 minutes of inactivity triggers a network scan, and one each for Jeff and Tracey that after 12 minutes of inactivity triggers an "away" message, and one that after 12 minutes of inactivity of both Jeff and Tracey turns on my motion detection camera
Then there is some logic to keep scanning the network once per minute after the motion detection is turned on, and some other nodes to turn off the motion detection as soon as anyone is detected, either from the detection of the probe request or by the active network scan.

It works well, but it seems overly complex. I have deliberately avoided writing javascript to simplify, but I'm thinking there should be ways to simplify even without javascript. It's very brute force as it is.

It would be interesting to hear how others might design a similar flow.

Cheers
Jeff

1 Like

Jeff, a design like this is very hard to follow. You have managed to create a graphical spagetti code. Good news you say it works as expected so the first thing, before trying to optimize, clean it up to make it easier to understand and for the future, easier to maintain

First thing is therefore to start moving things around to make a clearer view

I would:

  • see if I could break apart things a bit, put similar functionality more together so to say (obviously, the whole functionality relies on the scanning)
  • figure out if I should split things on separate tabs or create a subflow
  • never going back & forward will all those connections
  • design the flow from a top/down and left to right approach (or another orientation if you prefer but keep a structured one)
1 Like

Is there a difference between tracey or jeff away/home (other than the timers), or do you just want to determine if at least one or none are home ?

Personally I would handle everything before it goes into mqtt and use that as a state.

Thanks for the reply.

The only reason to separate Jeff and Tracey is that the link to another flow at the end goes to a telegram bot that sends those state changes as a message. I want those messages to differentiate Tracey and Jeff. I agree it could be much simpler if the flow doesn't care who is home as long as one of us is home.

The pcap probe request sniffing function is going to be off-loaded to an ESP32. This is so I can move node-red off the raspberry pi and into a container on a server that doesn't have wifi. That's the only reason mqtt is present. It's an intermediate state while I migrate. The ESP32 will be harder to change, so I just want it sniffing and sending MAC addresses to the flow via mqtt.

I'm currently "refactoring" lol, while I move most of the flow to the server node-red instance. I've simplified it slightly, taking advantage of the trigger node's new ability to handle messages on a per topic basis. It only helps on the 5 minute trigger though. If I combine the Jeff and Tracey 12 minute triggers, I'll only have to split the message it emits back out to set the separate presence messages.

Edit: I think the messages could be structured and carry more useful information that might simplify the flow. I feel like I am missing something because it's mostly just nodes triggering other nodes without passing anything useful in the message content. Otherwise I am pretty happy with how well it functions.

nodeshot

Is there anything in the msg that indicates it t is Jeff or Tracy? if so, before your twitter bot you should be able to determing who it is.

Have you thought about combining the three switch nodes into one?

Also the trigger node can be set to handle each msg.topic independently - so as long as the topic contains the identification (mac) then the same set of triggers could be re-used. (and then as Colin suggests - split the delivery - now based on topic - at the final step).

Colin?? I see I need to change my profile name :stuck_out_tongue_closed_eyes:

Yikes.. many apologies !

1 Like

Well I would have suggested if I had thought of it.

1 Like

On top of the excellent suggestions provided, I'd agree that having visuals that are messy makes the thing look and feel a lot more complex than it really is.

It is a really good idea to try and minimise or eliminate crossing wires - the easiest being that debug node which should be at the top out of the way.

Whenever I have a wire that goes backwards like you have quite a few of, I will always replace those with link nodes. That greatly simplifies the layout and makes it a lot easier to follow.

Also think about the problems you will have with this flow in 6-12 months time. If it isn't immediately obvious how it works, you will waste a lot of time working things through before you can make even the easiest of amendments. Comment nodes, the new node description option (v0.20) and named inputs/outputs make a massive difference.

This is a good suggestion and notice that in the revised flow shown in post 4 I combined them, however it doesn't work as expected. I had originally tried one switch node when I first built it and couldn't work out the issue. It seems I haven't gotten any smarter because I still can't make it work.

The top output of the switch node fires if the input contains Tracey's MAC Address, the middle fires where it contains Jeff's, and the bottom is Otherwise. For some reason the otherwise leg never fires. I have the flag in the node set to "checking all rules."

The issue is that once the 5 minute trigger fires for both Jeff and Tracey topics, the active scan never occurs again. If the active scan output doesn't include Jeff or Tracey's MAC, I expected the Otherwise output on the switch node to fire but it doesn't.

What I want it to do is fire the active scan node once per minute as long as either Tracey or Jeff has not been seen for 5 minutes. The reason for that is that if the phones get sleepy and don't send any probe requests - the active scan (which uses the arp-scan linux command) finds them.

I could rely solely on the active scan, but the captured probe requests act much more quickly to disable the motion detection when we arrive home because they are seen before connection to the home network is negotiated.

In the second flow shown in post 4, I used this feature in the five minute trigger. The change nodes prior to the trigger change the topic to Jeff or Tracey based on the MAC Address. I can't work out how to combine the 12 minute triggers into one because I need different messages to be emitted from the trigger and it looks like the trigger node only emits true or false.

Agreed. In this case I don't have any trouble following even after not looking at it for a year but I know what it does. On the other hand, is there a way to tell which link goes where when there are multiple links in a screen shot? Isn't selecting or hovering over the link node required to see where it goes?

I'd have a bash at simplifying it (in terms of how many nodes, the layout, the ease of comprehension) if you post your flow(s)?

Otherwise I'm looking at a graphic and thinking, WTF is that :smiley: ?

Off the top of my head (some things others have suggested)...

  • why does the node "Route" have 3 outputs when 2 of then go to "jeff detected"
  • All those trigger nodes... cant they be combined?
  • "many to many" == crossed wires & confusion! Instead of multiple nodes feeding multiple nodes (many wires), use link nodes.
  • Add comment nodes to augment comprehension.

TBH, there is nothing really wrong with your flow. There are always many ways to skin a cat. Your cat seems to be fairly well skinned. If you`re happy with it (both functionally and aesthetically), then you should ignore everything I have written :smiley:

Good luck & happy flowing.

Thanks for the comments everyone. Attached is a somewhat simplified flow, although I'm not confident of the shared trigger behaviour and the combined switch nodes as compared to the original flow. It doesn't seem to behave identically to the first flow, though according to my understanding it should. I'll have to let it work for a while to pinpoint what is causing the different behaviour.

Edit: I can articulate why the combined switch node doesn't do what I want it to do. It needs to route Jeff and Tracey's MAC addresses into the flow, either from the sniffed probe requests mqtt node or the result of the scan. While each probe request contains only one MAC Address, the active scan has 4 possible results I am interested in:

  1. Both MAC addresses
  2. Tracey's MAC address
  3. Jeff's MAC address
  4. Neither MAC address

Each of those conditions require a different action from the flow. The first three must pass the messages to the presence nodes as shown. The last three must continue the once per minute scan for the missing phone(s). Can I combine this into one switch node? What I have shown in the most recent flow doesn't do this.

What I seem to need is one of the following from the switch node in order to get the behaviour I want without needing three switch nodes:

  • Incoming message DOES NOT CONTAIN a particular MAC address
  • Incoming message contains BOTH Tracey's MAC address AND Jeff's MAC address

Is either of the above possible? I'm not really up to speed on the expression matching possibilities. Happy to be directed to relevant reading material.

Here's where I ended up:

nodeshot

I've reduced the number of nodes by three sharing two of the triggers. I had to revert back to three switch nodes to get the behaviour I mentioned above. I'm not sure it's more readable, but at least I've learned a couple of things.

Personally I would split this into multiple separate flows using MQTT to link between them. For example I would split out the presence detection into a separate flow that keeps track of who is present and maintains the presence state of each person in MQTT.

Then the motion detection stuff would be in another flow that picks up the current presence states and decides what to do, setting the required motion detection state in MQTT.

Then a third that picks up the required detection state and drives the cameras etc.

By using Retained topics in MQTT then if the system is restarted it will automatically restart in whatever mode it was before.

Not sure whether there is anything left after doing that. Perhaps that is everything.

A further advantage of this approach is that if you think of something else that depends on presence then you just need a new flow picking up the presence states and doing whatever it is, there is no need to go back and modify existing flows, with the danger of messing them up.

Thanks. I will do this eventually. When I do I don't imagine it will look a lot different. I'll just put an mqtt out node in place of the link node at the far right. I can move the logic for the alarm and motion commands to another flow, but it will still be required.

I still think there has to be a better way to achieve the result of those three switch nodes with fewer nodes. I played around with it for quite a while and ended up going back to the original.

It will look different as each bit will be on separate tabs, one to maintain the presence status, one to drive the motion state, one to drive the camera etc. Each one will be much simpler.