From b12df3f360d103483ba227dc62d9310f8b15054d Mon Sep 17 00:00:00 2001 From: James Chen Date: Tue, 11 Oct 2016 15:20:53 -0700 Subject: [PATCH] Convert setpoints in case of a temperature scale change. Removed useage of convertTemperatureIfNeeded which is an undocumented API fixed spacing On temperature change it will update all setpoints in alterSetpoint function fixed spacing issues spacing changes removed comments --- .../ecobee-thermostat.groovy | 132 ++++++++++-------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy index 37cbb85..adf6433 100644 --- a/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy +++ b/devicetypes/smartthings/ecobee-thermostat.src/ecobee-thermostat.groovy @@ -148,14 +148,12 @@ def generateEvent(Map results) { handlerName: name] if (name=="temperature" || name=="heatingSetpoint" || name=="coolingSetpoint" ) { - def sendValue = convertTemperatureIfNeeded(value.toDouble(), "F", 1) //API return temperature value in F - sendValue = location.temperatureScale == "C"? roundC(sendValue) : sendValue + def sendValue = location.temperatureScale == "C"? roundC(convertFtoC(value.toDouble())) : value.toInteger() isChange = isTemperatureStateChange(device, name, value.toString()) isDisplayed = isChange event << [value: sendValue, unit: temperatureScale, isStateChange: isChange, displayed: isDisplayed] } else if (name=="maxCoolingSetpoint" || name=="minCoolingSetpoint" || name=="maxHeatingSetpoint" || name=="minHeatingSetpoint") { - def sendValue = convertTemperatureIfNeeded(value.toDouble(), "F", 1) //API return temperature value in F - sendValue = location.temperatureScale == "C"? roundC(sendValue) : sendValue + def sendValue = location.temperatureScale == "C"? roundC(convertFtoC(value.toDouble())) : value.toInteger() event << [value: sendValue, unit: temperatureScale, displayed: false] } else if (name=="heatMode" || name=="coolMode" || name=="autoMode" || name=="auxHeatMode"){ isChange = isStateChange(device, name, value.toString()) @@ -253,7 +251,6 @@ void setCoolingSetpoint(setpoint) { def maxCoolingSetpoint = device.currentValue("maxCoolingSetpoint") def minCoolingSetpoint = device.currentValue("minCoolingSetpoint") - if (coolingSetpoint > maxCoolingSetpoint) { coolingSetpoint = maxCoolingSetpoint } else if (coolingSetpoint < minCoolingSetpoint) { @@ -283,7 +280,6 @@ void setCoolingSetpoint(setpoint) { } void resumeProgram() { - log.debug "resumeProgram() is called" sendEvent("name":"thermostatStatus", "value":"resuming schedule", "description":statusText, displayed: false) def deviceId = device.deviceNetworkId.split(/\./).last() @@ -354,7 +350,6 @@ def switchFanMode() { } def switchToFanMode(nextMode) { - log.debug "switching to fan mode: $nextMode" def returnCommand @@ -520,63 +515,56 @@ def fanAuto() { } def generateSetpointEvent() { - log.debug "Generate SetPoint Event" def mode = device.currentValue("thermostatMode") - log.debug "Current Mode = ${mode}" def heatingSetpoint = device.currentValue("heatingSetpoint") - log.debug "Heating Setpoint = ${heatingSetpoint}" - def coolingSetpoint = device.currentValue("coolingSetpoint") - log.debug "Cooling Setpoint = ${coolingSetpoint}" - def maxHeatingSetpoint = device.currentValue("maxHeatingSetpoint") def maxCoolingSetpoint = device.currentValue("maxCoolingSetpoint") def minHeatingSetpoint = device.currentValue("minHeatingSetpoint") def minCoolingSetpoint = device.currentValue("minCoolingSetpoint") - if(location.temperatureScale == "C") - { - maxHeatingSetpoint = roundC(maxHeatingSetpoint) - maxCoolingSetpoint = roundC(maxCoolingSetpoint) - minHeatingSetpoint = roundC(minHeatingSetpoint) - minCoolingSetpoint = roundC(minCoolingSetpoint) - heatingSetpoint = roundC(heatingSetpoint) - coolingSetpoint = roundC(coolingSetpoint) + if(location.temperatureScale == "C") { + maxHeatingSetpoint = maxHeatingSetpoint > 40 ? roundC(convertFtoC(maxHeatingSetpoint)) : roundC(maxHeatingSetpoint) + maxCoolingSetpoint = maxCoolingSetpoint > 40 ? roundC(convertFtoC(maxCoolingSetpoint)) : roundC(maxCoolingSetpoint) + minHeatingSetpoint = minHeatingSetpoint > 40 ? roundC(convertFtoC(minHeatingSetpoint)) : roundC(minHeatingSetpoint) + minCoolingSetpoint = minCoolingSetpoint > 40 ? roundC(convertFtoC(minCoolingSetpoint)) : roundC(minCoolingSetpoint) + heatingSetpoint = heatingSetpoint > 40 ? roundC(convertFtoC(heatingSetpoint)) : roundC(heatingSetpoint) + coolingSetpoint = coolingSetpoint > 40 ? roundC(convertFtoC(coolingSetpoint)) : roundC(coolingSetpoint) + } else { + maxHeatingSetpoint = maxHeatingSetpoint < 40 ? roundC(convertCtoF(maxHeatingSetpoint)) : maxHeatingSetpoint + maxCoolingSetpoint = maxCoolingSetpoint < 40 ? roundC(convertCtoF(maxCoolingSetpoint)) : maxCoolingSetpoint + minHeatingSetpoint = minHeatingSetpoint < 40 ? roundC(convertCtoF(minHeatingSetpoint)) : minHeatingSetpoint + minCoolingSetpoint = minCoolingSetpoint < 40 ? roundC(convertCtoF(minCoolingSetpoint)) : minCoolingSetpoint + heatingSetpoint = heatingSetpoint < 40 ? roundC(convertCtoF(heatingSetpoint)) : heatingSetpoint + coolingSetpoint = coolingSetpoint < 40 ? roundC(convertCtoF(coolingSetpoint)) : coolingSetpoint } + log.debug "Current Mode = ${mode}" + log.debug "Heating Setpoint = ${heatingSetpoint}" + log.debug "Cooling Setpoint = ${coolingSetpoint}" sendEvent("name":"maxHeatingSetpoint", "value":maxHeatingSetpoint, "unit":location.temperatureScale) sendEvent("name":"maxCoolingSetpoint", "value":maxCoolingSetpoint, "unit":location.temperatureScale) sendEvent("name":"minHeatingSetpoint", "value":minHeatingSetpoint, "unit":location.temperatureScale) sendEvent("name":"minCoolingSetpoint", "value":minCoolingSetpoint, "unit":location.temperatureScale) - + sendEvent("name":"heatingSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale) + sendEvent("name":"coolingSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale) if (mode == "heat") { - sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale) - } else if (mode == "cool") { - sendEvent("name":"thermostatSetpoint", "value":coolingSetpoint, "unit":location.temperatureScale) - } else if (mode == "auto") { - sendEvent("name":"thermostatSetpoint", "value":"Auto") - } else if (mode == "off") { - sendEvent("name":"thermostatSetpoint", "value":"Off") - } else if (mode == "auxHeatOnly") { - sendEvent("name":"thermostatSetpoint", "value":heatingSetpoint, "unit":location.temperatureScale) - } - } void raiseSetpoint() { @@ -585,21 +573,31 @@ void raiseSetpoint() { def maxHeatingSetpoint = device.currentValue("maxHeatingSetpoint") def maxCoolingSetpoint = device.currentValue("maxCoolingSetpoint") - if (mode == "off" || mode == "auto") { log.warn "this mode: $mode does not allow raiseSetpoint" } else { + def heatingSetpoint = device.currentValue("heatingSetpoint") def coolingSetpoint = device.currentValue("coolingSetpoint") def thermostatSetpoint = device.currentValue("thermostatSetpoint") + + if (location.temperatureScale == "C") { + maxHeatingSetpoint = maxHeatingSetpoint > 40 ? convertFtoC(maxHeatingSetpoint) : maxHeatingSetpoint + maxCoolingSetpoint = maxCoolingSetpoint > 40 ? convertFtoC(maxCoolingSetpoint) : maxCoolingSetpoint + heatingSetpoint = heatingSetpoint > 40 ? convertFtoC(heatingSetpoint) : heatingSetpoint + coolingSetpoint = coolingSetpoint > 40 ? convertFtoC(coolingSetpoint) : coolingSetpoint + thermostatSetpoint = thermostatSetpoint > 40 ? convertFtoC(thermostatSetpoint) : thermostatSetpoint + } else { + maxHeatingSetpoint = maxHeatingSetpoint < 40 ? convertCtoF(maxHeatingSetpoint) : maxHeatingSetpoint + maxCoolingSetpoint = maxCoolingSetpoint < 40 ? convertCtoF(maxCoolingSetpoint) : maxCoolingSetpoint + heatingSetpoint = heatingSetpoint < 40 ? convertCtoF(heatingSetpoint) : heatingSetpoint + coolingSetpoint = coolingSetpoint < 40 ? convertCtoF(coolingSetpoint) : coolingSetpoint + thermostatSetpoint = thermostatSetpoint < 40 ? convertCtoF(thermostatSetpoint) : thermostatSetpoint + } + log.debug "raiseSetpoint() mode = ${mode}, heatingSetpoint: ${heatingSetpoint}, coolingSetpoint:${coolingSetpoint}, thermostatSetpoint:${thermostatSetpoint}" - if (device.latestState('thermostatSetpoint')) { - targetvalue = device.latestState('thermostatSetpoint').value - targetvalue = location.temperatureScale == "F"? targetvalue.toInteger() : targetvalue.toDouble() - } else { - targetvalue = 0 - } + targetvalue = thermostatSetpoint ? thermostatSetpoint : 0 targetvalue = location.temperatureScale == "F"? targetvalue + 1 : targetvalue + 0.5 if ((mode == "heat" || mode == "auxHeatOnly") && targetvalue > maxHeatingSetpoint) { @@ -622,20 +620,29 @@ void lowerSetpoint() { def minHeatingSetpoint = device.currentValue("minHeatingSetpoint") def minCoolingSetpoint = device.currentValue("minCoolingSetpoint") - if (mode == "off" || mode == "auto") { log.warn "this mode: $mode does not allow lowerSetpoint" } else { def heatingSetpoint = device.currentValue("heatingSetpoint") def coolingSetpoint = device.currentValue("coolingSetpoint") def thermostatSetpoint = device.currentValue("thermostatSetpoint") - log.debug "lowerSetpoint() mode = ${mode}, heatingSetpoint: ${heatingSetpoint}, coolingSetpoint:${coolingSetpoint}, thermostatSetpoint:${thermostatSetpoint}" - if (device.latestState('thermostatSetpoint')) { - targetvalue = device.latestState('thermostatSetpoint').value - targetvalue = location.temperatureScale == "F"? targetvalue.toInteger() : targetvalue.toDouble() + + if (location.temperatureScale == "C") { + minHeatingSetpoint = minHeatingSetpoint > 40 ? convertFtoC(minHeatingSetpoint) : minHeatingSetpoint + minCoolingSetpoint = minCoolingSetpoint > 40 ? convertFtoC(minCoolingSetpoint) : minCoolingSetpoint + heatingSetpoint = heatingSetpoint > 40 ? convertFtoC(heatingSetpoint) : heatingSetpoint + coolingSetpoint = coolingSetpoint > 40 ? convertFtoC(coolingSetpoint) : coolingSetpoint + thermostatSetpoint = thermostatSetpoint > 40 ? convertFtoC(thermostatSetpoint) : thermostatSetpoint } else { - targetvalue = 0 + minHeatingSetpoint = minHeatingSetpoint < 40 ? convertCtoF(minHeatingSetpoint) : minHeatingSetpoint + minCoolingSetpoint = minCoolingSetpoint < 40 ? convertCtoF(minCoolingSetpoint) : minCoolingSetpoint + heatingSetpoint = heatingSetpoint < 40 ? convertCtoF(heatingSetpoint) : heatingSetpoint + coolingSetpoint = coolingSetpoint < 40 ? convertCtoF(coolingSetpoint) : coolingSetpoint + thermostatSetpoint = thermostatSetpoint < 40 ? convertCtoF(thermostatSetpoint) : thermostatSetpoint } + log.debug "lowerSetpoint() mode = ${mode}, heatingSetpoint: ${heatingSetpoint}, coolingSetpoint:${coolingSetpoint}, thermostatSetpoint:${thermostatSetpoint}" + + targetvalue = thermostatSetpoint ? thermostatSetpoint : 0 targetvalue = location.temperatureScale == "F"? targetvalue - 1 : targetvalue - 0.5 if ((mode == "heat" || mode == "auxHeatOnly") && targetvalue < minHeatingSetpoint) { @@ -653,7 +660,6 @@ void lowerSetpoint() { //called by raiseSetpoint() and lowerSetpoint() void alterSetpoint(temp) { - def mode = device.currentValue("thermostatMode") if (mode == "off" || mode == "auto") { @@ -666,6 +672,18 @@ void alterSetpoint(temp) { def targetHeatingSetpoint def targetCoolingSetpoint + def temperatureScaleHasChanged = false + + if (location.temperatureScale == "C") { + if ( heatingSetpoint > 40.0 || coolingSetpoint > 40.0 ) { + temperatureScaleHasChanged = true + } + } else { + if ( heatingSetpoint < 40.0 || coolingSetpoint < 40.0 ) { + temperatureScaleHasChanged = true + } + } + //step1: check thermostatMode, enforce limits before sending request to cloud if (mode == "heat" || mode == "auxHeatOnly"){ if (temp.value > coolingSetpoint){ @@ -707,17 +725,18 @@ void alterSetpoint(temp) { sendEvent("name": "thermostatSetpoint", "value": coolingSetpoint.toString(), displayed: false) } } + + if ( temperatureScaleHasChanged ) + generateSetpointEvent() generateStatusEvent() } } def generateStatusEvent() { - def mode = device.currentValue("thermostatMode") def heatingSetpoint = device.currentValue("heatingSetpoint") def coolingSetpoint = device.currentValue("coolingSetpoint") def temperature = device.currentValue("temperature") - def statusText log.debug "Generate Status Event for Mode = ${mode}" @@ -727,36 +746,25 @@ def generateStatusEvent() { log.debug "HVAC Mode = ${mode}" if (mode == "heat") { - if (temperature >= heatingSetpoint) statusText = "Right Now: Idle" else statusText = "Heating to ${heatingSetpoint} ${location.temperatureScale}" - } else if (mode == "cool") { - if (temperature <= coolingSetpoint) statusText = "Right Now: Idle" else statusText = "Cooling to ${coolingSetpoint} ${location.temperatureScale}" - } else if (mode == "auto") { - statusText = "Right Now: Auto" - } else if (mode == "off") { - statusText = "Right Now: Off" - } else if (mode == "auxHeatOnly") { - statusText = "Emergency Heat" - } else { - statusText = "?" - } + log.debug "Generate Status Event = ${statusText}" sendEvent("name":"thermostatStatus", "value":statusText, "description":statusText, displayed: true) } @@ -770,7 +778,7 @@ def roundC (tempC) { } def convertFtoC (tempF) { - return String.format("%.1f", (Math.round(((tempF - 32)*(5/9)) * 2))/2) + return ((Math.round(((tempF - 32)*(5/9)) * 2))/2).toDouble() } def convertCtoF (tempC) {