How Change node properties with a function block

I want change URL of WebSocket node with a function block.

my URL on WebSocket was variable, and necessary to change, it is possible?

image

You cannot dynamically change the the url of a websocket endpoint, it is only examined at Node-RED startup.

There really aren't many cases where you would actually want this anyway so you might want to explain why you are wanting to do this, perhaps we can think of alternative approaches.

ok.

i'm monting a equipament that have a HMI and a raspberry, the HMI make de connection with the raspberry via modbus, and read/write variables the system, and raspberry make the connection with the plataform. but the URL must be change, because if i provide my solution for other people, these people must to put on other url of your platoform.
i provided variables on the HMI for change the URL, and the raspberry read this information and change de url on websocket, but before change the url, the raspberry open the web socket, generating error, because the url is not define.

If I've read this right, you want to allow people to change the url before they start the Node-RED based system. Not dynamically. That's because they just need to be able to ensure that the url doesn't clash on their system.

Actually, even that isn't an issue unless you are giving them a FLOW to use in their own instance of Node-RED since they must choose an unused PORT for Node-RED so they would never have clashing URL's in any case.

If you are giving them a flow to use and they may have created their own URL's in their instance of Node-RED, what you need to do is allow a global configuration to be set in their settings.js. To do that, you will need a custom node I think. However, someone got there already since node-red-contrib-uibuilder allows the user to configure a URL and creates a websocket connection on a matching path. While this is generally designed to be used with front-end code and my uibuilderfe.js library, it wouldn't be hard to adjust for other uses.

1 Like

I solved this problem.

the firt thing i did, was on my dashboard, i create one variable with url on JSON file.

then on node of websocket i call this file, selecting the variable of url.

Hey @TotallyInformation,

I am new node-red user (loving it so far) and I want to use it to build a simple PoC for a device service for the EdgeX project by the linux foundation.

My issue is that I need the endpoints of the device service to include a device_id like {.../device/{device_id}/command/:command. Thisdevice_id is provisioned to the device at the bootstraping phase, so I can't hardcode it.

My first solution is to use ${env_var} by provisioning the device, setting the var and the restarting the node-red instance. I can't say that I like this approach. Do you think that there is a better alternative?
(I have searched everywhere for a solution, results are very sparse).

Thank you so much for your time and effort. I really appreciate it.

Best,
Odysseas

It is generally better to start a new thread for a new question, you will normally get better responses.

In this case, why not make the device id a variable like the command?

Also, if the device ID's are available before Node-RED starts up, you can set them into global variables in settings.js.

Hey @TotallyInformation,

Thank you so much for your time.

So I could use a id_variable and check the id_variable in a function node, because in case the ID is wrong, it should return an error. This would be the way to go?

Moreover, should I wanted to use env_var it would be /device/${device_id}/.... and the env would be set in the settings.js, am I right?

Thanks again for the thorough response.

Cheers!

Let's just back-track a second. When you say the above, exactly what are you trying to do here? Is this in Node-RED (e.g. you are using the http-in node) or on your devices (e.g. you are using the http-request node)?

One point about using env variables inside node settings - generally I believe that the env variable has to be the whole setting entry and not just part of it.

Hey,

What I want is to set the http in endpoint dynamically, after the start of the node-red services (and thus the flows).

In detail, the service during bootstraping will request an id from a central registry, and that id will be used in the endpoint url.

Thanks!

OK, so what is stopping using the following URL definition:

.../device/:device_id/command/:command

Now you have 2 variables to work with in Node-RED and your devices can use any device ID.

You will likely want to add some logic to restrict what ID's are valid. For that, since you know what they are before Node-RED starts up, I would create a JSON file (containing an array of ID's) or even a simple text file with one ID per line. You can then use that in Node-RED, read it on startup (either a flow on the first tab or add some logic to your settings.js file) into a global variable. Then you can use that to only allow valid ID's through.

Or have I misunderstood something?

1 Like

beat me to it :slight_smile:

You can access the variables in msg.req.params.id and msg.req.params.command

sample flow. (triggered by browsing http://localhost:1880/device/1/command/start ..

[{"id":"99225691.2177d8","type":"http in","z":"56fa9896.d15ed8","name":"","url":"/device/:id/command/:command","method":"get","upload":false,"swaggerDoc":"","x":260,"y":140,"wires":[["4d5394ac.ec39bc"]]},{"id":"938c0707.72d728","type":"debug","z":"56fa9896.d15ed8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":450,"y":200,"wires":[]},{"id":"4d5394ac.ec39bc","type":"change","z":"56fa9896.d15ed8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"\"{id:\" & req.params.id  & \",command:\\\"\" & req.params.command & \"\\\"}\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":200,"wires":[["938c0707.72d728","495784ba.799c6c"]]},{"id":"495784ba.799c6c","type":"http response","z":"56fa9896.d15ed8","name":"","statusCode":"","headers":{},"x":310,"y":260,"wires":[]}]
2 Likes

makes a change :wink:

3 Likes

Wow guys @Steve-Mcl, @TotallyInformation

I don't know what to say. I have been interacting with various communities these days as I am making a PoC for my Master's thesis, but this has been by far the quickest and most helpful reply. I am really humbled for your time.

I will follow your advice and use a function node to filter out the right ID. In essence, during a bootstraping flow, the device receives an ID which is then used as a global.variable in the API endpoints flow.

Thank you guys!

Btw, it's possible to use a http request node to upload a file using POST, right?

Cheers!

https://flows.nodered.org/?term=upload&type=flow&num_pages=1

Yes it is... No need to use any contrib nodes from the library. The sidebar help gives you the basic message structure needed at the bottom