mDNS based discovery for LAN devices

Using the SmartThings mDNS library to discover LAN devices

Here is a function I use in my edge driver discovery handlers to discovery LAN devices using mDNS.

1. Finding Devices

This code snippet uses mDNS to find LAN devices, with a name containing “Shelly” , which publicise a service called “http”.

local numberOfDiscoveredDevices, discoveredDevices = discoverDevices( "Shelly", "http")	

E.g. In my network mDNS discovered 10 devices publicising the “http” service.

  1. ShellyPlus1-441793A9C238
  2. everything-presence-st-d53394
  3. Sky Q Mini1478
  4. everything-presence-one-e016bc
  5. E415F65056F5@mysimplelink
  6. espNeostatHubBridge
  7. ShellyPlus1-441793A90660
  8. Sky Q 2TB Box2919
  9. Sky Q Mini9573
  10. Samsung M288x Series (SEC842519107403)

Of which two (1 & 7) matched my name criteria. So details of these two devices were returned.
Tip. watch out for devices with a “-” in their name. The minus sign needs an escape character e.g. everything%-presence in the deviceName.

The returned information can then be used to create two Smartthings devices.

2. discoverDevices function

local mdns = requires('st.mdns')
local function discoverDevices( deviceName, service)
    local serviceType = "_"  .. service .. "._tcp"
    local domain 	  = "local"
    local discoveredDevices = {}
    local i = 0

    local discoveryResponses = mdns.discover(serviceType, domain) or {} 
    log.info('*** mDNS discovered ' .. #discoveryResponses.found .. " devices")
    
    for idx, answer in ipairs(discoveryResponses.found) do
	if string.find(answer.service_info.name, deviceName) then
	    log.info('*** Discovered a ' .. deviceName .. ' device: ', idx, answer.service_info.name, answer.host_info.address, answer.host_info.port)
	    i = i+1
	    discoveredDevices[i] = {
		name 		= answer.service_info.name,
		ipAddress 	= answer.host_info.address,
		port 		= answer.host_info.port
	    }
	end
    end
    return i, discoveredDevices 
end