Need help dynamically setting delay for q-gate messages

I have the below flow (my first after lots of reading and trial/error) that plays a doorbell chime on all of my Google Home devices when a button is clicked.

[{"id":"74892af.da407d4","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"f8b4e343.d2eef","type":"debug","z":"74892af.da407d4","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1070,"y":220,"wires":[]},{"id":"552bdcc2.9d8f04","type":"link in","z":"74892af.da407d4","name":"","links":["a37bf2e8.d719a"],"x":555,"y":480,"wires":[["925ca098.241e4"]]},{"id":"9824886b.df9dd8","type":"server-events","z":"74892af.da407d4","name":"Doorbell Button Press","server":"559fe62.fc5b118","event_type":"hue_event","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":200,"y":340,"wires":[["b0d0224c.50297","ead0fc04.f5856"]]},{"id":"ef49d88.e86a728","type":"link out","z":"74892af.da407d4","name":"","links":["c873cb6.6216e38"],"x":555,"y":260,"wires":[],"icon":"node-red-contrib-huemagic/hue-group.png"},{"id":"b0d0224c.50297","type":"change","z":"74892af.da407d4","name":"Hue alert","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"alert\":2,\"hex\":\"ffca7b\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":260,"wires":[["ef49d88.e86a728"]]},{"id":"f5bf8a97.411538","type":"cast-to-client","z":"74892af.da407d4","name":"Master Bedroom Home","url":"","contentType":"","message":"","language":"en","ip":"192.168.3.222","port":"8009","volume":"","x":1130,"y":280,"wires":[["f8b4e343.d2eef"]]},{"id":"a385f9ce.316138","type":"cast-to-client","z":"74892af.da407d4","name":"Living Room Home","url":"","contentType":"","message":"","language":"en","ip":"192.168.3.225","port":"8009","volume":"","x":1110,"y":340,"wires":[[]]},{"id":"e7f96563.9e80a8","type":"cast-to-client","z":"74892af.da407d4","name":"Second Bedroom Home","url":"","contentType":"","message":"","language":"en","ip":"192.168.3.205","port":"8009","volume":"","x":1130,"y":400,"wires":[[]]},{"id":"30bfb6ea.5550ca","type":"delay","z":"74892af.da407d4","name":"process","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":860,"y":340,"wires":[["7afc03d2.f5202c","f5bf8a97.411538","a385f9ce.316138","e7f96563.9e80a8","f8b4e343.d2eef"]]},{"id":"a37bf2e8.d719a","type":"link out","z":"74892af.da407d4","name":"","links":["552bdcc2.9d8f04"],"x":1195,"y":480,"wires":[]},{"id":"7afc03d2.f5202c","type":"function","z":"74892af.da407d4","name":"get next","func":"node.send({topic: \"control\", payload: \"drop\"})\nmsg.topic = \"control\"\nmsg.payload = \"peek\"\nreturn msg;","outputs":1,"noerr":0,"x":1080,"y":460,"wires":[["a37bf2e8.d719a"]]},{"id":"925ca098.241e4","type":"q-gate","z":"74892af.da407d4","name":"q-gate","controlTopic":"control","defaultState":"queueing","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","peekCmd":"peek","dropCmd":"drop","statusCmd":"status","maxQueueLength":"100","keepNewest":false,"qToggle":false,"persist":false,"x":670,"y":340,"wires":[["30bfb6ea.5550ca"]]},{"id":"ead0fc04.f5856","type":"function","z":"74892af.da407d4","name":"send messages","func":"var msg1 = { payload:\n                    {\n                        \"url\":\"http://192.168.3.204:1880/endpoint/doorbell\",\n                        \"contentType\":\"audio/mp3\",\n                        \"streamType\":\"BUFFERED\",\n                        \"volume\":70\n                    }\n            };\n            \nvar msg2 = { payload:\n                    {\n                        \"volume\":50\n                    }\n};\n\nvar msg3 = { topic: \"control\", payload:\"peek\" };\n\nreturn [[msg1,msg2,msg3]];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":460,"y":340,"wires":[["925ca098.241e4"]]},{"id":"559fe62.fc5b118","type":"server","name":"Home Assistant","addon":true}]

There are two messages that are sent to a q-gate:

  • one that sets the volume to 70% then plays the file from an endpoint

  • one that sets the volume back to a normal setting of 50% once it is done playing (I would be open to first getting the current volume of the device prior to setting it to 70% and then setting it back but that may need its own post)

I would like the first message to be sent immediately but would like to delay the second message until the doorbell chime is done casting. The mp3 file can and will change so the length of time is going to vary.

As you can see, I have just a "dumb" delay in place as a placeholder and this is where I need some suggestions/assistance.

One of the contrib nodes will return the duration of an mp3. I have it in a flow but can’t access it right now due to haven’t a sleeping 9 week old in my arms. Once someone else gets up and stealers]r her, I’ll die it out.

How is the audio file created, if you had the length in the title you could parse that. Maybe use http static to serve audio file. Then you could hard code the file name with a length.

If the audio file is a 'wav' try node-red-contrib-wav. One of the options is ~Get WAV header which will supply you with 'duration'.

Thanks for the replies. It is an mp3. I have another part of the flow that takes a Google Assistant command to change the file at the endpoint.

So how would I be able to pass the first message through without a delay but then delay the second message that sets the volume back? Any design ideas?

not quite the same at all - but this example does queue up commands for an exec node and releases the next when each is complete

I would do something like below. In your endpoint flow when you change the file, update a globalcontext and store the new file play length.

Then the below code you can send to multiple cast devices, add an ip for each. The function will send the initial cast with url, volume ip, port etc. Then after delay will send the old volume.

hope it helps

[{"id":"75926a1.c9d9a94","type":"inject","z":"baae6393.f4a898","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":560,"y":240,"wires":[["9e173148.d76d18"]]},{"id":"9e173148.d76d18","type":"change","z":"baae6393.f4a898","name":"","rules":[{"t":"set","p":"delaylength","pt":"global","to":"10","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":240,"wires":[[]]},{"id":"f2a62557.716e6","type":"comment","z":"baae6393.f4a898","name":"can pre quey device for volume","info":"","x":320,"y":320,"wires":[]},{"id":"cd566ad4.065708","type":"comment","z":"baae6393.f4a898","name":"when ever endpoint chages file this must add new delay to global store","info":"","x":800,"y":200,"wires":[]},{"id":"35bb1f84.0172e8","type":"inject","z":"baae6393.f4a898","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":580,"y":320,"wires":[["dde60d61.b0381"]]},{"id":"dde60d61.b0381","type":"function","z":"baae6393.f4a898","name":"","func":"//optional volume inputs\nlet pVolume = msg.payload.pVolume || 30;\nlet nVolume = msg.payload.nVolume || 50;\n// grab delay length stored by edpoint flow\nlet length = global.get(\"delaylength\") || 10;\nmsg.payload = {};// clean slate\nmsg.payload.url = \"http://192.168.3.204:1880/endpoint/doorbell\";\n// possible to grab audio file lenth from title possible direct link using http static\nmsg.payload.contentType = \"audio/mp3\";\nmsg.payload.streamType = \"BUFFERED\";\nmsg.payload.volume = 50;\n//ip of cast devices\nlet IPS = [\"192.168.0.19\",\"192.168.1.20\"];\n// parse length\nmsg.payload[\"port\"] = 8009;\n// send cast\n    for (let i of IPS){\n        msg.payload.ip = i;\n        node.send(msg)\n        }\n    node.done();\n //set delay to return volume       \n    setTimeout(function(){\n    delete msg.payload.url;\n    delete msg.payload.contentType;\n    delete msg.payload.streamType;\n    msg.payload.volume = pVolume;\n        for (let i of IPS){\n            msg.payload.ip = i;\n            node.send(msg)\n            \n        }\n    node.done();\n}, (length * 1000));\n    \nreturn;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":770,"y":320,"wires":[["7825135a.6c22c4"]]},{"id":"7825135a.6c22c4","type":"debug","z":"baae6393.f4a898","name":"output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":940,"y":320,"wires":[]},{"id":"2cc3d6b5.8807f2","type":"comment","z":"baae6393.f4a898","name":"single cast node goes here no settings","info":"","x":1040,"y":300,"wires":[]}]

I am happy to report that thanks to @zenofmud and @E1cid I have converted my mp3s to wav and am now able to take the duration and set it to a global variable to then be used to send the second message that sets the volume to a lower setting. Next on the agenda is getting the original volume levels and using these instead of a static value.

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