Use table for battery voltage to percent remaining calculation

The new table based approach yields a more accurate battery percentage
remaining than the old linear calculation.

Resolves:
    https://smartthings.atlassian.net/browse/SMJN-39
This commit is contained in:
Tom Manley
2016-01-18 13:29:48 -06:00
parent e51a38eb28
commit 968834e33e
4 changed files with 112 additions and 50 deletions

View File

@@ -88,31 +88,37 @@ private handleReportAttributeMessage(String description) {
} }
} }
private handleBatteryEvent(rawValue) { /**
def linkText = getLinkText(device) * Create battery event from reported battery voltage.
*
def eventMap = [ * @param volts Battery voltage in .1V increments
name: 'battery', */
value: '--' private handleBatteryEvent(volts) {
] if (volts == 0 || volts == 255) {
log.debug "Ignoring invalid value for voltage (${volts/10}V)"
def volts = rawValue / 10 }
if (volts > 0){ else {
def minVolts = 2.0 def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
def maxVolts = 2.8 22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
def minVolts = 15
def maxVolts = 28
if (volts < minVolts) if (volts < minVolts)
volts = minVolts volts = minVolts
else if (volts > maxVolts) else if (volts > maxVolts)
volts = maxVolts volts = maxVolts
def pct = (volts - minVolts) / (maxVolts - minVolts) def pct = batteryMap[volts]
if (pct != null) {
eventMap.value = Math.round(pct * 100) def linkText = getLinkText(device)
eventMap.descriptionText = "${linkText} battery was ${eventMap.value}%" def eventMap = [
name: 'battery',
value: pct,
descriptionText: "${linkText} battery was ${pct}%"
]
log.debug "Creating battery event for voltage=${volts/10}V: ${eventMap}"
sendEvent(eventMap)
}
} }
log.debug "Creating battery event: ${eventMap}"
sendEvent(eventMap)
} }
private handlePresenceEvent(present) { private handlePresenceEvent(present) {

View File

@@ -215,24 +215,47 @@ def getTemperature(value) {
} }
private Map getBatteryResult(rawValue) { private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug "Battery rawValue = ${rawValue}"
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [
name: 'battery' name: 'battery',
value: '--'
] ]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText
if (volts > 3.5) { if (rawValue == 0 || rawValue == 255) {}
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else { else {
def minVolts = 2.1 if (volts > 3.5) {
def maxVolts = 3.0 result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
def pct = (volts - minVolts) / (maxVolts - minVolts) }
result.value = Math.min(100, (int) pct * 100) else {
result.descriptionText = "${linkText} battery was ${result.value}%" if (device.getDataValue("manufacturer") == "SmartThings") {
volts = rawValue // For the batteryMap to work the key needs to be an int
def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
def minVolts = 15
def maxVolts = 28
if (volts < minVolts)
volts = minVolts
else if (volts > maxVolts)
volts = maxVolts
def pct = batteryMap[volts]
if (pct != null) {
result.value = pct
result.descriptionText = "${linkText} battery was ${result.value}%"
}
}
else {
def minVolts = 2.1
def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts)
result.value = Math.min(100, (int) pct * 100)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
}
} }
return result return result

View File

@@ -230,30 +230,46 @@ def getTemperature(value) {
} }
private Map getBatteryResult(rawValue) { private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug "Battery rawValue = ${rawValue}"
def linkText = getLinkText(device) def linkText = getLinkText(device)
log.debug rawValue
def result = [ def result = [
name: 'battery', name: 'battery',
value: '--' value: '--'
] ]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText
if (rawValue == 0) {} if (rawValue == 0 || rawValue == 255) {}
else { else {
if (volts > 3.5) { if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)." result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
} }
else if (volts > 0){ else {
def minVolts = 2.1 if (device.getDataValue("manufacturer") == "SmartThings") {
def maxVolts = 3.0 volts = rawValue // For the batteryMap to work the key needs to be an int
def pct = (volts - minVolts) / (maxVolts - minVolts) def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
result.value = Math.min(100, (int) pct * 100) 22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
result.descriptionText = "${linkText} battery was ${result.value}%" def minVolts = 15
def maxVolts = 28
if (volts < minVolts)
volts = minVolts
else if (volts > maxVolts)
volts = maxVolts
def pct = batteryMap[volts]
if (pct != null) {
result.value = pct
result.descriptionText = "${linkText} battery was ${result.value}%"
}
}
else {
def minVolts = 2.1
def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts)
result.value = Math.min(100, (int) pct * 100)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
} }
} }

View File

@@ -303,8 +303,7 @@ def getTemperature(value) {
} }
private Map getBatteryResult(rawValue) { private Map getBatteryResult(rawValue) {
log.debug "Battery" log.debug "Battery rawValue = ${rawValue}"
log.debug rawValue
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [
@@ -313,19 +312,37 @@ private Map getBatteryResult(rawValue) {
] ]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText
if (rawValue == 255) {} if (rawValue == 0 || rawValue == 255) {}
else { else {
if (volts > 3.5) { if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)." result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
} }
else { else {
def minVolts = 2.1 if (device.getDataValue("manufacturer") == "SmartThings") {
def maxVolts = 3.0 volts = rawValue // For the batteryMap to work the key needs to be an int
def pct = (volts - minVolts) / (maxVolts - minVolts) def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
result.value = Math.min(100, (int) pct * 100) 22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
result.descriptionText = "${linkText} battery was ${result.value}%" def minVolts = 15
def maxVolts = 28
if (volts < minVolts)
volts = minVolts
else if (volts > maxVolts)
volts = maxVolts
def pct = batteryMap[volts]
if (pct != null) {
result.value = pct
result.descriptionText = "${linkText} battery was ${result.value}%"
}
}
else {
def minVolts = 2.1
def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts)
result.value = Math.min(100, (int) pct * 100)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
} }
} }