Compare commits

..

1 Commits

Author SHA1 Message Date
Nathan Shaw
798a5dea0a MSA-2097: Simple Hue Bulb Template. 2017-07-15 08:11:10 -07:00
6 changed files with 265 additions and 258 deletions

View File

@@ -27,9 +27,13 @@ Works with:
## Device Health ## Device Health
Aeon Labs MultiSensor 6 is polled by the hub. Aeon Labs MultiSensor 6 is polled by the hub.
Aeon MultiSensor reports in once every hour. As of hubCore version 0.14.38 the hub sends up reports every 15 minutes regardless of whether the state changed.
Device-Watch allows 2 check-in misses from device plus some lag time. So Check-in interval = (2*15 + 2)mins = 32 mins.
Not to mention after going OFFLINE when the device is plugged back in, it might take a considerable amount of time for
the device to appear as ONLINE again. This is because if this listening device does not respond to two poll requests in a row,
it is not polled for 5 minutes by the hub. This can delay up the process of being marked ONLINE by quite some time.
* __122min__ checkInterval * __32min__ checkInterval
## Troubleshooting ## Troubleshooting

View File

@@ -130,13 +130,13 @@ metadata {
} }
def installed(){ def installed(){
// Device-Watch simply pings if no device events received for 122min(checkInterval) // Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID]) sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
} }
def updated() { def updated() {
// Device-Watch simply pings if no device events received for 122min(checkInterval) // Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID]) sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
log.debug "Updated with settings: ${settings}" log.debug "Updated with settings: ${settings}"
log.debug "${device.displayName} is now ${device.latestValue("powerSupply")}" log.debug "${device.displayName} is now ${device.latestValue("powerSupply")}"

View File

@@ -200,4 +200,3 @@ def verifyPercent(percent) {
return false return false
} }
} }

View File

@@ -171,8 +171,8 @@ private Map getBatteryResult(rawValue) {
def pct = batteryMap[volts] def pct = batteryMap[volts]
result.value = pct result.value = pct
} else { } else {
def minVolts = 2.4 def minVolts = 2.1
def maxVolts = 2.7 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)

View File

@@ -274,7 +274,7 @@ private Map getBatteryResult(rawValue) {
result.value = pct result.value = pct
} else { } else {
def minVolts = 2.1 def minVolts = 2.1
def maxVolts = 2.7 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)

View File

@@ -15,9 +15,10 @@ metadata {
definition (name: "Z-Wave Thermostat", namespace: "smartthings", author: "SmartThings") { definition (name: "Z-Wave Thermostat", namespace: "smartthings", author: "SmartThings") {
capability "Actuator" capability "Actuator"
capability "Temperature Measurement" capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Thermostat" capability "Thermostat"
capability "Configuration" capability "Configuration"
capability "Refresh" capability "Polling"
capability "Sensor" capability "Sensor"
capability "Health Check" capability "Health Check"
@@ -116,7 +117,7 @@ metadata {
state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff" state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff"
} }
standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") { standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
state "default", action:"refresh.refresh", icon:"st.secondary.refresh" state "default", action:"polling.poll", icon:"st.secondary.refresh"
} }
main "temperature" main "temperature"
details(["temperature", "mode", "fanMode", "heatSliderControl", "heatingSetpoint", "coolSliderControl", "coolingSetpoint", "refresh"]) details(["temperature", "mode", "fanMode", "heatSliderControl", "heatingSetpoint", "coolSliderControl", "coolingSetpoint", "refresh"])
@@ -124,20 +125,13 @@ metadata {
} }
def installed(){ def installed(){
sendHubCommand(new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeSupportedGet().format())) // Device-Watch simply pings if no device events received for 32min(checkInterval)
initialize() sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
} }
def updated(){ def updated(){
initialize()
}
def initialize() {
// Device-Watch simply pings if no device events received for 32min(checkInterval) // Device-Watch simply pings if no device events received for 32min(checkInterval)
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID]) sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
unschedule()
runEvery5Minutes("refresh")
refresh()
} }
def parse(String description) def parse(String description)
@@ -155,7 +149,6 @@ def parse(String description)
] ]
if (map.name == "thermostatMode") { if (map.name == "thermostatMode") {
state.lastTriedMode = map.value state.lastTriedMode = map.value
map.data = [supportedThermostatModes:state.supportedThermostatModes]
if (map.value == "cool") { if (map.value == "cool") {
map2.value = device.latestValue("coolingSetpoint") map2.value = device.latestValue("coolingSetpoint")
log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}" log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
@@ -179,7 +172,6 @@ def parse(String description)
} }
} else if (map.name == "thermostatFanMode" && map.isStateChange) { } else if (map.name == "thermostatFanMode" && map.isStateChange) {
state.lastTriedFanMode = map.value state.lastTriedFanMode = map.value
map.data = [supportedThermostatFanModes: state.supportedThermostatFanModes]
} }
log.debug "Parse returned $result" log.debug "Parse returned $result"
result result
@@ -313,26 +305,26 @@ def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanMod
} }
def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) { def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
def supportedModes = [] def supportedModes = ""
if(cmd.off) { supportedModes << "off" } if(cmd.off) { supportedModes += "off " }
if(cmd.heat) { supportedModes << "heat" } if(cmd.heat) { supportedModes += "heat " }
if(cmd.cool) { supportedModes << "cool" } if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergency heat " }
if(cmd.auto) { supportedModes << "auto" } if(cmd.cool) { supportedModes += "cool " }
if(cmd.auxiliaryemergencyHeat) { supportedModes << "emergency heat" } if(cmd.auto) { supportedModes += "auto " }
state.supportedThermostatModes = supportedModes state.supportedModes = supportedModes
sendEvent(name: "supportedThermostatModes", value: supportedModes, displayed: false) // No events to be generated, return empty map
return [:] return [:]
} }
def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) { def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
def supportedFanModes = [] def supportedFanModes = ""
if(cmd.auto) { supportedFanModes << "auto" } // "fanAuto " if(cmd.auto) { supportedFanModes += "auto " } // "fanAuto "
if(cmd.circulation) { supportedFanModes << "circulate" } // "fanCirculate" if(cmd.low) { supportedFanModes += "on " } // "fanOn"
if(cmd.low) { supportedFanModes << "on" } // "fanOn" if(cmd.circulation) { supportedFanModes += "circulate " } // "fanCirculate"
state.supportedThermostatFanModes = supportedFanModes state.supportedFanModes = supportedFanModes
sendEvent(name: "supportedThermostatFanModes", value: supportedFanModes, displayed: false) // No events to be generated, return empty map
return [:] return [:]
} }
@@ -345,17 +337,15 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
} }
// Command Implementations // Command Implementations
def refresh() { def poll() {
def cmds = [] delayBetween([
cmds << new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeSupportedGet().format()) zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
cmds << new physicalgraph.device.HubAction(zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format()) zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
cmds << new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeGet().format()) zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
cmds << new physicalgraph.device.HubAction(zwave.thermostatFanModeV3.thermostatFanModeGet().format()) zwave.thermostatModeV2.thermostatModeGet().format(),
cmds << new physicalgraph.device.HubAction(zwave.sensorMultilevelV2.sensorMultilevelGet().format()) // current temperature zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
cmds << new physicalgraph.device.HubAction(zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format()) zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format()
cmds << new physicalgraph.device.HubAction(zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format()) ], 2300)
cmds << new physicalgraph.device.HubAction(zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format())
sendHubCommand(cmds)
} }
def quickSetHeat(degrees) { def quickSetHeat(degrees) {
@@ -426,14 +416,28 @@ def ping() {
poll() poll()
} }
def configure() {
delayBetween([
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format(),
zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format(),
zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
zwave.thermostatModeV2.thermostatModeGet().format(),
zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format()
], 2300)
}
def modes() { def modes() {
return state.supportedThermostatModes ["off", "heat", "cool", "auto", "emergency heat"]
} }
def switchMode() { def switchMode() {
def currentMode = device.currentState("thermostatMode")?.value def currentMode = device.currentState("thermostatMode")?.value
def lastTriedMode = state.lastTriedMode ?: currentMode ?: ["off"] def lastTriedMode = state.lastTriedMode ?: currentMode ?: "off"
def supportedModes = getDataByName("supportedThermostatModes") def supportedModes = getDataByName("supportedModes")
def modeOrder = modes() def modeOrder = modes()
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] } def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode) def nextMode = next(lastTriedMode)
@@ -450,7 +454,7 @@ def switchMode() {
} }
def switchToMode(nextMode) { def switchToMode(nextMode) {
def supportedModes = getDataByName("supportedThermostatModes") def supportedModes = getDataByName("supportedModes")
if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported" if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
if (nextMode in modes()) { if (nextMode in modes()) {
state.lastTriedMode = nextMode state.lastTriedMode = nextMode
@@ -462,9 +466,9 @@ def switchToMode(nextMode) {
def switchFanMode() { def switchFanMode() {
def currentMode = device.currentState("thermostatFanMode")?.value def currentMode = device.currentState("thermostatFanMode")?.value
def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: ["off"] def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: "off"
def supportedModes = getDataByName("supportedThermostatFanModes") ?: ["auto", "on"] def supportedModes = getDataByName("supportedFanModes") ?: "auto on" // "fanAuto fanOn"
def modeOrder = state.supportedThermostatFanModes def modeOrder = ["auto", "circulate", "on"] // "fanAuto", "fanCirculate", "fanOn"
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] } def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
def nextMode = next(lastTriedMode) def nextMode = next(lastTriedMode)
while (!supportedModes?.contains(nextMode) && nextMode != "auto") { // "fanAuto" while (!supportedModes?.contains(nextMode) && nextMode != "auto") { // "fanAuto"
@@ -474,7 +478,7 @@ def switchFanMode() {
} }
def switchToFanMode(nextMode) { def switchToFanMode(nextMode) {
def supportedFanModes = getDataByName("supportedThermostatFanModes") def supportedFanModes = getDataByName("supportedFanModes")
if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported" if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
def returnCommand def returnCommand