Merge pull request #1414 from SmartThingsCommunity/master

Rolling up master to staging for next week deploy
This commit is contained in:
Vinay Rao
2016-11-01 14:27:41 -07:00
committed by GitHub
13 changed files with 214 additions and 194 deletions

View File

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

View File

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

View File

@@ -188,29 +188,20 @@ private Map getBatteryResult(rawValue) {
log.debug rawValue log.debug rawValue
def result = [ def result = [:]
name: 'battery',
value: '--'
]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {} if (!(rawValue == 0 || rawValue == 255)) {
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)
} def roundedPct = Math.round(pct * 100)
else if (volts > 0){ if (roundedPct <= 0)
def minVolts = 2.1 roundedPct = 1
def maxVolts = 3.0 result.name = 'battery'
def pct = (volts - minVolts) / (maxVolts - minVolts) result.value = Math.min(100, roundedPct)
def roundedPct = Math.round(pct * 100) result.descriptionText = "${linkText} battery was ${result.value}%"
if (roundedPct <= 0)
roundedPct = 1
result.value = Math.min(100, roundedPct)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
} }
return result return result

View File

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

View File

@@ -187,35 +187,31 @@ def getTemperature(value) {
} }
} }
private Map getBatteryResult(rawValue) { private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug 'Battery'
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [:]
name: 'battery'
]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText
if (rawValue == 0 || rawValue == 255) {} if (!(rawValue == 0 || rawValue == 255)) {
else if (volts > 3.5) { def minVolts = 2.1
result.descriptionText = "${linkText} battery has too much power (${volts} volts)." def maxVolts = 3.0
} def pct = (volts - minVolts) / (maxVolts - minVolts)
else { def roundedPct = Math.round(pct * 100)
def minVolts = 2.1 if (roundedPct <= 0)
def maxVolts = 3.0 roundedPct = 1
def pct = (volts - minVolts) / (maxVolts - minVolts) result.name = 'battery'
def roundedPct = Math.round(pct * 100) result.value = Math.min(100, roundedPct)
if (roundedPct <= 0) result.descriptionText = "${linkText} battery was ${result.value}%"
roundedPct = 1
result.value = Math.min(100, roundedPct)
result.descriptionText = "${linkText} battery was ${result.value}%"
}
return result
} }
private Map getTemperatureResult(value) { return result
}
private Map getTemperatureResult(value) {
log.debug 'TEMP' log.debug 'TEMP'
def linkText = getLinkText(device) def linkText = getLinkText(device)
if (tempOffset) { if (tempOffset) {

View File

@@ -196,25 +196,19 @@ private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug 'Battery'
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [:]
name: 'battery'
]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText if (!(rawValue == 0 || rawValue == 255)) {
if (rawValue == 0 || rawValue == 255) {}
else if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {
def minVolts = 2.1 def minVolts = 2.1
def maxVolts = 3.0 def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts) def pct = (volts - minVolts) / (maxVolts - minVolts)
def roundedPct = Math.round(pct * 100) def roundedPct = Math.round(pct * 100)
if (roundedPct <= 0) if (roundedPct <= 0)
roundedPct = 1 roundedPct = 1
result.value = Math.min(100, roundedPct) result.value = Math.min(100, roundedPct)
result.descriptionText = "${linkText} battery was ${result.value}%" result.descriptionText = "${linkText} battery was ${result.value}%"
result.name = 'battery'
} }
return result return result

View File

@@ -207,25 +207,20 @@ private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug 'Battery'
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [:]
name: 'battery'
]
def volts = rawValue / 10 def volts = rawValue / 10
def descriptionText if (!(rawValue == 0 || rawValue == 255)) {
if (rawValue == 0 || rawValue == 255) {}
else if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {
def minVolts = 2.1 def minVolts = 2.1
def maxVolts = 3.0 def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts) def pct = (volts - minVolts) / (maxVolts - minVolts)
def roundedPct = Math.round(pct * 100) def roundedPct = Math.round(pct * 100)
if (roundedPct <= 0) if (roundedPct <= 0)
roundedPct = 1 roundedPct = 1
result.value = Math.min(100, roundedPct) result.value = Math.min(100, roundedPct)
result.descriptionText = "${linkText} battery was ${result.value}%" result.descriptionText = "${linkText} battery was ${result.value}%"
result.name = 'battery'
} }
return result return result

View File

@@ -181,22 +181,17 @@ private Map getBatteryResult(rawValue) {
log.debug 'Battery' log.debug 'Battery'
def linkText = getLinkText(device) def linkText = getLinkText(device)
def result = [ def result = [:]
name: 'battery'
]
def volts = rawValue / 10 if (!(rawValue == 0 || rawValue == 255)) {
def descriptionText def volts = rawValue / 10
if (volts > 3.5) {
result.descriptionText = "${linkText} battery has too much power (${volts} volts)."
}
else {
def minVolts = 2.1 def minVolts = 2.1
def maxVolts = 3.0 def maxVolts = 3.0
def pct = (volts - minVolts) / (maxVolts - minVolts) def pct = (volts - minVolts) / (maxVolts - minVolts)
def roundedPct = Math.round(pct * 100) def roundedPct = Math.round(pct * 100)
result.value = Math.min(100, roundedPct) result.value = Math.min(100, roundedPct)
result.descriptionText = "${linkText} battery was ${result.value}%" result.descriptionText = "${linkText} battery was ${result.value}%"
result.name = 'battery'
} }
return result return result

View File

@@ -0,0 +1,2 @@
.st-ignore
README.md

View File

@@ -0,0 +1,41 @@
# GE Plug-In/In-Wall Smart Dimmer (ZigBee)
Works with:
* [GE In-Wall Smart Dimmer (ZigBee)](https://shop.smartthings.com/#!/products/ge-in-wall-smart-dimmer-switch)
* [GE Plug-In Smart Dimmer (ZigBee)](https://www.smartthings.com/works-with-smartthings/ge/ge-plug-in-smart-dimmer-zigbee)
## Table of contents
* [Capabilities](#capabilities)
* [Health](#device-health)
* [Troubleshooting](#Troubleshooting)
## Capabilities
* **Actuator** - represents that a Device has commands
* **Configuration** - _configure()_ command called when device is installed or device preferences updated
* **Refresh** - _refresh()_ command for status updates
* **Power Meter** - ability to check the power meter(energy consumption) of device
* **Sensor** - represents the device sensor capability
* **Switch** - can detect state (possible values: on/off)
* **Switch Level** - represents current light level, usually 0-100 in percent
* **Health Check** - indicates ability to get device health notifications
## Device Health
A Zigbee dimmer with maxReportTime of 5 mins.
Check-in interval is double the value of maxReportTime.
This gives the device twice the amount of time to respond before it is marked as offline.
Enrolls with default periodic reporting until newer 5 min interval is confirmed
It then enrolls the device with updated checkInterval i.e. 12 mins
## Troubleshooting
If the device doesn't pair when trying from the SmartThings mobile app, it is possible that the device is out of range.
Pairing needs to be tried again by placing the device closer to the hub.
Instructions related to pairing, resetting and removing the device from SmartThings can be found in the following link:
* [GE Z-Wave In-Wall Smart Dimmer (GE 45857) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/204988564-GE-In-Wall-Smart-Dimmer-45857GE-ZigBee-)
* [GE Zigbee Plug-in Smart Dimmer (GE 45852) Troubleshooting Tips](https://support.smartthings.com/hc/en-us/articles/205239280-GE-Plug-In-Smart-Dimmer-45852GE-ZigBee-)

View File

@@ -21,6 +21,7 @@ metadata {
capability "Sensor" capability "Sensor"
capability "Switch" capability "Switch"
capability "Switch Level" capability "Switch Level"
capability "Health Check"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702"
@@ -70,8 +71,20 @@ def parse(String description) {
} }
} }
else { else {
log.warn "DID NOT PARSE MESSAGE for description : $description" def cluster = zigbee.parse(description)
log.debug zigbee.parseDescriptionAsMap(description) if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
if (cluster.data[0] == 0x00){
log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}
else {
log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
}
}
else {
log.warn "DID NOT PARSE MESSAGE for description : $description"
log.debug zigbee.parseDescriptionAsMap(description)
}
} }
} }
@@ -87,11 +100,22 @@ def setLevel(value) {
zigbee.setLevel(value) zigbee.setLevel(value)
} }
/**
* PING is used by Device-Watch in attempt to reach the Device
* */
def ping() {
return zigbee.onOffRefresh()
}
def refresh() { def refresh() {
zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig() + zigbee.levelConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig() zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig()
} }
def configure() { def configure() {
log.debug "Configuring Reporting and Bindings." log.debug "Configuring Reporting and Bindings."
// Device-Watch allows 3 check-in misses from device (plus 1 min lag time)
// enrolls with default periodic reporting until newer 5 min interval is confirmed
sendEvent(name: "checkInterval", value: 3 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
refresh() refresh()
} }

View File

@@ -20,6 +20,7 @@ metadata {
capability "Power Meter" capability "Power Meter"
capability "Sensor" capability "Sensor"
capability "Switch" capability "Switch"
capability "Health Check"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0B04" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0B04"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0702"
@@ -77,10 +78,26 @@ def on() {
} }
def refresh() { def refresh() {
zigbee.onOffRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig() Integer reportIntervalMinutes = 5
zigbee.onOffRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig(0,reportIntervalMinutes * 60) + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig()
} }
def configure() { def configure() {
log.debug "Configuring Reporting and Bindings." log.debug "in configure()"
refresh() configureHealthCheck()
}
def configureHealthCheck() {
Integer hcIntervalMinutes = 12
refresh()
sendEvent(name: "checkInterval", value: hcIntervalMinutes * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}
def updated() {
log.debug "in updated()"
configureHealthCheck()
}
def ping() {
return zigbee.onOffRefresh()
} }

View File

@@ -21,6 +21,7 @@ metadata {
fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006" fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch" fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "0003, 0006, 0019, 0406", manufacturer: "Leviton", model: "ZSS-10", deviceJoinName: "Leviton Switch"
fingerprint profileId: "0104", inClusters: "0000, 0003, 0006", outClusters: "000A", manufacturer: "HAI", model: "65A21-1", deviceJoinName: "Leviton Wireless Load Control Module-30amp"
} }
// simulator metadata // simulator metadata