PageRenderTime 52ms CodeModel.GetById 16ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/smartapps/smartthings/mdns-discovery-example.groovy

https://github.com/rappleg/SmartThings
Groovy | 169 lines | 138 code | 23 blank | 8 comment | 32 complexity | 3fbd243318da4061767b172f604b72e4 MD5 | raw file
  1/**
  2 *  mDNS Discovery Example
  3 *
  4 *  Author: smartthings
  5 *  Date: 2014-04-02
  6 */
  7preferences {
  8	section("Title") {
  9		page(name:"firstPage", title:"mDNS Device Setup", content:"firstPage")
 10	}
 11}
 12
 13def installed() {
 14	log.debug "Installed with settings: ${settings}"
 15
 16	initialize()
 17}
 18
 19def updated() {
 20	log.debug "Updated with settings: ${settings}"
 21
 22	unsubscribe()
 23	initialize()
 24}
 25
 26def initialize() {
 27	// TODO: subscribe to attributes, devices, locations, etc.
 28}
 29
 30def discover() {
 31	sendHubCommand(new physicalgraph.device.HubAction("lan discover mdns/dns-sd ._smartthings._tcp._site", physicalgraph.device.Protocol.LAN))
 32}
 33
 34def firstPage()
 35{
 36		int refreshCount = !state.refreshCount ? 0 : state.refreshCount as int
 37		state.refreshCount = refreshCount + 1
 38		def refreshInterval = 5
 39
 40		//log.debug "REFRESH COUNT :: ${refreshCount}"
 41
 42		if(!state.subscribe) {
 43			subscribe(location, null, locationHandler, [filterEvents:false])
 44			state.subscribe = true
 45		}
 46
 47		if((refreshCount % 3) == 0) {
 48			discover()
 49		}
 50
 51		def devicesDiscovered = devicesDiscovered()
 52
 53		return dynamicPage(name:"firstPage", title:"Discovery Started!", nextPage:"", refreshInterval: refreshInterval, install:true, uninstall: true) {
 54			section("Please wait while we discover your device. Select your device below once discovered.") {
 55				input "selectedDevices", "enum", required:false, title:"Select Devices \n(${devicesDiscovered.size() ?: 0} found)", multiple:true, options:devicesDiscovered
 56			}
 57		}
 58}
 59
 60def devicesDiscovered() {
 61	def devices = getDevices()
 62	def map = [:]
 63	devices.each {
 64		def value = it.value.name ?: "mDNS Device: ${it.value.mac}"
 65		def key = it.value.ip + ":" + it.value.port
 66		map["${key}"] = value
 67	}
 68	map
 69}
 70
 71def getDevices()
 72{
 73	if (!state.devices) { state.devices = [:] }
 74	state.devices
 75}
 76
 77def locationHandler(evt) {
 78	def description = evt.description
 79	def hub = evt?.hubId
 80
 81	def parsedEvent = parseEventMessage(description)
 82	parsedEvent << ["hub":hub]
 83
 84	if (parsedEvent?.mdnsPath)
 85	{
 86		def devices = getDevices()
 87
 88		if (!(devices."${parsedEvent?.mac?.toString()}"))
 89		{ //device does not exist
 90			devices << ["${parsedEvent.mac.toString()}":parsedEvent]
 91		}
 92		else
 93		{ // update the values
 94
 95			log.debug "Device was already found in state..."
 96			def d = device."${parsedEvent.mac.toString()}"
 97			boolean deviceChangedValues = false
 98
 99			if(d.ip != parsedEvent.ip || d.port != parsedEvent.port) {
100				d.ip = parsedEvent.ip
101				d.port = parsedEvent.port
102				deviceChangedValues = true
103				log.debug "mdns device's port or ip changed..."
104			}
105
106			if (deviceChangedValues) {
107				def children = getChildDevices()
108				children.each {
109					if (it.getDeviceDataByName("mac") == parsedEvent.mac) {
110						log.debug "updating dni for device ${it} with mac ${parsedEvent.mac}"
111						it.setDeviceNetworkId((parsedEvent.ip + ":" + parsedEvent.port))
112					}
113				}
114			}
115		}
116	}
117}
118
119private def parseEventMessage(String description) {
120	def event = [:]
121	def parts = description.split(',')
122	parts.each { part ->
123		part = part.trim()
124		if (part.startsWith('devicetype:')) {
125			def valueString = part.split(":")[1].trim()
126			event.devicetype = valueString
127		}
128		else if (part.startsWith('mac:')) {
129			def valueString = part.split(":")[1].trim()
130			if (valueString) {
131				event.mac = valueString
132			}
133		}
134		else if (part.startsWith('networkAddress:')) {
135			def valueString = part.split(":")[1].trim()
136			if (valueString) {
137				event.ip = valueString
138			}
139		}
140		else if (part.startsWith('deviceAddress:')) {
141			def valueString = part.split(":")[1].trim()
142			if (valueString) {
143				event.port = valueString
144			}
145		}
146		else if (part.startsWith('mdnsPath:')) {
147			def valueString = part.split(":")[1].trim()
148			if (valueString) {
149				event.mdnsPath = valueString
150			}
151		}
152		else if (part.startsWith('headers')) {
153			part -= "headers:"
154			def valueString = part.trim()
155			if (valueString) {
156				event.headers = valueString
157			}
158		}
159		else if (part.startsWith('body')) {
160			part -= "body:"
161			def valueString = part.trim()
162			if (valueString) {
163				event.body = valueString
164			}
165		}
166	}
167
168	event
169}