From 290e8e4129ab573bb5c9fe73fcac60367f6d0301 Mon Sep 17 00:00:00 2001 From: Tom Manley Date: Tue, 24 Nov 2015 14:03:29 -0600 Subject: [PATCH] The x,y,z attributes are often sent in a separate Attribute Report from the accelerometer attribute. Sometimes, however, they are all sent in the same Attribute Report. When that happens, only the accelerometer attribute was being handled and the x,y,z attributes were not. Now they are all handled if they arrive in the same message. Resolves: https://smartthings.atlassian.net/browse/DVCSMP-1271 --- .../smartsense-multi-sensor.groovy | 71 +++++++++++-------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy index 8d614c3..a4b670b 100644 --- a/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy +++ b/devicetypes/smartthings/smartsense-multi-sensor.src/smartsense-multi-sensor.groovy @@ -115,31 +115,30 @@ } } - def parse(String description) { - - Map map = [:] - if (description?.startsWith('catchall:')) { - map = parseCatchAllMessage(description) - } - else if (description?.startsWith('read attr -')) { - map = parseReportAttributeMessage(description) - } +def parse(String description) { + Map map = [:] + if (description?.startsWith('catchall:')) { + map = parseCatchAllMessage(description) + } else if (description?.startsWith('temperature: ')) { - map = parseCustomMessage(description) - } - else if (description?.startsWith('zone status')) { - map = parseIasMessage(description) - } + map = parseCustomMessage(description) + } + else if (description?.startsWith('zone status')) { + map = parseIasMessage(description) + } def result = map ? createEvent(map) : null - if (description?.startsWith('enroll request')) { - List cmds = enrollResponse() - log.debug "enroll response: ${cmds}" - result = cmds?.collect { new physicalgraph.device.HubAction(it) } - } - return result - } + if (description?.startsWith('enroll request')) { + List cmds = enrollResponse() + log.debug "enroll response: ${cmds}" + result = cmds?.collect { new physicalgraph.device.HubAction(it) } + } + else if (description?.startsWith('read attr -')) { + result = parseReportAttributeMessage(description).each { createEvent(it) } + } + return result +} private Map parseCatchAllMessage(String description) { Map resultMap = [:] @@ -178,28 +177,40 @@ private boolean shouldProcessMessage(cluster) { return !ignoredMessage } -private Map parseReportAttributeMessage(String description) { +private List parseReportAttributeMessage(String description) { Map descMap = (description - "read attr - ").split(",").inject([:]) { map, param -> def nameAndValue = param.split(":") map += [(nameAndValue[0].trim()):nameAndValue[1].trim()] } - - Map resultMap = [:] + + List result = [] if (descMap.cluster == "0402" && descMap.attrId == "0000") { def value = getTemperature(descMap.value) - resultMap = getTemperatureResult(value) + result << getTemperatureResult(value) } else if (descMap.cluster == "FC02" && descMap.attrId == "0010") { - resultMap = getAccelerationResult(descMap.value) + if (descMap.value.size() == 32) { + // value will look like 00ae29001403e2290013001629001201 + // breaking this apart and swapping byte order where appropriate, this breaks down to: + // X (0x0012) = 0x0016 + // Y (0x0013) = 0x03E2 + // Z (0x0014) = 0x00AE + // note that there is a known bug in that the x,y,z attributes are interpreted in the wrong order + // this will be fixed in a future update + def threeAxisAttributes = descMap.value[0..-9] + result << parseAxis(threeAxisAttributes) + descMap.value = descMap.value[-2..-1] + } + result << getAccelerationResult(descMap.value) } - else if (descMap.cluster == "FC02" && descMap.attrId == "0012") { - resultMap = parseAxis(descMap.value) + else if (descMap.cluster == "FC02" && descMap.attrId == "0012") { + result << parseAxis(descMap.value) } else if (descMap.cluster == "0001" && descMap.attrId == "0020") { - resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16)) + result << getBatteryResult(Integer.parseInt(descMap.value, 16)) } - return resultMap + return result } private Map parseCustomMessage(String description) {