I’ve had the urge to make a custom virtual thermostat controller after being let down by the official one in the SmartThings library. What I’m trying to do is have a virtual thermostat where I can turn it on and off, and a setpoint. Using a SmartApp (or CoRE for right now), I can detect the ambient temperature from any temperature sensor, compare that to the setpoint on the virtual thermostat, detect whether the thermostat is “on”, and if all is good, then turn on the air conditioner.
I’d also like to be able to control this all via the Amazon Echo voice commands, but in it’s current form, I keep getting strange device errors using thermostat controls via voice to Smarthings for this. Alexa will turn on and off the master switch just fine, but it seems it’s not able to associate “Alexa, set the “thermostat name” temperature to 65 degrees.” with this device type.
Also, it seems that the GUI smarttile elements don’t seem to update correctly on the app when I press buttons. It was working fine in the simulator…
What am I doing wrong? This is my first SmartThings Device Type or programming attempt of any kind. Help!
FYI: I know and understand the risks in having large appliances turned on and off automatically like this. Just want to get this working.
/**
* Smart Virtual Thermostat
*
* Copyright 2017 Angela Morley
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
metadata {
definition (name: "Smart Virtual Thermostat", namespace: "omgitsgela", author: "Angela Morley") {
capability "Switch"
capability "Temperature Measurement"
capability "Thermostat Setpoint"
command "on"
command "off"
command "tempUp"
command "tempDown"
command "setTemperature", ["number"] }
simulator {
/* TODO: define status and reply messages here */ }
tiles (scale: 1) {
valueTile("thermostatSetpoint", "device.thermostatSetpoint") {
state("thermostatSetpoint", label:'${currentValue}', unit:"dF",
backgroundColors:[
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]])}
standardTile("switch", "device.switch", canChangeIcon: true, decoration: "flat") {
state "off", label: 'off', action: "on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
state "on", label: 'on', action: "off", icon: "st.switches.switch.on", backgroundColor: "#79b821" }
standardTile("tempUp", "device.thermostatSetpoint", decoration: "flat") {
state "default", label:'up', action:"tempUp", icon: "st.thermostat.thermostat-up"}
standardTile("tempDown", "device.thermostatSetpoint", decoration: "flat") {
state "default", label:'down', action:"tempDown", icon: "st.thermostat.thermostat-down"}
main("switch")
// view (order is left-to-right, top-to-bottom)
details(["thermostatSetpoint", "switch", "tempUp", "tempDown"])
}
}
def installed() {
sendEvent(name: "thermostatSetpoint", value: 72, unit: "F")
sendEvent(name: "temperature", value: 72, unit: "F")
}
// parse events into attributes
def parse(String description) {
log.debug "Parsing '${description}'"
// TODO: handle 'switch' attribute
// TODO: handle 'temperature' attribute
// TODO: handle 'thermostatSetpoint' attribute
// TODO: handle 'thermostatSetpointMin' attribute
// TODO: handle 'thermostatSetpointMax' attribute
}
// handle commands
def on() {
log.debug "Executing 'on'"
sendEvent(name: "switch", value: "on")
}
def off() {
log.debug "Executing 'off'"
sendEvent(name: "switch", value: "off")
}
def tempUp() {
def ts = device.currentState("thermostatSetpoint")
def value = ts ? ts.integerValue + 1 : 72
log.debug "Temperature set to " + value
sendEvent(name:"thermostatSetpoint", value: value)
sendEvent(name:"temperature", value: value)
}
def tempDown() {
def ts = device.currentState("thermostatSetpoint")
def value = ts ? ts.integerValue - 1 : 72
log.debug "Temperature set to " + value
sendEvent(name:"thermostatSetpoint", value: value)
sendEvent(name:"temperature", value: value)
}