multi: Fix x,y,z parsing error

The previous axis value parsing code was very fragile. For example, this
code block:

    def unsignedY = hexToInt(part.split("13")[1].trim())

would fail when `part` was "13xx13", where "xx" is any value. The split
assumed the value "13" was present only once in the string, and everything
after the "13" was the value. When "13" was part of the value this code
would interpret only "xx" as the value, instead of "xx13".

The new parsing code is not fragile like this. It knows exactly what bytes
of the string are X, Y, and Z and parses the values correctly.
This commit is contained in:
Tom Manley
2016-01-04 15:21:55 -06:00
parent 41e95b9248
commit e98a04a1b4

View File

@@ -478,50 +478,34 @@ def enrollResponse() {
] ]
} }
private Map parseAxis(String description) { private Map parseAxis(String description) {
log.debug "parseAxis" def hexToSignedInt = { hexVal ->
def xyzResults = [x: 0, y: 0, z: 0] def unsignedVal = hexToInt(hexVal)
def parts = description.split("2900") unsignedVal > 32767 ? unsignedVal - 65536 : unsignedVal
parts[0] = "12" + parts[0] }
parts.each { part ->
part = part.trim() def z = hexToSignedInt(description[0..3])
if (part.startsWith("12")) { def y = hexToSignedInt(description[10..13])
def unsignedX = hexToInt(part.split("12")[1].trim()) def x = hexToSignedInt(description[20..23])
def signedX = unsignedX > 32767 ? unsignedX - 65536 : unsignedX def xyzResults = [x: x, y: y, z: z]
xyzResults.x = signedX
log.debug "X Part: ${signedX}" if (device.getDataValue("manufacturer") == "SmartThings") {
} // This mapping matches the current behavior of the Device Handler for the Centralite sensors
// Y and the Z axes are interchanged between SmartThings's implementation and Centralite's implementation xyzResults.x = z
else if (part.startsWith("13")) { xyzResults.y = y
def unsignedY = hexToInt(part.split("13")[1].trim()) xyzResults.z = -x
def signedY = unsignedY > 32767 ? unsignedY - 65536 : unsignedY } else {
if (device.getDataValue("manufacturer") == "SmartThings") { // The axises reported by the Device Handler differ from the axises reported by the sensor
xyzResults.z = -signedY // This may change in the future
log.debug "Z Part: ${xyzResults.z}" xyzResults.x = z
if (garageSensor == "Yes") xyzResults.y = x
garageEvent(xyzResults.z) xyzResults.z = y
} }
else {
xyzResults.y = signedY log.debug "parseAxis -- ${xyzResults}"
log.debug "Y Part: ${signedY}"
} if (garageSensor == "Yes")
} garageEvent(xyzResults.z)
else if (part.startsWith("14")) {
def unsignedZ = hexToInt(part.split("14")[1].trim())
def signedZ = unsignedZ > 32767 ? unsignedZ - 65536 : unsignedZ
if (device.getDataValue("manufacturer") == "SmartThings") {
xyzResults.y = signedZ
log.debug "Y Part: ${signedZ}"
} else {
xyzResults.z = signedZ
log.debug "Z Part: ${signedZ}"
if (garageSensor == "Yes")
garageEvent(signedZ)
}
}
}
getXyzResult(xyzResults, description) getXyzResult(xyzResults, description)
} }