Odd behaviour for LAN connected devices


(Nick Baker) #1

Hi

I have created a DTH I am using and seeing some odd behaviour. Just wondering if anybody has seen similar and can offer any tips.

My device is an Wemos D1 mini with two temp sensors and two contact sensors attached. One sensor and one contact in my freezer and one sensor and one contact in the fridge. The Wemos has two HTTP servers running, one on port 80 and the other on 81.

My DTH is the same for both fridge and freezer with a runIn function polling the values from the Wemos and updating contact and temperatureMeasurement capabilities. The DNIs are set correctly in ip:port (hex encoded) formats for both devices - the same IP in both but the fridge on port 81 and freezer on port 80.

In the mobile app if I look at the tiles of either device they report correctly and if I look at the events in the IDE under the device all looks good… but if I go to the Recent tab in he mobile app under Freezer I see a whole load of events for Fridge with the fridge temp reported. Also interestingly I use Initial State to graph things and that is seeing no events for freezer at all but the temp for fridge is spiking between -12 and +8 every few minutes.

It’s almost as if the fridge is receiving responses from the other device. But the DNIs are set correctly so ST should be using those to route the appropriate responses to each device.

If I look at the live logging in the IDE I see requests and callbacks there for the correct devices. Every response I see to a freezer poll is a temp < 0 and every request to the fridge is > 0 - so that part is right.

Any ideas?

Nick


(Nick Baker) #2

Some more info, here are some screenshots where you can see what’s going on, plus below is the code for my DTH. I’m pretty stumped now.

Nick

import groovy.json.JsonSlurper

metadata {
	definition (name: "WiFi Fridge Monitor", namespace: "nickb512", author: "nickb512") {
		capability "Refresh"
		capability "Sensor"
    capability "Polling"
    capability "temperatureMeasurement"
    capability "contactSensor"
	}
preferences {
    input "ip", "string", title: "IP Address", required: true
    input "port", "number", title: "Port", required: true
}
	tiles (scale: 2) {
    valueTile("temperature", "device.temperature", width: 6, height: 4) {
        state "temperature", label: '${currentValue}', unit:"dC", 
            backgroundColors:[
                [value: 0, color: "#153591"],
                [value: 7, color: "#1e9cbb"],
                [value: 15, color: "#90d2a7"],
                [value: 23, color: "#44b621"],
                [value: 28, color: "#f1d801"],
                [value: 35, color: "#d04e00"],
                [value: 37, color: "#bc2323"]
            ]
    }
    standardTile("contact", "device.contact", width: 2, height: 2, decoration: "flat") {
        state "closed", label: "", icon: "st.contact.contact.closed"
        state "open", label: "", icon: "st.contact.contact.open"
    }
   	standardTile("main", "device.temperature", decoration: "flat", width: 2, height: 2) {
			state "temperature", label: '${currentValue}°C', icon: "st.alarm.temperature.normal"
    }
    standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state("default", label:'refresh', action:"polling.poll", icon:"st.secondary.refresh-icon")
		}
		main "main"
		details (["temperature", "contact", "refresh"])
}
}

def installed() {
	log.debug "installed()"
	configure()
}

def configure() {
log.debug "configure()"
def iphex = convertIPtoHex(ip)
def porthex = convertPortToHex(port)
device.deviceNetworkId = "$iphex:$porthex"
log.debug "DNI set to $iphex:$porthex"
runEvery1Minute(refresh)
sendEvent(name: "temperature", value: 0)
sendEvent(name: "contact", value: "closed")
}

def updated() {
log.debug "updated()"
configure();
}

def parse(description) {
	log.debug "Parsing: ${description}"
def descMap = parseDescriptionAsMap(description)
def body
//log.debug "descMap: ${descMap}"
	
if (descMap["body"]) body = new String(descMap["body"].decodeBase64())
	
if (body && body != "") {
	if(body.startsWith("{") || body.startsWith("[")) {
		def slurper = new JsonSlurper()
		def result = slurper.parseText(body)
		log.debug "result: ${result}"
        if (result.contact == 1) {
            sendEvent(name: "contact", value: "open")
        } else {
            sendEvent(name: "contact", value: "closed")
        }
        sendEvent(name: "temperature", value: result.temp)
	} else {
    	log.debug "Response is not JSON: $body"
	}
}
}

def parseDescriptionAsMap(description) {
	description.split(",").inject([:]) { map, param ->
		def nameAndValue = param.split(":")
    
    if (nameAndValue.length == 2) map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
    else map += [(nameAndValue[0].trim()):""]
	}
}

def refresh() {
	log.debug "refresh()"
	def hubAction = new physicalgraph.device.HubAction(
	method: "GET",
	path: "/",
	headers: [
    	host: getHostAddress()
	]
  	)
sendHubCommand(hubAction)
  	return hubAction
}

def poll() {
	log.debug "poll()"
	refresh()
}

def ping() {
log.debug "ping()"
refresh()
}

private getHostAddress() {
def ip = getDataValue("ip")
def port = getDataValue("port")
def parts = device.deviceNetworkId.split(":")
log.debug "DNI: ${device.deviceNetworkId}"
if (parts.length == 2) {
    ip = convertHexToIP(parts[0])
    port = convertHexToInt(parts[1])
} else {
    log.warn "Can't figure out ip and port for device: ${device.id}"
}
log.debug "Using IP: $ip and port: $port for device: ${device.id}"
return ip + ":" + port
}

private Integer convertHexToInt(hex) {
return Integer.parseInt(hex,16)
}

private String convertHexToIP(hex) {
return [convertHexToInt(hex[0..1]),convertHexToInt(hex[2..3]),convertHexToInt(hex[4..5]),convertHexToInt(hex[6..7])].join(".")
}

private String convertIPtoHex(ipAddress) {
	try {
    String hex = ipAddress.tokenize( '.' ).collect {  String.format('%02x', it.toInteger() ) }.join()  // thanks to @pstuart
    return hex
} catch (Exception e) {
    log.error "Invalid IP Address $ipAddress, check your settings! Error: $e"
}
}

private String convertPortToHex(port) {
try {
    String hexport = port.toString().format('%04x', port.toInteger() )   // thanks to @pstuart
    return hexport
} catch (Exception e) {
    log.error "Invalid port $port, check your settings! Error: $e"
}
}

(Nick Baker) #3

Ok so while I was sat in a restaurant in London something has happened to ST and it’s sorted its life out. It is now reporting everything correct. I did nothing, it just decided it would work properly now… Gotta love technology eh

Capture

Edit: not sure if its of any note, but this was pretty much exactly 24 hours after I created and setup the device