DHCP and Grafana iframe

Hello all, I'm new in this forum.

Usually I'm able to find a solution searching the web, but this time I haven't been able, and despite all my trials I have to give off.

I open grafana in a new tab (in all the tab layout there is just a ui_template) with a iframe conteining a grafana panel. The problem is that the URL is something like 192.168.1.xx:3000....; when the Red-Node server reboots, the DHCP gives it a new address so grafana is at 192.168.1.YY:3000.. and the iframe doesn't work.

I tried to use localhost:3000.., but a computer that connects from a remote location thinks that localhost is its own machine, and again it doesn't work.

I already managed to have the running IP on a global var named status - status.get("internalIP") but still I don't understand how to use it in the iframe.

What did the others? Everybody use a static IP? Please give me a hint.

Thank in advance

You will either have to use fixed IP (either in the server or via the DHCP server) or use the local domain name. For example, on Linux systems the computer may be accessible as its_host_name.local. I don't know about Windows systems but I assume something similar is available.

When you say a remote location, do you mean out on the internet, or just another computer on the local network?

Thank for your reply.

It's weird:
My box runs Ubunu 20.04
http://host_name.local works
http://host_name.local:1880/admin no
http://host_ip:1880/admin works

Anyway it would be a workaround as I have in a global var the actual IP, so, instead putting http://host_name.local:3000 -which would be os-guest dependant, in the iframe in the ui_template I would use that global. Of course the better solution would be a way to say "same machine".

It isn't the same machine. The iframe runs in the browser not the server.

Right, That's the problem: when I wrote 'localhost' my Ubuntu machine searched for the grafana instance while it was in Raspberry. With "same machine" I meant that node-red should understand that grafana is is on the "same machine" and substiute the IP by itself.

There is no way in the general case for node-red to know the correct ip or port. On a local network the local IP will generally work, but if it is accessible from other networks then it might be necessary to use a specific domain name. So for example to access my grafana charts running on the same machine as node-red I use charts.mydomain.org.uk. There is no way that node-red can automatically know that.

I did that: it is possible. It is not a native function, you have to install a new node.
I tried a couple.
Now I'm using node-red-contrib-get-my-ipl
In a init node I do

if (msg.payload.hasOwnProperty("internalIPv4") ){
    status.internalIP = msg.payload.internalIPv4;

That is providing your local network ip, but as I explained that is not a solution which would work for everyone. It would not work for me as to see my grafana charts I have to use https://charts.mydomain.org.uk. There is absolutely no way that node-red can automatically know that.

Oh, now I got the misunderstood: yes you are right; in my case node-red_server_ip equals to grafana_server_ip (reason for localhost), but it is not a universal case.

The question was simply, given the address of the grafana_server (same machine of nodered_server or another one), and known that localhost doesn't work, how do I write the iframe in the ui_template?

It is worth noting here that localhost is absolutely NOT the same as the device's IP address. You need to understand a little about how networking works.

Localhost is genuinely local - that's to say that the transmission data never needs to hit the external port of your network card. If you were to use the device's IP address, then the traffic does have to go via the external interface of the network card and this is, in general, not a good idea.

However, in your case, you are trying to access two different services that just happen to live on the same device - at the moment - but maybe not in the future.

So having something that automatically "knows" that 2 different services run on the same server is a non-trivial exercise in logic. As Colin say's, what would work for you wouldn't necessarily work for someone else.

The easiest thing to do is to keep configuration variables somewhere, one for each service and then always use those. For example, you could create environment variables within settings.js since you can use those in place of node settings in most cases.

The other thing you could do would be to configure your Pi to have a fixed IP address (either through local config or via DHCP on your router) and simply use that address everywhere (though you would then have to go round finding and changing addresses if you needed to move one of the services so not ideal). You could go further and use a local DNS to create sub-domain names for each service - again, that gives you one place to change things so is good for the future.

No, that isn't the issue. Node red and grafana are both on the same machine. The issue is that the local network IP only works if the browser is on the local network, which is not necessarily the case.

I thought you had solved it. You have to use the IP address or host name that will get you to the grafana server from the machine running the browser. So that is the same URL that you would use if you were opening up grafana directly on the machine running the browser.

I know, I understand (and already known) what everybody say, mine is simple question: I have a global var with the local IP (given from the DHCP and valid only in the local LAN): How can I write the iframe with that IP? It is just syntax/node question.

I'm already doing that: when the flow starts I get the IP and store it in a variable that can be accessed by all the nodes.

If you also (externally to Node-RED) create an environment variable that has the complete url then you can use them for node properties - as per Using environment variables : Node-RED - or if using node-red-node-ui-iframe you can inject it as msg.url

Pass it to the iframe in msg.url as described in the node's help text.

Just one post might be the solutions. I marked Colin's one but I wibh to thank dceejay, too.

I claimed it "solved" too early: I had to do many more trails, but at the end I made it working with the node the both of you two suggested.
Here is a copy of that part of my flow:

[{"id":"f317856b.d37db","type":"function","z":"f497d8f9.dba4d","name":"","func":"var url=\"http://\";\n\nvar status = typeof(global.get(\"status\")) == 'undefined' ? {} : global.get(\"status\");\nvar IP = \"localhost\";\n\nif (status.hasOwnProperty(\"internalIP\") ){\n IP = global.get(\"status.internalIP\");\n}\n\nurl += IP;\nurl += \":3000/d/tgv4G1zRz/dummy?orgId=1&from=now-15m&to=now&viewPanel=2\";\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":375,"y":285,"wires":[["a8ff4f28.b6838"]]}]

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