[Release] Google DNS Updater

This driver allows you to use your Hubitat hub as a Dynamic Dns updater for Google Domains dns records. It uses their API found here.

I doubt this will be useful to many, but if you use Google Domains to host your web domain, there are a few side benefits including free dynamic dns subdomains. For those who use a VPN server to connect into their home networks and don't want to sign up for the one in their routers (Netgear/Asus, etc) this is an awesome side feature of Google Domains. I previously used my Raspberry Pi with ddclient to perform this update but figured it would be easier to see and control the updates with another always connected device...my HE hub.

Please Note: For the super security conscious, this driver stores your username and password in plain text on your hub. Not an issue for me, but might be for some.

The driver acts as a simple momentary switch that can be pushed to start the follwing:

  • Get existing external IP
  • If different from what is currently stored in the driver, it will send an Dynamic Dns Update to google domains service.
  • Ip checks can be scheduled (Every 1,5,10,30 minutes or Every 1,3 Hours)

A manual ip update can be sent as well. Simply enter the ip under Manual Update and hit the button. Manual Ip update can be sent from other apps as well if needed.

Driver Code:

Hubitat/drivers/Google DNS Updater/Google DNS Updater.groovy at master · stephack/Hubitat · GitHub

5 Likes

Love your code. It is a very nice replacement for the same bash script I had running on my NAS.

I'd like to suggest a couple of changes though:

  1. Since I was already using GoogleDNS for my sites name resolution, the address was already set up and continually threw errors. I'd suggest setting the internal IP when gDNS has the same as what we are trying to set.
  2. Capturing the last time there was a successful update to gDNS.

Here's the snippets of code I'm offering. (no pride... mangle as you see fit)

(suggested changes are prefixed with a ">")

        attribute "ip", "string"
>       attribute "lastUpdate", "string"

...

def updateGoogle(myIp){
    if(logEnable) log.debug "Post URL: https://${username}:${password}@domains.google.com/nic/update?hostname=${hostname}&myip=${myIp}"
    def params = [
        uri: "https://${username}:${password}@domains.google.com/nic/update?hostname=${hostname}&myip=${myIp}",
        contentType: "text/html",
        requestContentType: "text/html",
    ]
>   def now = new Date().format('MM/dd/yyyy h:mm a',location.timeZone)
    try{
        httpPost(params){response ->
            if(logEnable) log.debug "Response Status: " + response.status
            if(logEnable) log.debug "Response Data: " + response.data

            def responseCode = "${response.data}"
            if(response.status != 200) log.error "Invalid URL or Unable to contact domains.google.com - Enable Debug logging for details!"
            else if(responseCode.contains("good")){
                log.info "Ip successfully updated to: " + myIp
                sendEvent(name: "ip", value: myIp)
>               sendEvent(name: "lastUpdate", value: now, descriptionText: "Last Update: $now")
            }
>           else if(responseCode.contains("nochg")){
>               log.warn "The supplied IP address is already set for this host. You should not attempt another update until your IP address changes."
>               sendEvent(name: "ip", value: myIp)
>               sendEvent(name: "lastUpdate", value: now, descriptionText: "Last Update: $now")
>           }

Awesome work... Thank you for posting.

Thanks for the feedback. What were the errors you were receiving? You should have received the nochg warning the first time the the driver attempted to update to Google DNS but not after that. Here's what the driver should do.

  • Get the external ip using https://domains.google.com/checkip
  • check the ip attribute of the driver
  • if the external ip is the same as the attribute...do nothing
  • if different send the IP update request to google using their API
  • if the attempted ip change is the same as in Google DNS, the API will return a "nochg" warning that should be captured.
  • the next time the driver starts the process, the attribute should now be set and prevent sending unneeded update requests.

Please post your errors with debug logging turned on so I can see what I missed.

After re-reading what I posted, I see where it could cause an issue on first time setup.

I will update the "ip" attribute everytime the getIp() extracts the external IP instead of after the google DNS update. I will also add the timestamps as you suggested. Thanks again for your suggestions.

v1.1.20190127 updated in Github with the following changelog.

  • added LastUpdate and LastCheck state variable to keep track of ip updates/checks
  • fixed initial ip attribute setting that generated errors
  • thanks to @pdhruska for finding above deficiencies

I use state variables for timestamps because they won't fill your device event log unnecessarily (especially if you schedule the driver to check frequently).

The error I was receiving was:

[warn] The supplied IP address is already set for this host. You should not attempt another update until your IP address changes.

You are correct that it was a result of the initial IP being stored as an attribute bing null, and my already having my IP address stored with gDNS.

Thanks for your response and changes.

@stephack Thanks for releasing this. I was able to use your code as a basis for creating my own Duck DNS Updater, which seems to be doing the trick for me :slight_smile: I especially like having a dashboard button that can force an IP update.

Would you consider expanding your version into something that could work with Duck DNS and other Dynamic DNS services?

I suppose I could if the services have fairly simple and documented API's. I dont imagine there are many people using multiple DNS services, so the additional "features" would only make the driver unnecessarily complex and bloated. I think user needs would be better served by using a driver built just for that service. Just my opinion.

Btw, you can feel free to share your Duckdns driver with the community even if it's using a lot of my code. I would appreciate a mention in the header but it's free to use and adapt by the community as needed.

2 Likes

Alright, cool. I'll just release mine as a standalone version :slight_smile:

Thanks again!

2 Likes

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