I did a quick search and didn’t see anything directly related, so I thought I’d ask here. What’s the “best” way to trigger a specific Node-RED flow from PAC Control?
I know that I can do time-based polling, but that’s not a great fit for my application. I’m wondering if my best option is to use PAC Control to write/touch a file and then have my Node-RED flow set up to run when it detects a change to the file.
Are you looking for sub 1 second response? If so I wonder what the rest of the flow looks like…
But if you can take 1 second, just poll with an inject node the PAC Control read node thats looking at an int32 and then follow that with a switch node that passes it onto the flow when the values is the ‘go-trigger’ value.
The one var in PAC Control could in this way fire off different flows pretty smoothly.
@Beno: no, I don’t need sub 1 second response, so your solution is probably the simplest. Guess I was just wondering if there was a solution different than polling.
You are going to have some sort of poll regardless.
You can poll a var or you can poll the file read, but you are going to have to poll something.
I mean, if you really don’t want to poll and are ready to really look at a nice learning curve, there is always the Node-RED API.
One final question: is there some reason I wouldn’t want to use an HTTP In node since it’s pretty simple to perform a simple GET request from within PAC Control?
Philip beat me to it… UDP would be better than TCP, you have to really manage those socket connections from PAC. The TTL (Time To Live) can bite you when you least expect it. Also opening and closing the HTTP stuff has a fair bit of overhead compared to UDP.
@philip: I’m not too familiar with using UDP in this way. When you say send off a packet, is this more than sending a character to a UDP communication handle:
I would need to look up the docs / experiment to determine if you would want to open and close the handle on the UDP connection - they are technically connectionless. I would probably open it and never close it.
On UDP, the connection isn’t closed on errors - so you can leave it open. From PAC Control help:
Many applications never close a communication handle once they are opened. If a communication fault were to occur on an unbound communication handle, the handle continues to remain open and may still be used to resume communications. If the communication handle was bound, it too remains open and datagrams will be received once the network problem is corrected.
Use TransmitString instead of TransmitChar or call TransmitNewLine after using TransmitChar. TransmitChar only adds the character to the buffer.
@philip & @Beno: Thank you for the help. I got this UDP method set up, and I like it because I can send a string “command” to a Node-RED flow and branch off in a variety of different directions based on the command sent. That saves me from having to poll a number of different PAC variables.
I created this OptoScript box, but did not insert it into the flow diagram. I my case, all I am trying to do is listen for the Integer32 variable called Start_Feeder_Command (which has a 1 or 0) via UDP 55555. You can also see that the test compile revealed several errors. Do I have to insert this OptoScript block into my flow (just after the green diamond that says “Is Start_Feeder_Command equal to 1?”)? Any ideas how to resolve the syntax errors below?
Your firewall rule looks pretty much like mine. I only selected eth0 and tun0, but that’s the only difference.
I don’t think you’re missing anything in the Communication Handle definition. Mine is defined the same way (inside a subroutine even).
I’m guessing the issue here is that you’re comparing an int32 variable to an empty string. Try converting your int32 to a string first and use the string. Also, I’m using TransmitString, not TransmitChar. Also make sure there were no weird copy/paste issues with curly quotes.
I see the same message about the port already being in use, so that doesn’t concern me. I did set the output to “a String”.
Hopefully this helps. Let me know if anything else comes up and I’m happy to help.
I don’t think you need firewall rules when communicating on localhost.
The SetCommunicationHandleValue only needs done one time, or you can just put the string in the Initial Value on the variable definition.
Use TransmitString like varland said - TransmitChar only adds the character to the outgoing buffer, it doesn’t actually send it.
For more reference, when I use this code in my application, I’m sending a string like status;1222;319.35986;471.12216;8.03261 via TransmitString. On the Node-RED side, I split the string on semicolons, branch based on the “command” (value before the first semicolon), and then handle the rest of the data as needed. That allows me to use a single port and a single UDP listener for a variety of functions within Node-RED. Some of those flows send data to other systems, while others end up pushing data back into variables via the PAC Write nodes.
I feel this setup accomplished what I wanted originally, which was to come up with a way to trigger a Node-RED flow from PAC Control without relying on periodic polling from Node-RED. I actually have the OptoScript code that @grant1 pasted in a subroutine named StartNodeREDFlow (creative, I know). s_Command is passed in as a string literal and ch_NodeRED is defined within the subroutine. I use it in about 10 different places in my strategy and have been really happy with it since deploying it two years ago.
Just to be clear, does my OptoScript block need to be connected with arrows in my flow? Or can it just sit off to the side as it presently is. If it’s in my flow, then I’ll put it just after Start_Feeder_Command changes.
My revised block is:
if (not Start_Feeder_Command == “”) then SetCommunicationHandleValue(“udp:localhost:55555”, ch_NodeRED); OpenOutgoingCommunication(ch_NodeRED); TransmitString(Start_Feeder_Command, ch_NodeRED); endif
Doing this means you can eliminate the SetCommunicationHandleValue command from your OptoScript code. Your code will be marginally more efficient, and you get the benefit that if you reuse that communication handle in other places, you have one central definition. Mine is initialized in the code because it’s inside a subroutine and subroutine instance variables aren’t persistent, but there’s no reason not to do it like @philip said.
Once you connect your block with arrows in PAC Control, you should be able to add a debug node after your UDP listen node in Node-RED and see the messages coming across.