Convert hostname to IP Address

I"m trying to figure out how to convert a hostname to an ipaddress in ST.

The groovy code would be:

InetAddress.getByName(hostname).address.collect { it & 0xFF }.join('.')

however with ST platform one cannot access the static object InetAddress. Anyone have any ideas?

Quick possibility … this site has info on how to get a JSON response from their server; looks promising to me, but I haven’t worked much with SmartThings’s http calls yet. – Oops, this particular reference does the reverse of what you are looking for, I think. But I’ll be the opposite exists, of course, an “nslookup” of some sort. I’ll add a new Reply… … ( Convert hostname to IP Address )

http://ipinfo.io/developers

…CP / Terry.

How about this one? There probably is a frequency limit, but maybe it does the trick for a reasonable number of accesses? Basically it is a REST-API to the dig command, right?

http://api.myiponline.net/dig?url=cosmicpuppy.com

[[{"host":"cosmicpuppy.com","type":"A","ip":"192.145.239.20","class":"IN","ttl":14400}],[{"host":"cosmicpuppy.com","type":"NS","target":"ns.inmotionhosting.com","class":"IN","ttl":86400},{"host":"cosmicpuppy.com","type":"NS","target":"ns2.inmotionhosting.com","class":"IN","ttl":86400}],[{"host":"cosmicpuppy.com","type":"MX","pri":0,"target":"cosmicpuppy.com","class":"IN","ttl":14400}]]

Main page: http://www.myiponline.net/myapi

…CP / Terry.

interesting but I don’t think these will work with ST, they will have async reponses with ST where as I’m trying to see if there is a synchronous option, the apps will convert the hostname into IP rather than deferring the action.

Forgive me; not sure I understand the difference in this context, but my experience is weak.

Aren’t many SmartApps doing REST-API calls to servers that have similar, umm, “async responses”; for example weather lookup, NEST status lookup, ?

That’s correct the REST response are async which mean the response will be sent back by the server at a point, the smart app will “parse” it and manage it. Where I’m trying to see if this can be done real time because the app can’t defer the action.

@duncan, @tslagle13, @minollo - I guess it’s a limitation of the ST platform not being able to access static classes (unless I’m wrong), is there anything else available you may be aware of?

1 Like

Ah… OK.

Can it be near real-time? i.e., busy-wait or block for a “short” time to wait for the reply? Even a synchronous call is not instantaneous, right?

right but with sync - ie. the code waits until there’s a response. In this case the smartapp can’t defer the action and needs to wait until the “answer” is provided - hence the REST is not an option

BTW: I’m wondering if this is this for local hostname resolution (hosts on the LAN, local hosts table, or local DNS), external, or both?

Hmmm… I still don’t understand that’s there’s not an “easy” way to workaround this, but that’s my own ignorance in play here.

Not urgent, but I’d love to learn more about this sort of thing; so if you can share an actual code example in context or some other reference, I’d love to learn more. No rush – hope you find what you need in the meantime!

Cheers,
…Terry.

When calling hubAction from a device code one needs to use IPAddress and ports. this is what I understood from here:

so if the user enters a (public) hostname instead of an ipaddress when initializing the device, how does one convert it to an IPAddress. @urman looping you into the conversation incase you’ve any insight into this and why InetAddress doesn’t work with ST.

@tgauchat interestingly to use REST in a device code you’ll need the IPAddress for the website (in this case api.myiponline.com) to use hubAction to get the REST response unless I’m missing something.

@tgauchat I think I see what you’re getting at, according to the specs using httpGet we can get the code to “pause” for upto 20 seconds to get a response from the server without having to defer it. Thanks.

Thanks for pointing me in the right direction, for those interested this worked:

private String convertHostnameToIPAddress(hostname) {
	def params = [
      uri: "http://api.myiponline.net/dig?url=" + hostname
    ]

	def retVal = null
    
	try { // thanks @CosmicPuppy
    	retVal = httpGet(params) { response ->
			log.debug "Request was successful, data=$response.data, status=$response.status"
            for(result in response.data) {
	            for(subresult in result) {
                    if (subresult.type == "A") {
                        log.debug("Hostname $subresult.host has IP Address $subresult.ip")
                        return subresult.ip
                    }
                }
            }
        }
    }
    catch (Exception e) {
    	log.debug("Unable to convert hostname to IP Address, Error: $e")
    }
    
    return retVal
}
2 Likes

Looks great!

Please credit GitHub @CosmicPuppy IF you wish.

Thanks!

1 Like

Looks like api.myiponline.net is down

I found another site which can be used

See [RELEASE] Amcrest IPM-721 & IP2M-841 LIVE Video/PTZ/Night Vision/Motion/Video Record/+More IP Camera DTH

1 Like

Here’s an updated one folks can use:

private String convertHostnameToIPAddress(hostname) {
    def params = [
        uri: "http://dns.google.com/resolve?name=" + hostname,
        contentType: 'application/json'
    ]

    def retVal = null

    try {
        retVal = httpGet(params) { response ->
            log.trace "Request was successful, data=$response.data, status=$response.status"
            //log.trace "Result Status : ${response.data?.Status}"
            if (response.data?.Status == 0) { // Success
                for (answer in response.data?.Answer) { // Loop through results looking for the first IP address returned otherwise it's redirects
                    //log.trace "Processing response: ${answer}"
                    if (isIPAddress(answer?.data)) {
                        log.trace "Hostname ${answer?.name} has IP Address ${answer?.data}"
                        return answer?.data // We're done here (if there are more ignore it, we'll use the first IP address returned)
                    } else {
                        log.trace "Hostname ${answer?.name} redirected to ${answer?.data}"
                    }
                }
            } else {
                log.warn "DNS unable to resolve hostname ${response.data?.Question[0]?.name}, Error: ${response.data?.Comment}"
            }
        }
    } catch (Exception e) {
        log.warn("Unable to convert hostname to IP Address, Error: $e")
    }

    //log.trace "Returning IP $retVal for Hostname $hostname"
    return retVal
}
2 Likes

*edit.

Found the problem.

@RBoy

There seems to be a typo in the above code.

if (isIPAddress(answer?.data)) {

Should be
if (isIpAddress(answer?.data)) {

–lowercase p.

1 Like

@gausnes

Luke, did ST make a change to the platform httpGet API?

def params = [
        uri: "http://dns.google.com/resolve?name=" + hostname,
        contentType: 'application/json'
    ]
httpGet(params)

This code no longer works when trying to resolve a hostname to IP address. ST now returns:

Error: groovyx.net.http.ResponseParseException: Forbidden

It’s almost like ST is blocking google dns