Wait for the execution of a flow and then continoue another

Hi,

I made a flow that streams images from a cam to google nest hub. I use a webserver for publishing the file

Each file has a unique name and a prefix off xxx so that the share where these files are on are not synchronized with my nas after that the file has been shown on my nest, after that i remove the xxx prefix and all files are synced. (i use the sync because my nas isnt always on). And when the sync executes it could move active files my mistake..

For so far the context.
My problem is that i want to rename the orignal unique file after that the files has been shown on mu nest hub. But the node (castv2-sender-node = Google nest hub) kills the information that i need for the rename sudo command.

So my question is: is it possible that the rename executes after the castv2-sender-node (nest hub) is executed ? (and uses info from before the cast-node?
I use a delay node for this to work, and IT DOES WORK NOW, but i am not happy with delay solutions...
And, i like to learn how to solve this another way...

For flows like these I'm a fan of using node-red-contrib-queue-gate in closed mode, and open it once I know the result is there. In this case you could perhaps use a file watcher node to see if it is created/edited, then continue from there to send the opening signal to the gate.

There's probably better solutions than that too...

OK, i am going to study that, THANKS!

@update : So i place this node with inputs "BEWAAR FOTO FILE" and "GOOGLE Home HUB and i can use Google Home HUB as a trigger and use the info from "BEWAAR FOTO FILE" ?

OK, gates goes open en close, but does not give any outcome.
I put a debug node after it, no msg out!

OK, sorry afelix, it does work (well)!
I thougt when you activate close, it would buffer and release when open...
But close works different. It is more toggle between queue and open...

Hi @afelix

I made the flow as you suggested, and it works! See my attachment.
I made a submodule fileexist and a gatekeeper to open the gate.

In theory this flow can fail, when the "RENAME-part" of the flow is later in time than that the image is presented (the GOOGLE HOME HUB-part).

So the best solution could be if not one part opens the gate, but both have the half of the key..

Next: check that both messages belong together, but that seems impossible as two nodes delete the content of the message (node google home hub and node (file node: BEWAAR FOTO FILE)

Do you have suggestions for the two keys opening ?
flow and global vars seems not in place here to use as there are more msg from this cam flow..!

PS: by the way, i love these problems! Great way to learn about messages, flow, vars, nodes...

..

the 'join' node - add a change node to each leg of the flow to set the 'parts' up and then connect them to a `join'. Here is a sample flow demonstrating the idea
Screen Shot 2020-02-12 at 6.39.45 AM

[{"id":"bcb83c61.f0baf","type":"join","z":"fde23e1e.8ac458","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":510,"y":140,"wires":[["674bb85d.248a"]]},{"id":"9f557bbf.c47278","type":"inject","z":"fde23e1e.8ac458","name":"","topic":"","payload":"abc","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":80,"wires":[["ebcf34ce.9b0c38","5fa187b9.414bf"]]},{"id":"674bb85d.248a","type":"debug","z":"fde23e1e.8ac458","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":510,"y":200,"wires":[]},{"id":"ebcf34ce.9b0c38","type":"change","z":"fde23e1e.8ac458","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": _msgid,\t   \"type\": \"string\",\t   \"ch\": \"\",\t   \"index\": 0,\t   \"count\": 2\t}","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"ABC","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":120,"wires":[["bcb83c61.f0baf"]]},{"id":"5fa187b9.414bf","type":"delay","z":"fde23e1e.8ac458","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":180,"y":160,"wires":[["7ea2c842.1327f8"]]},{"id":"7ea2c842.1327f8","type":"change","z":"fde23e1e.8ac458","name":"","rules":[{"t":"set","p":"parts","pt":"msg","to":"{\t   \"id\": _msgid,\t   \"type\": \"string\",\t   \"ch\": \"\",\t   \"index\": 1,\t   \"count\": 2\t}","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"DEF","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":160,"wires":[["bcb83c61.f0baf"]]}]

In this case I'm joning two strings so you may need to alter the change nodes to suit your purpose.

I was just messing with the join node, and i think it is an easier solution...
I will not be lazy and post my test join before i read yours...

Thanks @zenofmud
Only thing i had to do is making dummy msg so that the msg.topic is available on both parts before the join, that was easy!

[{"id":"d10da8c0.5a5958","type":"subflow","name":"FILE_EXISTS","info":"","category":"","in":[{"x":160,"y":100,"wires":[{"id":"919001e5.4322d8"}]}],"out":[{"x":1260,"y":160,"wires":[{"id":"23e2633f.d42c2c","port":1},{"id":"525ed2fe.30ff4c","port":0}]}],"env":[],"color":"#DDAA99"},{"id":"b1b06e08.94333","type":"fs-ops-access","z":"d10da8c0.5a5958","name":"fileexists","path":"xfilestore","pathType":"msg","filename":"xfilename","filenameType":"msg","read":true,"write":false,"throwerror":true,"x":500,"y":100,"wires":[["af46224c.691d4"],["af46224c.691d4"]]},{"id":"af46224c.691d4","type":"switch","z":"d10da8c0.5a5958","name":"","property":"error.message","propertyType":"msg","rules":[{"t":"nnull"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":670,"y":100,"wires":[["3db89492.81980c"],["525ed2fe.30ff4c"]]},{"id":"3db89492.81980c","type":"function","z":"d10da8c0.5a5958","name":"nok","func":"msg.fileexist=false;\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":60,"wires":[["23e2633f.d42c2c"]]},{"id":"525ed2fe.30ff4c","type":"function","z":"d10da8c0.5a5958","name":"ok","func":"msg.fileexist=true;\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":160,"wires":[[]]},{"id":"23e2633f.d42c2c","type":"repeat","z":"d10da8c0.5a5958","name":"x times","repetitions":"5","elseOutput":true,"outputs":2,"x":570,"y":240,"wires":[["b1b06e08.94333"],[]]},{"id":"919001e5.4322d8","type":"function","z":"d10da8c0.5a5958","name":"init","func":"msg.repetitions = msg.xrepetitions;\n// xfilestore en xfilename worden via input meegegeven\n\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":100,"wires":[["b1b06e08.94333"]]},{"id":"b398a23d.84c758","type":"http request","z":"c80f5a41.19d26","name":"CAM image","method":"GET","ret":"bin","paytoqs":false,"url":"192.168.20.35:82/camsnapshot.jpg?idx=2","tls":"","persist":false,"proxy":"","authType":"basic","x":450,"y":120,"wires":[["39b78367.4b0924"]]},{"id":"f075aba.53b8758","type":"castv2-sender","z":"c80f5a41.19d26","name":"Google Home Hub","host":"","x":1070,"y":240,"wires":[["e4d9f1b7.0b9dc"]]},{"id":"39b78367.4b0924","type":"function","z":"c80f5a41.19d26","name":"BEWAAR FOTO MSG","func":"\n// this function generates a randomized file name\nvar myDate = new Date();\nvar namedate = myDate.getMonth()+ '-' +myDate.getDate()+ '-' +myDate.getFullYear()+ ':' + myDate.getHours()+ ':' + myDate.getMinutes()+ ':' + myDate.getSeconds();\n\nif (msg.service === \"Camera straat\")    nwnaam = \"BEL_CAMERA_STRAAT_\";\nif (msg.service === \"Camera tuin\")      nwnaam = \"BEL_CAMERA_TUIN_\";\n\nnaamprefix = \"xxx\";\nnwnaam1 = naamprefix + nwnaam + namedate + \".jpg\";\nnwnaam2 = nwnaam + namedate + \".jpg\";\n\nmsg.webnaam = nwnaam1;                               // naam zonder filestore met tmp prefix\nmsg.filename = global.get(\"filestore\") + nwnaam1;    // naam met filestore met tmp prefix\nmsg.filename_nw = global.get(\"filestore\") + nwnaam2;                 // naam met filestore zonder tmp prefix\nmsg.nwnaam1 = nwnaam1;\nmsg.nwnaam2 = nwnaam2;\nmsg.camoscmd= \"sudo mv \" + msg.filename + \" \" + msg.filename_nw;\n\n//flow.set(\"camoscmd\", \"sudo mv \" + msg.filename + \" \" + msg.filename_nw);\n// flow is niet ok, andere cam image msg gebruiken deze in andere runs van de flow\n\nreturn[msg]","outputs":1,"noerr":0,"x":740,"y":120,"wires":[["463a5005.9bd78","4bebd44e.939b2c","89e8222f.5e809"]],"info":"if ( msg.payload === true )\n{waarde = \"On\"}\nelse \n{waarde = \"Off\"}\n\nvar uservar = '[{\"obj\": \"' + msg.topic + '\",\"act\":\"' + waarde + '\"}]';\n\nmsg.payload = {\"value\": uservar};\nmsg.payload.command = \"setuservariable\";\nmsg.payload.idx = 13;\n\nreturn msg\n\n\ndeze variant riep daarna ook json conversie aan"},{"id":"463a5005.9bd78","type":"file","z":"c80f5a41.19d26","name":"BEWAAR FOTO FILE","filename":"","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":1080,"y":120,"wires":[[]]},{"id":"4637144f.1315d4","type":"exec","z":"c80f5a41.19d26","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":1030,"y":360,"wires":[[],[],[]]},{"id":"89e8222f.5e809","type":"function","z":"c80f5a41.19d26","name":"RENAME","func":"msg.payload= msg.camoscmd;\n\nreturn msg","outputs":1,"noerr":0,"x":260,"y":360,"wires":[["ff0fe699.8f2678"]],"info":"if ( msg.payload === true )\n{waarde = \"On\"}\nelse \n{waarde = \"Off\"}\n\nvar uservar = '[{\"obj\": \"' + msg.topic + '\",\"act\":\"' + waarde + '\"}]';\n\nmsg.payload = {\"value\": uservar};\nmsg.payload.command = \"setuservariable\";\nmsg.payload.idx = 13;\n\nreturn msg\n\n\ndeze variant riep daarna ook json conversie aan"},{"id":"6afe5bb1.0f9714","type":"function","z":"c80f5a41.19d26","name":"Nest hub IMAGES","func":"msg = \n{\n  host:msg.ip_nest,\n  payload:  {\n            type: \"MEDIA\",\n            media:  {\n                    url: global.get(\"url_pvk_websvr\") + msg.webnaam,\n                    title: \"CAMERA\", // optional unless desired\n                    }\n            }\n};\n\nreturn[msg]","outputs":1,"noerr":0,"x":830,"y":240,"wires":[["f075aba.53b8758"]]},{"id":"b5b6fa52.c54518","type":"inject","z":"c80f5a41.19d26","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":120,"wires":[["e10660a6.816c6"]]},{"id":"e10660a6.816c6","type":"function","z":"c80f5a41.19d26","name":"params","func":"msg.service = \"Camera straat\";\nmsg.ip_nest = \"192.168.20.37\";\nmsg.webnaam = \"\"\n\nreturn[msg]","outputs":1,"noerr":0,"x":280,"y":120,"wires":[["b398a23d.84c758"]],"info":"if ( msg.payload === true )\n{waarde = \"On\"}\nelse \n{waarde = \"Off\"}\n\nvar uservar = '[{\"obj\": \"' + msg.topic + '\",\"act\":\"' + waarde + '\"}]';\n\nmsg.payload = {\"value\": uservar};\nmsg.payload.command = \"setuservariable\";\nmsg.payload.idx = 13;\n\nreturn msg\n\n\ndeze variant riep daarna ook json conversie aan"},{"id":"4bebd44e.939b2c","type":"function","z":"c80f5a41.19d26","name":"init fileexist","func":"msg.xfilename = msg.nwnaam1\nmsg.xfilestore = global.get(\"filestore\");\nmsg.xrepetitions = 5;           // bij 0 directe test ?\n\nreturn[msg]","outputs":1,"noerr":0,"x":270,"y":240,"wires":[["4805323e.31b234"]],"info":"if ( msg.payload === true )\n{waarde = \"On\"}\nelse \n{waarde = \"Off\"}\n\nvar uservar = '[{\"obj\": \"' + msg.topic + '\",\"act\":\"' + waarde + '\"}]';\n\nmsg.payload = {\"value\": uservar};\nmsg.payload.command = \"setuservariable\";\nmsg.payload.idx = 13;\n\nreturn msg\n\n\ndeze variant riep daarna ook json conversie aan"},{"id":"8918d04d.c483f8","type":"comment","z":"c80f5a41.19d26","name":"kills msg content","info":"","x":1080,"y":80,"wires":[]},{"id":"f22930bb.71bcb8","type":"comment","z":"c80f5a41.19d26","name":"kills msg content","info":"","x":1080,"y":200,"wires":[]},{"id":"4805323e.31b234","type":"subflow:d10da8c0.5a5958","z":"c80f5a41.19d26","name":"FILE_EXISTS","env":[],"x":460,"y":240,"wires":[["bd30715a.e2f988"]]},{"id":"bd30715a.e2f988","type":"switch","z":"c80f5a41.19d26","name":"fileexist","property":"fileexist","propertyType":"msg","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":640,"y":240,"wires":[["6afe5bb1.0f9714"],[]]},{"id":"55b6f318.f5fba4","type":"join","z":"c80f5a41.19d26","name":"","mode":"custom","build":"object","property":"","propertyType":"full","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":630,"y":360,"wires":[["5f7bf025.f3456"]]},{"id":"ff0fe699.8f2678","type":"function","z":"c80f5a41.19d26","name":"topic ","func":"msg.topic = \"flow_os\";\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":360,"wires":[["55b6f318.f5fba4"]]},{"id":"e4d9f1b7.0b9dc","type":"function","z":"c80f5a41.19d26","name":"topic","func":"msg.topic = \"flow_hub\";\n\nreturn msg;","outputs":1,"noerr":0,"x":1250,"y":240,"wires":[["55b6f318.f5fba4"]]},{"id":"5f7bf025.f3456","type":"function","z":"c80f5a41.19d26","name":"init os command","func":"msg.payload = msg.camoscmd;\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":360,"wires":[["4637144f.1315d4"]]}]type or paste code here

mmm, i think @zenofmud that your config has more potential.

I see that you config the parts manually!, cooool
I had to set the parts ID to 1 on both parts because the node EDIT castv2-sender node kills the ID ( make a new msg)

Dont understand why these nodes kill the old message and dont pasthrough the old msg and id's

But, the flow is working, see the result!

You might want to open an issue in github about this. According to the documentation (https://nodered.org/docs/creating-nodes/)

Nodes should document what properties they add to messages, and they should be consistent and predictable in their behaviour.
(I hi-lighted the 'add')

I will!

Advantage for me is that i have to config these workarounds and learn a lot!
I like node-red more and more, ubelievable what you can do with it.
I have the console you see above in three houses distributed and i can manage them remote and distribute calls for services(cams, devices, restart servers, servers) and execute them local and remote... works great

I hope you are doing that very securely....

i do my best....
My english is not great, i hope the node author understands it...

node-castv2 isnt maintained... I have to look for another cast node...