Making a custom thermostat controller

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)
}

Are you just trying to automate the thermostat?

Does the thermostat already work with SmartThings without a custom device handler? If so, a device type probably isn’t the right place to do this. I would recommend a SmartApp.

What kind of thermostat are you using?

I might not be fully clear…

My end goal is to control an air conditioner on an appliance switch with
feedback from a temperature sensor in the same room. The difference between
this and the stock virtual thermostat smartapp is that I want a way to
disable and reenable the automatic temperature control as needed.

I am trying to interface with this function via Amazon Echo, which speaks
to devices, not SmartApps. A pseudo virtual device is necessary to capture
the commands needed and emulate the function of a real thermostat for these
purposes.

I want Alexa/Echo to respond to the following commands:

Turn AC controller off (currently works)
Turn AC controller on (currently works)
Set AC controller to XX degrees (fails)

It currently seems as if Alexa thinks this device handler is primarily a
switch, and isn’t playing with it a thermostat setpoint controls.

Now, I have also added a temperature sensor capability in this virtual
thermostat that copies the same value as whatever is set on the thermostat
setpoint. I found that some apps like CoRE won’t reference a thermostat
setpoint if the other comparator is another device type. This is a
compatibility feature.

What I need help with is how to clean this up so Alexa responds believing
it is both a switch and a thermostat that can be set.

I have the same scenario but I use a Virtual Thermostat (based on the Template “Simulated Thermostat”) a Virtual Switch and CoRE.

It looks like your DH is missing a lot of Attributes and Commands needed for the “Thermostat” capability and that’s probably why the Amazon Echo is not recognizing this as a Thermostat.
Take a look at the “Simulated Thermostat” Template and the Thermostat Capability (http://docs.smartthings.com/en/latest/capabilities-reference.html#thermostat).

2 Likes