How to monitor a dynamic WAN IP address

Update 2017-05-01: Added JavaScript transformation to test for valid IP.

Most Internet Service Providers (ISP) provide you with a dynamic WAN IP address. This address may change over time. If you rely on this address, for example for accessing a computer inside your home network, you might want to monitor changes to the address. Websites like icanhazip and WhatIsMyIP return your public IP address as plain text.

This solution grabs that address and stores it in an item. A rule monitors changes to the item and acts on it.

This solution requires that you have the HTTP Binding installed.

Note: Please be nice to the websites you ping. Don’t increase the interval above once per minute.

valid_ip.js

// return valid IP or '-'
(function(ip) {

  // remove blanks first
  ip = ip.replace(/\s/g, '');

  // http://stackoverflow.com/a/26445549
  var rx=/^(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/;
  if (rx.test(ip)) {
    return (ip);
  }
  else {
    return "-";
  }
})(input)
// input variable contains data passed by openhab

demo.items

// check for WAN IP address changes every 10 mins
String Network_WAN_IP "WAN IP address [%s]" <network> (Network) { http="<[http://icanhazip.com:600000:JS(valid_ip.js)]" }

demo.rules

rule "Monitor WAN IP"
when
    Item Network_WAN_IP changes
then
    // perform any action needed
    val currentState = Network_WAN_IP.state
    if (currentState == "-") {
        logError("MonitorWANIP", "Unable to get WAN IP")
    } else {
        logInfo("MonitorWANIP", "WAN IP changed to: " + currentState)
    }
end

demo.sitemap

sitemap demo label="Demo" {
	Frame {
		Text item=Network_WAN_IP
	}
}

I have already added this solution to a wiki page:

5 Likes

I use http://www.duckdns.org/ to get a consistent name I can address. Other dynamic dns services are available.

1 Like

Nice work thanks for that.

Cheers,
George

Great idea! I have a cron job that emails me if the ip changes, but I might do this too.

Dynamic DNS services are very handy and many routers have included support to send updates to them.
I am using no-ip.com, which is fine but asks for reactivation once a month. Other solutions are available. Random comparison article:

https://smartdns.com/blog/60/5-best-free-ddns-providers

Hello,

Background:
I have openhab on 1 computer in one VLAN , ex 192.168.1.x with a normal WAN IP.
However, I would like to check if the WAN IP changes on another VLAN ex 192.168.2.x.
Reason, this WAN IP is always on an VPN.
I can access the second VLAN from my openhab.

Would it be possible somehow to make openhab ask VLAN ‘2’ for its WAN IP adress just for this instance?
I would like top check if it goes down and reveals my “real WAN IP”.

You can do this by setting a host route in your openHAB system. I.e. if you’re using the solution from above, you just have to add this route (Linux in this case):

ip route add 45.76.25.15/32 via 192.168.2.254

where 45.76.25.15 is the IP of icanhazip.com and 192.168.2.254 is your router in VLAN 2.

Christian

Obviously I’m a dumbnut, but could not get it to work via adding the routes normally.
Fortunately, there was a another routing setting in my router so I could set the destination IP to go via VPN instead which worked as expected.
Thank you for the help!

I’ve been using ddclient for the past 10 years I think. Also going with no-ip as provider. Ddclient has very good support for most dns services.

https://sourceforge.net/p/ddclient/wiki/Home/

Thanks for the tipp.
I am using icanhazip.com successfully, but have one issue:
Sometimes it does not work and the entire html response wll flood my log file.

So I would like to check whether the returned String is shorter than 17 digits.
Any suggestion how I could do this within OH (without an external script)?
Thanks in advance.

I have OH 1.8.3 and using canhazip.com for more then year, but for last few days log file is fool of warnings like this:

2017-04-30 20:02:08.272 [WARN ] [.a.c.httpclient.HttpMethodBase] - Cookie rejected: "$Version=0; __cfduid=d8174938ef26dc52c7c3ad5abff6998311493571727; $Path=/; $Domain=.icanhazip.com". Illegal domain attribute ".icanhazip.com". Domain of origin: "icanhazip.com"

How this can be fixed?

That’s exactly the problem I encountered, but I hoped it was just a temporary issue.
Obviously it’s not… :frowning:
Fritzbox wanip (with Fritzbox TR064 binding) is not working either…

I changed service to this : https://api.ipify.org

It seams to fix the cookie errors :slight_smile:

1 Like

The original example used the default REGEX transformation to just return the output of the web request. I have modified the example to use a JavaScript transformation that tests for a valid IP address. Please see above.

Cookie messages are gone, but as far as I have noticed the icanhazip service kept working as expected.

Thanks.
That did the Trick. :slight_smile:

There must ba a } at the end and then it works

1 Like

You are right. Corrected. :blush:

One question:
When starting in openhab.log I get the error message:

2017-09-09 15:59:59.444 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘wanip.rules’ has errors, therefore ignoring it: [3,5]: no viable alternative at input ‘changes’

2017-09-09 16:00:05.296 [ERROR] [ab.binding.http.internal.HttpBinding] - Transformation ‘JS(valid_ip.js)’ threw an exception. [response=xx.xx.xx.xx
]
org.openhab.core.transform.TransformationException: An error occurred while loading script.
at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:62)[189:org.openhab.core.compat1x:2.1.0]
at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:189)[188:org.openhab.binding.http:1.10.0]
at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:157)[189:org.openhab.core.compat1x:2.1.0]
at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:169)[189:org.openhab.core.compat1x:2.1.0]

Do you know something about it?

My *.rules file:

rule "Monitor WAN IP"
when
Item Network_WAN_IP changes
then
// perform any action needed
val currentState = Network_WAN_IP.state
if (currentState == “-”) {
logError(“MonitorWANIP”, “Unable to get WAN IP”)
} else {
logInfo(“MonitorWANIP”, "WAN IP changed to: " + currentState)
}
end

Just to start with. I assume you are using OH2 and have installed the JavaScript transformation service?

http://docs.openhab.org/addons/transformations/javascript/readme.html

Hello Robert, thanks for your fast reply. Yes, I am using OH2. As written in the link I created the getValue.js file in /etc/openhab2/transform folder:

-rw-rw-r-- 1 openhab openhabian 98 Sep 10 17:27 getValue.js

but still get the message:

2017-09-10 17:42:19.171 [ERROR] [ab.binding.http.internal.HttpBinding] - Transformation ‘JS(valid_ip.js)’ threw an exception. [response=91.240.65.131
]
org.openhab.core.transform.TransformationException: An error occurred while loading script.
at org.openhab.core.transform.TransformationHelper$TransformationServiceDelegate.transform(TransformationHelper.java:62)[189:org.openhab.core.compat1x:2.1.0]
at org.openhab.binding.http.internal.HttpBinding.execute(HttpBinding.java:189)[188:org.openhab.binding.http:1.10.0]
at org.openhab.core.binding.AbstractActiveBinding$BindingActiveService.execute(AbstractActiveBinding.java:157)[189:org.openhab.core.compat1x:2.1.0]
at org.openhab.core.service.AbstractActiveService$RefreshThread.run(AbstractActiveService.java:169)[189:org.openhab.core.compat1x:2.1.0]

every ten minutes.

My valid_ip.js

// return valid IP or '-'
(function(ip) {
  // remove blanks first
  ip = ip.replace(/\s/g, '');
  // http://stackoverflow.com/a/26445549
  var rx=/^(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/;
  if (rx.test(ip)) {
    return (ip);
  }
  else {
    return "-";
  }
}](input)
// input variable contains data passed by openhab