Restart NodeRED After PAC Control Download

Is there anyway to restart Node-RED (or, more accurately, restart Node-RED flows) every time I do a download from PAC Control?

Before I think too much more about this… you just gotta know I’m going to ask… why?

Unfortunately, the answer is probably some bad programming in some custom nodes I’ve written. I’ve written a few nodes that are called periodically that rely on some specifically named variables in my control strategy. I’ve noticed that sometimes when I do a download, these nodes will essentially hang. Restarting Node-RED fixes the problem. I’m also working to include better error handling in the nodes themselves, but being able to restart the flows (which is really what I want, not restarting the entire runtime) would be a quick fix.

Ah, Ok, that makes sense now.
Thanks for the clear explanation. (I would be putting a catch node in and recording any errors - to a local file perhaps - to see whats going on).

I think the best way to do this is to put in the powerup chart in PAC Control an API call to the Node-RED admin.
https://nodered.org/docs/api/admin/
You will most likely need this call here:
https://nodered.org/docs/api/admin/methods/post/flows/

I don’t have time to spin up some sample code (got new groov family hardware on my desk to test), but you will need to dig into the httpget command with the key etc.

@Beno: thanks for pointing me in the right direction. I should be able to manage that.

1 Like

So I’m trying to go down the route mentioned by @Beno and send an HTTP request to the Node-RED Admin API on my Groov EPIC PR-1. For now, I’ve created a simple PAC strategy that only has one block and I’m attempting to GET “/auth/login” as described here.

Here’s my OptoScript code:

HttpGet(st_ResponseContents,
        st_ResponseHeaders,
        st_GetHeaders,
        1,
        "/node-red/auth/login",
        i_HTTP,
        443,
        "127.0.0.1");

Every time I run the code, I get an HTTP status of 500 no matter what I do. I’m sure I’m forgetting something stupid, but I can’t for the life of me figure out what it is. All three string tables remain empty after the GET request.

I’ve tried various paths:

  • /node-red/auth/login
  • /auth/login

I’ve tried both localhost and 127.0.0.1 for the hostname and nothing has made a difference so far.

Edit: Looks like my HttpGet function call is returning -2008, which I’m assuming is an SSL certificate error. I still don’t know how to fix it, but it’s an extra piece of information.

Edit 2: I added the self-signed certificate in Groov Manage, and that resolved one error. Now I’m getting a 401 error saying that I have to login before I can access that page. Any tips on how to login would be great.

Edit 3: Figured out that I had to add an apiKey header to my GET request.

If anybody else is interested, here’s what seems to be working for me. I created a subroutine called RestartNodeRED. It accepts one parameter, the API key of a user with appropriate permissions. Here’s the code of the subroutine:

// Prepare request.
st_SourceContents[0] = "[]";

// Create headers.
st_SourceHeaders[0] = "Host: localhost";
st_SourceHeaders[1] = "Content-Type: application/json";
st_SourceHeaders[2] = "apiKey: " + s_Key;
st_SourceHeaders[3] = "Node-RED-Deployment-Type: reload";
HttpPostCalcContentLength(st_SourceContents, st_SourceHeaders, 4);

// Clear response fields.
MoveToStrTableElements("", 0, -1, st_ResponseContents);
MoveToStrTableElements("", 0, -1, st_ResponseHeaders);

// Submit request.
i_Status = HttpPostFromStringTable(st_ResponseContents,
                                   st_ResponseHeaders,
                                   st_SourceContents,
                                   st_SourceHeaders,
                                   1,
                                   "/node-red/flows",
                                   i_HTTP,
                                   443,
                                   "localhost");

// Return true if POST successful and appropriate status code returned.
if (i_Status == 0 and i_HTTP == 204) then
  SetVariableTrue(b_Result);
else
  SetVariableFalse(b_Result);
endif
2 Likes

Fantastic!
Thanks for following up and for sharing the code.
Really appreciate that!

hi @varland
Could you please tell me how to create the subroutine “subroutine called RestartNodeRED” I’m new to node red. If you could leave me some screenshots that would be great.

Hello Marcelo, welcome to the forums.

If you are not comfortable making a PAC Control subroutine, perhaps just copy/paste the code example above this post into a chart and just run it as a chart until you happy with how it works, then you can move it to a subroutine if you like.

Remember, its a very unusual use case to want to programmatically restart Node-RED.
If you only need to restart it now and then, you can always do that from the groov Manage interface.

If you want to learn more about subroutines, you will find them on page 365 of the PAC Control users guide.

@marce0pasu: I’m not sure what I can add to the code I posted above. Before you go down that road, I would strongly encourage you to follow @Beno’s advice. I’ll say it a little more bluntly: if you need this code to restart Node-RED, you’re probably doing something wrong. In my case, I had programmed some custom nodes and I didn’t do much error handling. Rather than fix the root of the problem, I was brute forcing a restart. I was able to make Node-RED restart using this code, but I’m no longer using the code and had forgotten all about it.

2 Likes