Skip to content

Commit 771926c

Browse files
committed
ICP-1148 Support Thermostat Dynamic data
Adding support for dynamic thermostat and fan modes to TCC DTH. Also replaced capability "Polling" with "Refresh" and runEvery5Minutes("refresh") as polling capability is unreliable. Also removed capability "Relative Humidity Measurement" as Honeywell Z-Wave Thermostat (YTH8320ZW1007/U) doesn't support humidity.
1 parent ef5fffc commit 771926c

File tree

1 file changed

+47
-51
lines changed

1 file changed

+47
-51
lines changed

devicetypes/smartthings/zwave-thermostat.src/zwave-thermostat.groovy

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ metadata {
1515
definition (name: "Z-Wave Thermostat", namespace: "smartthings", author: "SmartThings") {
1616
capability "Actuator"
1717
capability "Temperature Measurement"
18-
capability "Relative Humidity Measurement"
1918
capability "Thermostat"
2019
capability "Configuration"
21-
capability "Polling"
20+
capability "Refresh"
2221
capability "Sensor"
2322
capability "Health Check"
2423

@@ -117,21 +116,28 @@ metadata {
117116
state "cool", label:'${currentValue}° cool', backgroundColor:"#ffffff"
118117
}
119118
standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
120-
state "default", action:"polling.poll", icon:"st.secondary.refresh"
119+
state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
121120
}
122121
main "temperature"
123122
details(["temperature", "mode", "fanMode", "heatSliderControl", "heatingSetpoint", "coolSliderControl", "coolingSetpoint", "refresh"])
124123
}
125124
}
126125

127126
def installed(){
128-
// Device-Watch simply pings if no device events received for 32min(checkInterval)
129-
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
127+
sendHubCommand(new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeSupportedGet().format()))
128+
initialize()
130129
}
131130

132131
def updated(){
132+
initialize()
133+
}
134+
135+
def initialize() {
133136
// Device-Watch simply pings if no device events received for 32min(checkInterval)
134137
sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
138+
unschedule()
139+
runEvery5Minutes("refresh")
140+
refresh()
135141
}
136142

137143
def parse(String description)
@@ -149,6 +155,7 @@ def parse(String description)
149155
]
150156
if (map.name == "thermostatMode") {
151157
state.lastTriedMode = map.value
158+
map.data = [supportedThermostatModes:state.supportedThermostatModes]
152159
if (map.value == "cool") {
153160
map2.value = device.latestValue("coolingSetpoint")
154161
log.info "THERMOSTAT, latest cooling setpoint = ${map2.value}"
@@ -172,6 +179,7 @@ def parse(String description)
172179
}
173180
} else if (map.name == "thermostatFanMode" && map.isStateChange) {
174181
state.lastTriedFanMode = map.value
182+
map.data = [supportedThermostatFanModes: state.supportedThermostatFanModes]
175183
}
176184
log.debug "Parse returned $result"
177185
result
@@ -305,26 +313,26 @@ def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanMod
305313
}
306314

307315
def zwaveEvent(physicalgraph.zwave.commands.thermostatmodev2.ThermostatModeSupportedReport cmd) {
308-
def supportedModes = ""
309-
if(cmd.off) { supportedModes += "off " }
310-
if(cmd.heat) { supportedModes += "heat " }
311-
if(cmd.auxiliaryemergencyHeat) { supportedModes += "emergency heat " }
312-
if(cmd.cool) { supportedModes += "cool " }
313-
if(cmd.auto) { supportedModes += "auto " }
314-
315-
state.supportedModes = supportedModes
316-
// No events to be generated, return empty map
316+
def supportedModes = []
317+
if(cmd.off) { supportedModes << "off" }
318+
if(cmd.heat) { supportedModes << "heat" }
319+
if(cmd.cool) { supportedModes << "cool" }
320+
if(cmd.auto) { supportedModes << "auto" }
321+
if(cmd.auxiliaryemergencyHeat) { supportedModes << "emergency heat" }
322+
323+
state.supportedThermostatModes = supportedModes
324+
sendEvent(name: "supportedThermostatModes", value: supportedModes, displayed: false)
317325
return [:]
318326
}
319327

320328
def zwaveEvent(physicalgraph.zwave.commands.thermostatfanmodev3.ThermostatFanModeSupportedReport cmd) {
321-
def supportedFanModes = ""
322-
if(cmd.auto) { supportedFanModes += "auto " } // "fanAuto "
323-
if(cmd.low) { supportedFanModes += "on " } // "fanOn"
324-
if(cmd.circulation) { supportedFanModes += "circulate " } // "fanCirculate"
329+
def supportedFanModes = []
330+
if(cmd.auto) { supportedFanModes << "auto" } // "fanAuto "
331+
if(cmd.circulation) { supportedFanModes << "circulate" } // "fanCirculate"
332+
if(cmd.low) { supportedFanModes << "on" } // "fanOn"
325333

326-
state.supportedFanModes = supportedFanModes
327-
// No events to be generated, return empty map
334+
state.supportedThermostatFanModes = supportedFanModes
335+
sendEvent(name: "supportedThermostatFanModes", value: supportedFanModes, displayed: false)
328336
return [:]
329337
}
330338

@@ -337,15 +345,17 @@ def zwaveEvent(physicalgraph.zwave.Command cmd) {
337345
}
338346

339347
// Command Implementations
340-
def poll() {
341-
delayBetween([
342-
zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
343-
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
344-
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
345-
zwave.thermostatModeV2.thermostatModeGet().format(),
346-
zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
347-
zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format()
348-
], 2300)
348+
def refresh() {
349+
def cmds = []
350+
cmds << new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeSupportedGet().format())
351+
cmds << new physicalgraph.device.HubAction(zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format())
352+
cmds << new physicalgraph.device.HubAction(zwave.thermostatModeV2.thermostatModeGet().format())
353+
cmds << new physicalgraph.device.HubAction(zwave.thermostatFanModeV3.thermostatFanModeGet().format())
354+
cmds << new physicalgraph.device.HubAction(zwave.sensorMultilevelV2.sensorMultilevelGet().format()) // current temperature
355+
cmds << new physicalgraph.device.HubAction(zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format())
356+
cmds << new physicalgraph.device.HubAction(zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format())
357+
cmds << new physicalgraph.device.HubAction(zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format())
358+
sendHubCommand(cmds)
349359
}
350360

351361
def quickSetHeat(degrees) {
@@ -416,28 +426,14 @@ def ping() {
416426
poll()
417427
}
418428

419-
def configure() {
420-
delayBetween([
421-
zwave.thermostatModeV2.thermostatModeSupportedGet().format(),
422-
zwave.thermostatFanModeV3.thermostatFanModeSupportedGet().format(),
423-
zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format(),
424-
zwave.sensorMultilevelV3.sensorMultilevelGet().format(), // current temperature
425-
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 1).format(),
426-
zwave.thermostatSetpointV1.thermostatSetpointGet(setpointType: 2).format(),
427-
zwave.thermostatModeV2.thermostatModeGet().format(),
428-
zwave.thermostatFanModeV3.thermostatFanModeGet().format(),
429-
zwave.thermostatOperatingStateV1.thermostatOperatingStateGet().format()
430-
], 2300)
431-
}
432-
433429
def modes() {
434-
["off", "heat", "cool", "auto", "emergency heat"]
430+
return state.supportedThermostatModes
435431
}
436432

437433
def switchMode() {
438434
def currentMode = device.currentState("thermostatMode")?.value
439-
def lastTriedMode = state.lastTriedMode ?: currentMode ?: "off"
440-
def supportedModes = getDataByName("supportedModes")
435+
def lastTriedMode = state.lastTriedMode ?: currentMode ?: ["off"]
436+
def supportedModes = getDataByName("supportedThermostatModes")
441437
def modeOrder = modes()
442438
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
443439
def nextMode = next(lastTriedMode)
@@ -454,7 +450,7 @@ def switchMode() {
454450
}
455451

456452
def switchToMode(nextMode) {
457-
def supportedModes = getDataByName("supportedModes")
453+
def supportedModes = getDataByName("supportedThermostatModes")
458454
if(supportedModes && !supportedModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
459455
if (nextMode in modes()) {
460456
state.lastTriedMode = nextMode
@@ -466,9 +462,9 @@ def switchToMode(nextMode) {
466462

467463
def switchFanMode() {
468464
def currentMode = device.currentState("thermostatFanMode")?.value
469-
def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: "off"
470-
def supportedModes = getDataByName("supportedFanModes") ?: "auto on" // "fanAuto fanOn"
471-
def modeOrder = ["auto", "circulate", "on"] // "fanAuto", "fanCirculate", "fanOn"
465+
def lastTriedMode = state.lastTriedFanMode ?: currentMode ?: ["off"]
466+
def supportedModes = getDataByName("supportedThermostatFanModes") ?: ["auto", "on"]
467+
def modeOrder = state.supportedThermostatFanModes
472468
def next = { modeOrder[modeOrder.indexOf(it) + 1] ?: modeOrder[0] }
473469
def nextMode = next(lastTriedMode)
474470
while (!supportedModes?.contains(nextMode) && nextMode != "auto") { // "fanAuto"
@@ -478,7 +474,7 @@ def switchFanMode() {
478474
}
479475

480476
def switchToFanMode(nextMode) {
481-
def supportedFanModes = getDataByName("supportedFanModes")
477+
def supportedFanModes = getDataByName("supportedThermostatFanModes")
482478
if(supportedFanModes && !supportedFanModes.contains(nextMode)) log.warn "thermostat mode '$nextMode' is not supported"
483479

484480
def returnCommand

0 commit comments

Comments
 (0)