Get unaffected link out nodes

Hi,

Is there a way to see "link out nodes" that are not connected to a "link in node" ?
It could have been an output after deploying flows.

when exporting/importing flows between enironments, links a lost, and I have to get them back manually. I fear to miss one, …

Regards,
Nicolas

Here is a flow I threw together that should find the link out nodes that don't have a connecting link. Export your flow in compact format.

  1. Enter the flow file name in the inject node at the start
  2. Enter the path to the flow file in the change node that comes next.
    In my case I'm using a Mac and the flow file is in my "Downloads" folder.
  3. press the Inject node button

What it does is read the flow file and change each occurance of },{ to },qaz{.
It then split the flow on ,qaz.
Next it searches each line for the text link out and ignores any line without that match.
Next it searches each line for the text "links":[] and ignores any line without that match
And finaly dumps the remaining lines to a debug output.

28%20AM

You can then grab the value of the id - in ths case it is d5f694c2.cae2e - and in the hamburger menu select Search Flows insert the id and it will bring you to that node.

Hope it helps you.

[{"id":"46a18e0e.b62268","type":"tab","label":"Find 'link out' node with no links","disabled":false,"info":""},{"id":"50156b53.96d05c","type":"inject","z":"46a18e0e.b62268","name":"Enter file name to search","topic":"","payload":"flows-18.json","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":80,"wires":[["293249d2.9a819e"]]},{"id":"2fbde711.56fd3","type":"file in","z":"46a18e0e.b62268","name":"","filename":"","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":110,"y":200,"wires":[["b065103f.e48b4"]]},{"id":"a9d13b86.766518","type":"split","z":"46a18e0e.b62268","name":"","splt":",qaz","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":110,"y":320,"wires":[["cf783107.6f1b6"]]},{"id":"b065103f.e48b4","type":"change","z":"46a18e0e.b62268","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"},{","fromt":"str","to":"},qaz{","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":160,"y":260,"wires":[["a9d13b86.766518"]]},{"id":"b0ad2721.5992f","type":"debug","z":"46a18e0e.b62268","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":130,"y":620,"wires":[]},{"id":"293249d2.9a819e","type":"change","z":"46a18e0e.b62268","name":"set file path and add file name","rules":[{"t":"set","p":"path","pt":"msg","to":"/Users/Paul/Downloads/","tot":"str"},{"t":"set","p":"filename","pt":"msg","to":"path&payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":140,"wires":[["2fbde711.56fd3"]]},{"id":"cf783107.6f1b6","type":"switch","z":"46a18e0e.b62268","name":"look for 'link out'","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"link out","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":150,"y":380,"wires":[["4e33606e.d56f6"]]},{"id":"4e33606e.d56f6","type":"switch","z":"46a18e0e.b62268","name":"look for no links","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"\"links\":[]","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":140,"y":440,"wires":[["d8639871.4ab578"]]},{"id":"693e8372.c48884","type":"json","z":"46a18e0e.b62268","name":"","property":"payload","action":"","pretty":false,"x":110,"y":560,"wires":[["b0ad2721.5992f"]]},{"id":"d8639871.4ab578","type":"change","z":"46a18e0e.b62268","name":"Fix case where link out is last node in flow","rules":[{"t":"change","p":"payload","pt":"msg","from":"}]","fromt":"str","to":"}","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":220,"y":500,"wires":[["693e8372.c48884"]]}]```

On my Raspberry Pi, I had to make these minor adjustments to Paul's NR flow...

In the 'Inject' node I put... flow.json

And in the first change node I put... /home/pi/.node-red/projects/testing/

Note: I'm using 'projects' on my setup and the particular project was called 'testing'.

Hi,
Thanks a lot for your quick replies.
Indeed, it can be easily done by parsing the json file.
I managed to automatically repair broken links, based on simple link names syntax ("->xxx" for link out, "xxx" for link in).

Blockquote
[{"id":"4d098c59.0afd04","type":"debug","z":"ec0052b3.387cc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":250,"y":500,"wires":},{"id":"69580034.02955","type":"inject","z":"ec0052b3.387cc","name":"Enter file name to search","topic":"","payload":"flows.json","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":80,"wires":[["4548fea0.05603"]]},{"id":"63b5af5d.ecfa","type":"file in","z":"ec0052b3.387cc","name":"","filename":"","format":"utf8","chunk":false,"sendError":false,"x":150,"y":200,"wires":[["8583b547.786c18"]]},{"id":"4548fea0.05603","type":"change","z":"ec0052b3.387cc","name":"set file path and add file name","rules":[{"t":"set","p":"path","pt":"msg","to":"C:\Users\std\Desktop\","tot":"str"},{"t":"set","p":"filename","pt":"msg","to":"path&payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":140,"wires":[["63b5af5d.ecfa"]]},{"id":"8583b547.786c18","type":"json","z":"ec0052b3.387cc","name":"","property":"payload","action":"","pretty":false,"x":220,"y":260,"wires":[["106701d9.38777e"]]},{"id":"106701d9.38777e","type":"function","z":"ec0052b3.387cc","name":"","func":"msg.file=msg.payload;\nmsg.filenameIn=msg.filename;\n\n\nfor(i=0;i<msg.payload.length;i++)\n{\n var type = msg.payload[i].type;\n if (!msg[type])\n msg[type]=;\n msg[type].push(msg.payload[i]);\n\n \n}\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":320,"wires":[["7bb37652.f7a658"]]},{"id":"7bb37652.f7a658","type":"function","z":"ec0052b3.387cc","name":"","func":"msg.filenameOut=msg.filenameIn+".txt";\nmsg.filename=msg.filenameOut;\nmsg.fileOut=;\n\nmsg.var={};\nfor(i=0;i<msg.file.length;i++)\n{\n if ((msg.file[i].type=="mongodb2 in") &&\n (msg.file[i].configNode===""))\n msg.file[i].configNode=msg.mongodb2[0].id;\n \n if ((msg.file[i].type=="link out") &&\n (!msg.file[i].links[0]))\n {\n msg.var.linkId0="toto";\n var linkId="toto";\n var linkTitle=msg.file[i].name.substring(2);\n for(k=0;k<msg["link in"].length;k++)\n {\n if (msg["link in"][k]["name"]==linkTitle)\n linkId=msg["link in"][k]["id"];\n msg.var.linkId=linkId;\n }\n msg.file[i].links[0]=linkId;\n \n }\n \n \n \n msg.fileOut.push(msg.file[i]);\n}\n\nmsg.payload=msg.fileOut;\nreturn msg;","outputs":1,"noerr":0,"x":230,"y":360,"wires":[["200435f2.85096a"]]},{"id":"10b7460c.aa5e9a","type":"file","z":"ec0052b3.387cc","name":"","filename":"","appendNewline":true,"createDir":false,"overwriteFile":"true","x":270,"y":440,"wires":[["4d098c59.0afd04"]]},{"id":"200435f2.85096a","type":"json","z":"ec0052b3.387cc","name":"","property":"payload","action":"","pretty":false,"x":260,"y":400,"wires":[["10b7460c.aa5e9a"]]}]

Blockquote

So you have solved your issue, that”s great!

Meta-programming at its best - love it! :slight_smile:

2 Likes

I'm using a similar approach to retrieve flow statistics... number of nodes, subflows, inputs... et cetera. :grinning: