mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-09 05:11:52 +00:00
Compare commits
1 Commits
MSA-1522-1
...
MSA-882-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1298dc55ae |
@@ -0,0 +1,970 @@
|
||||
/**
|
||||
* Total Comfort API
|
||||
*
|
||||
* Based on Code by Eric Thomas
|
||||
*
|
||||
* 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
|
||||
* lgk v 3 added optional outdoor temp sensors and preferences for it, also made api login required.
|
||||
* 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.
|
||||
* lgk version 4 supports celsius and fahrenheit with option, and now colors.
|
||||
* lgk version 5, due to intermittant update failures added last update date/time tile so that you can see when it happended
|
||||
* not there is a new input tzoffset which defaults to my time ie -5 which you must set .
|
||||
* lgk version 6 add support for actually knowing the fan is on or not (added tile),
|
||||
* and also the actual operating state ie heating,cooling or idle via new response variables.
|
||||
* lgk version 7, change the new operating state to be a value vs standard tile
|
||||
* to work around a bug smartthings caused in the latest 2.08 release with text wrapping.
|
||||
* related also added icons to the operating state, and increase the width of the last update
|
||||
* to avoid wrapping.
|
||||
* 2-14-16 llb added full path to icons so the show on android Fire Tablet
|
||||
* 2-14-16 llb added check for indoor humidity sensor to avoid 128 value if not supported
|
||||
* 2-14-16 llb modified operating state tile to show control by Hold or Schedule
|
||||
*
|
||||
*/
|
||||
preferences {
|
||||
input("username", "text", title: "Username", description: "Your Total Comfort User Name", required: true)
|
||||
input("password", "password", title: "Password", description: "Your Total Comfort password",required: true)
|
||||
input("honeywelldevice", "text", title: "Device ID", description: "Your Device ID", required: true)
|
||||
input ("enableOutdoorTemps", "enum", title: "Do you have the optional outdoor temperature sensor and want to enable it?", options: ["Yes", "No"], required: false, defaultValue: "No")
|
||||
input ("tempScale", "enum", title: "Fahrenheit or Celsius?", options: ["F", "C"], required: false, defaultValue: "F")
|
||||
input("tzOffset", "number", title: "Time zone offset +/-xx?", required: false, defaultValue: -5, description: "Time Zone Offset ie -5.")
|
||||
}
|
||||
|
||||
metadata {
|
||||
definition (name: "Total Comfort API", namespace:
|
||||
"Total Comfort API", author: "Eric Thomas, modified lg kahn") {
|
||||
capability "Polling"
|
||||
capability "Thermostat"
|
||||
capability "Refresh"
|
||||
capability "Temperature Measurement"
|
||||
capability "Sensor"
|
||||
capability "Relative Humidity Measurement"
|
||||
command "heatLevelUp"
|
||||
command "heatLevelDown"
|
||||
command "coolLevelUp"
|
||||
command "coolLevelDown"
|
||||
attribute "outdoorHumidity", "number"
|
||||
attribute "outdoorTemperature", "number"
|
||||
attribute "lastUpdate", "string"
|
||||
|
||||
|
||||
}
|
||||
|
||||
simulator {
|
||||
// TODO: define status and reply messages here
|
||||
}
|
||||
|
||||
tiles {
|
||||
valueTile("temperature", "device.temperature", width: 2, height: 2, canChangeIcon: true) {
|
||||
state("temperature", label: '${currentValue}°',
|
||||
icon: "http://cdn.device-icons.smartthings.com/Weather/weather2-icn@3x.png",
|
||||
unit:"F", backgroundColors: [
|
||||
[value: -14, color: "#1e9cbb"],
|
||||
[value: -10, color: "#90d2a7"],
|
||||
[value: -5, color: "#44b621"],
|
||||
[value: -2, color: "#f1d801"],
|
||||
[value: 0, color: "#153591"],
|
||||
[value: 7, color: "#1e9cbb"],
|
||||
[value: 15, color: "#90d2a7"],
|
||||
[value: 23, color: "#44b621"],
|
||||
[value: 29, color: "#f1d801"],
|
||||
[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("thermostatMode", "device.thermostatMode", inactiveLabel: false, canChangeIcon: true) {
|
||||
state "off", label:'${name}', action:"thermostat.cool", icon: "http://cdn.device-icons.smartthings.com/Outdoor/outdoor19.png"
|
||||
state "cool", label:'${name}', action:"thermostat.heat", icon: "http://cdn.device-icons.smartthings.com/Weather/weather7.png", backgroundColor: '#1e9cbb'
|
||||
state "heat", label:'${name}', action:"thermostat.auto", icon: "http://cdn.device-icons.smartthings.com/Weather/weather14.png", backgroundColor: '#E14902'
|
||||
state "auto", label:'${name}', action:"thermostat.off", icon: "http://cdn.device-icons.smartthings.com/Weather/weather3.png", backgroundColor: '#44b621'
|
||||
}
|
||||
standardTile("thermostatFanMode", "device.thermostatFanMode", inactiveLabel: false, canChangeIcon: true) {
|
||||
state "auto", label:'${name}', action:"thermostat.fanAuto", icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png", backgroundColor: '#44b621'
|
||||
state "circulate", label:'${name}', action:"thermostat.fanCirculate", icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png", backgroundColor: '#44b621'
|
||||
state "on", label:'${name}', action:"thermostat.fanOn", icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png", backgroundColor: '#44b621'
|
||||
}
|
||||
|
||||
controlTile("coolSliderControl", "device.coolingSetpoint", "slider", height: 3, width: 1, inactiveLabel: false) {
|
||||
state "setCoolingSetpoint", label:'Set temperarure to', action:"thermostat.setCoolingSetpoint",
|
||||
backgroundColors:[
|
||||
[value: 0, color: "#153591"],
|
||||
[value: 7, color: "#1e9cbb"],
|
||||
[value: 15, color: "#90d2a7"],
|
||||
[value: 23, color: "#44b621"],
|
||||
[value: 29, color: "#f1d801"],
|
||||
[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"]
|
||||
]
|
||||
}
|
||||
valueTile("coolingSetpoint", "device.coolingSetpoint", inactiveLabel: false)
|
||||
{
|
||||
state "default", label:'Cool\n${currentValue}°', unit:"F",
|
||||
backgroundColors: [
|
||||
[value: 0, color: "#153591"],
|
||||
[value: 7, color: "#1e9cbb"],
|
||||
[value: 15, color: "#90d2a7"],
|
||||
[value: 23, color: "#44b621"],
|
||||
[value: 29, color: "#f1d801"],
|
||||
[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"]
|
||||
]
|
||||
}
|
||||
valueTile("heatingSetpoint", "device.heatingSetpoint", inactiveLabel: false)
|
||||
{
|
||||
state "default", label:'Heat\n${currentValue}°', unit: "F",
|
||||
backgroundColors:[
|
||||
[value: 0, color: "#153591"],
|
||||
[value: 7, color: "#1e9cbb"],
|
||||
[value: 15, color: "#90d2a7"],
|
||||
[value: 23, color: "#44b621"],
|
||||
[value: 29, color: "#f1d801"],
|
||||
[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"]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
//tile added for operating state - Create the tiles for each possible state, look at other examples if you wish to change the icons here.
|
||||
|
||||
valueTile("thermostatOperatingState", "device.thermostatOperatingState", inactiveLabel: false) {
|
||||
state 'default', label:'${currentValue}',
|
||||
backgroundColors:[
|
||||
[value: 0, color: "#911535"]]
|
||||
state "Unknown", label:'${name}', backgroundColor : '#cc0000', icon: ""
|
||||
}
|
||||
|
||||
standardTile("fanOperatingState", "device.fanOperatingState", inactiveLabel: false) {
|
||||
state "On", label:'${name}',icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png", backgroundColor : '#53a7c0'
|
||||
state "Idle", label:'${name}',icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png"
|
||||
state "Unknown", label:'${name}',icon: "http://cdn.device-icons.smartthings.com/Appliances/appliances11.png", backgroundColor : '#cc0000'
|
||||
}
|
||||
|
||||
standardTile("refresh", "device.thermostatMode", inactiveLabel: false, decoration: "flat") {
|
||||
state "default", action:"polling.poll", icon:"http://cdn.device-icons.smartthings.com/secondary/refresh@2x.png"
|
||||
}
|
||||
|
||||
standardTile("heatLevelUp", "device.heatingSetpoint", canChangeIcon: false, inactiveLabel: false) {
|
||||
state "heatLevelUp", label:' ', action:"heatLevelUp", icon:"http://cdn.device-icons.smartthings.com/thermostat/thermostat-up.png"
|
||||
}
|
||||
standardTile("heatLevelDown", "device.heatingSetpoint", canChangeIcon: false, inactiveLabel: false) {
|
||||
state "heatLevelDown", label:' ', action:"heatLevelDown", icon:"http://cdn.device-icons.smartthings.com/thermostat/thermostat-down.png"
|
||||
}
|
||||
standardTile("coolLevelUp", "device.heatingSetpoint", canChangeIcon: false, inactiveLabel: false) {
|
||||
state "coolLevelUp", label:' ', action:"coolLevelUp", icon:"http://cdn.device-icons.smartthings.com/thermostat/thermostat-up.png"
|
||||
}
|
||||
standardTile("coolLevelDown", "device.heatingSetpoint", canChangeIcon: false, inactiveLabel: false) {
|
||||
state "coolLevelDown", label:' ', action:"coolLevelDown", icon:"http://cdn.device-icons.smartthings.com/thermostat/thermostat-down.png"
|
||||
}
|
||||
|
||||
valueTile("relativeHumidity", "device.relativeHumidity", inactiveLabel: false)
|
||||
{
|
||||
state "default", label:'Humidity\n${currentValue}%',
|
||||
icon: "http://cdn.device-icons.smartthings.com/Weather/weather12-icn@3x.png",
|
||||
unit:"%", backgroundColors : [
|
||||
[value: 01, color: "#724529"],
|
||||
[value: 11, color: "#724529"],
|
||||
[value: 21, color: "#724529"],
|
||||
[value: 35, color: "#44b621"],
|
||||
[value: 49, color: "#44b621"],
|
||||
[value: 50, color: "#1e9cbb"]
|
||||
]
|
||||
}
|
||||
|
||||
standardTile("thermostatMode", "device.thermostatMode", inactiveLabel: false, canChangeIcon: true)
|
||||
{
|
||||
}
|
||||
|
||||
/* lgk new tiles for outside temp and hummidity */
|
||||
valueTile("outdoorTemperature", "device.outdoorTemperature", width: 1, height: 1, canChangeIcon: true) {
|
||||
state("temperature", label: 'Outdoor\n ${currentValue}°',
|
||||
icon: "http://cdn.device-icons.smartthings.com/Weather/weather2-icn@3x.png",
|
||||
unit:"F", backgroundColors: [
|
||||
[value: -31, color: "#003591"],
|
||||
[value: -10, color: "#90d2a7"],
|
||||
[value: -5, color: "#44b621"],
|
||||
[value: -2, color: "#f1d801"],
|
||||
[value: 0, color: "#153591"],
|
||||
[value: 7, color: "#1e9cbb"],
|
||||
[value: 00, color: "#cccccc"],
|
||||
[value: 31, color: "#153500"],
|
||||
[value: 44, color: "#1e9cbb"],
|
||||
[value: 59, color: "#90d2a7"],
|
||||
[value: 74, color: "#44b621"],
|
||||
[value: 84, color: "#f1d801"],
|
||||
[value: 95, color: "#d04e00"],
|
||||
[value: 96, color: "#bc2323"]
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
valueTile("outdoorHumidity", "device.outdoorHumidity", inactiveLabel: false){
|
||||
state "default", label:'Outdoor\n ${currentValue}%',
|
||||
icon: "http://cdn.device-icons.smartthings.com/Weather/weather12-icn@3x.png",
|
||||
unit:"%", backgroundColors : [
|
||||
[value: 01, color: "#724529"],
|
||||
[value: 11, color: "#724529"],
|
||||
[value: 21, color: "#724529"],
|
||||
[value: 35, color: "#44b621"],
|
||||
[value: 49, color: "#44b621"],
|
||||
[value: 70, color: "#449c00"],
|
||||
[value: 90, color: "#009cbb"]
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
valueTile("status", "device.lastUpdate", width: 3, height: 1, decoration: "flat") {
|
||||
state "default", label: 'Last Update: ${currentValue}'
|
||||
}
|
||||
|
||||
main "temperature"
|
||||
details(["temperature", "thermostatMode", "thermostatFanMode",
|
||||
"heatLevelUp", "heatingSetpoint" , "heatLevelDown", "coolLevelUp",
|
||||
"coolingSetpoint", "coolLevelDown" ,"thermostatOperatingState","fanOperatingState",
|
||||
"refresh","relativeHumidity","outdoorTemperature","outdoorHumidity", "status"])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def coolLevelUp()
|
||||
{
|
||||
state.DisplayUnits = settings.tempScale
|
||||
if (state.DisplayUnits == "F")
|
||||
{
|
||||
int nextLevel = device.currentValue("coolingSetpoint") + 1
|
||||
|
||||
if( nextLevel > 99){
|
||||
nextLevel = 99
|
||||
}
|
||||
log.debug "Setting cool set point up to: ${nextLevel}"
|
||||
setCoolingSetpoint(nextLevel)
|
||||
}
|
||||
else
|
||||
{
|
||||
int nextLevel = device.currentValue("coolingSetpoint") + 0.5
|
||||
|
||||
if( nextLevel > 37){
|
||||
nextLevel = 37
|
||||
}
|
||||
log.debug "Setting cool set point up to: ${nextLevel}"
|
||||
setCoolingSetpoint(nextLevel)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def coolLevelDown()
|
||||
{
|
||||
state.DisplayUnits = settings.tempScale
|
||||
if (state.DisplayUnits == "F")
|
||||
{
|
||||
int nextLevel = device.currentValue("coolingSetpoint") - 1
|
||||
|
||||
if( nextLevel < 50){
|
||||
nextLevel = 50
|
||||
}
|
||||
log.debug "Setting cool set point down to: ${nextLevel}"
|
||||
setCoolingSetpoint(nextLevel)
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
double nextLevel = device.currentValue("coolingSetpoint") - 0.5
|
||||
|
||||
if( nextLevel < 10){
|
||||
nextLevel = 10
|
||||
}
|
||||
log.debug "Setting cool set point down to: ${nextLevel}"
|
||||
setCoolingSetpoint(nextLevel)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def heatLevelUp()
|
||||
{
|
||||
state.DisplayUnits = settings.tempScale
|
||||
if (state.DisplayUnits == "F")
|
||||
{
|
||||
log.debug "in fahrenheit level up"
|
||||
int nextLevel = device.currentValue("heatingSetpoint") + 1
|
||||
|
||||
if( nextLevel > 90){
|
||||
nextLevel = 90
|
||||
}
|
||||
log.debug "Setting heat set point up to: ${nextLevel}"
|
||||
setHeatingSetpoint(nextLevel)
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
log.debug "in celsius level uo"
|
||||
double nextLevel = device.currentValue("heatingSetpoint") + 0.5
|
||||
|
||||
if( nextLevel > 33){
|
||||
nextLevel = 33
|
||||
}
|
||||
log.debug "Setting heat set point up to: ${nextLevel}"
|
||||
setHeatingSetpoint(nextLevel)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
def heatLevelDown()
|
||||
{
|
||||
state.DisplayUnits = settings.tempScale
|
||||
if (state.DisplayUnits == "F")
|
||||
{
|
||||
log.debug "in fahrenheit level down"
|
||||
int nextLevel = device.currentValue("heatingSetpoint") - 1
|
||||
|
||||
if( nextLevel < 40){
|
||||
nextLevel = 40
|
||||
}
|
||||
log.debug "Setting heat set point down to: ${nextLevel}"
|
||||
setHeatingSetpoint(nextLevel)
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
log.debug "in celsius level down"
|
||||
double nextLevel = device.currentValue("heatingSetpoint") - 0.5
|
||||
|
||||
if( nextLevel < 4){
|
||||
nextLevel = 4
|
||||
}
|
||||
log.debug "Setting heat set point down to: ${nextLevel}"
|
||||
setHeatingSetpoint(nextLevel)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// parse events into attributes
|
||||
def parse(String description) {
|
||||
|
||||
}
|
||||
|
||||
// handle commands
|
||||
|
||||
def setHeatingSetpoint(Double temp)
|
||||
{
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = temp
|
||||
data.CoolSetpoint = 'null'
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'heatingSetpoint', value: temp as double)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def setHeatingSetpoint(temp) {
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = temp
|
||||
data.CoolSetpoint = 'null'
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'heatingSetpoint', value: temp as Integer)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def setCoolingSetpoint(double temp) {
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = 'null'
|
||||
data.CoolSetpoint = temp
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'coolingSetpoint', value: temp as double)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def setCoolingSetpoint(temp) {
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = 'null'
|
||||
data.CoolSetpoint = temp
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'coolingSetpoint', value: temp as Integer)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def setTargetTemp(temp) {
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = temp
|
||||
data.CoolSetpoint = temp
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
}
|
||||
|
||||
|
||||
|
||||
def setTargetTemp(double temp) {
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = temp
|
||||
data.CoolSetpoint = temp
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='1'
|
||||
data.StatusCool='1'
|
||||
data.FanMode = 'null'
|
||||
setStatus()
|
||||
}
|
||||
|
||||
|
||||
def off() {
|
||||
setThermostatMode(2)
|
||||
}
|
||||
|
||||
def auto() {
|
||||
setThermostatMode(4)
|
||||
}
|
||||
|
||||
def heat() {
|
||||
setThermostatMode(1)
|
||||
}
|
||||
|
||||
def emergencyHeat() {
|
||||
|
||||
}
|
||||
|
||||
def cool() {
|
||||
setThermostatMode(3)
|
||||
}
|
||||
|
||||
def setThermostatMode(mode) {
|
||||
data.SystemSwitch = mode
|
||||
data.HeatSetpoint = 'null'
|
||||
data.CoolSetpoint = 'null'
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat=1
|
||||
data.StatusCool=1
|
||||
data.FanMode = 'null'
|
||||
|
||||
setStatus()
|
||||
|
||||
def switchPos
|
||||
|
||||
if(mode==1)
|
||||
switchPos = 'heat'
|
||||
if(mode==2)
|
||||
switchPos = 'off'
|
||||
if(mode==3)
|
||||
switchPos = 'cool'
|
||||
/* lgk modified my therm has pos 5 for auto vision pro */
|
||||
if(mode==4 || swithPos == 5)
|
||||
switchPos = 'auto'
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'thermostatMode', value: switchPos)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def fanOn() {
|
||||
setThermostatFanMode(1)
|
||||
}
|
||||
|
||||
def fanAuto() {
|
||||
setThermostatFanMode(0)
|
||||
}
|
||||
|
||||
def fanCirculate() {
|
||||
setThermostatFanMode(2)
|
||||
}
|
||||
|
||||
def setThermostatFanMode(mode) {
|
||||
|
||||
data.SystemSwitch = 'null'
|
||||
data.HeatSetpoint = 'null'
|
||||
data.CoolSetpoint = 'null'
|
||||
data.HeatNextPeriod = 'null'
|
||||
data.CoolNextPeriod = 'null'
|
||||
data.StatusHeat='null'
|
||||
data.StatusCool='null'
|
||||
data.FanMode = mode
|
||||
|
||||
setStatus()
|
||||
|
||||
def fanMode
|
||||
|
||||
if(mode==0)
|
||||
fanMode = 'auto'
|
||||
if(mode==1)
|
||||
fanMode = 'on'
|
||||
if(mode==2)
|
||||
fanMode = 'circulate'
|
||||
|
||||
if(data.SetStatus==1)
|
||||
{
|
||||
sendEvent(name: 'thermostatFanMode', value: fanMode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
def poll() {
|
||||
refresh()
|
||||
}
|
||||
|
||||
|
||||
def setStatus() {
|
||||
|
||||
data.SetStatus = 0
|
||||
|
||||
login()
|
||||
log.debug "Executing 'setStatus'"
|
||||
def today= new Date()
|
||||
log.debug "https://www.mytotalconnectcomfort.com/portal/Device/SubmitControlScreenChanges"
|
||||
log.debug "setting heat setpoint to $data.HeatSetpoint"
|
||||
log.debug "setting cool setpoint to $data.CoolSetpoint"
|
||||
|
||||
def params = [
|
||||
uri: "https://www.mytotalconnectcomfort.com/portal/Device/SubmitControlScreenChanges",
|
||||
headers: [
|
||||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'DNT': '1',
|
||||
'Accept-Encoding': 'gzip,deflate,sdch',
|
||||
'Cache-Control': 'max-age=0',
|
||||
'Accept-Language': 'en-US,en,q=0.8',
|
||||
'Connection': 'keep-alive',
|
||||
'Host': 'rs.alarmnet.com',
|
||||
'Referer': "https://www.mytotalconnectcomfort.com/portal/Device/Control/${settings.honeywelldevice}",
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36',
|
||||
'Cookie': data.cookiess ],
|
||||
body: [ DeviceID: "${settings.honeywelldevice}", SystemSwitch : data.SystemSwitch ,HeatSetpoint :
|
||||
data.HeatSetpoint, CoolSetpoint: data.CoolSetpoint, HeatNextPeriod:
|
||||
data.HeatNextPeriod,CoolNextPeriod:data.CoolNextPeriod,StatusHeat:data.StatusHeat,
|
||||
StatusCool:data.StatusCool,FanMode:data.FanMode,ThermostatUnits: settings.tempScale]
|
||||
|
||||
]
|
||||
|
||||
log.debug "params = $params"
|
||||
httpPost(params) { response ->
|
||||
log.debug "Request was successful, $response.status"
|
||||
|
||||
}
|
||||
|
||||
log.debug "SetStatus is 1 now"
|
||||
data.SetStatus = 1
|
||||
|
||||
}
|
||||
|
||||
def getStatus() {
|
||||
log.debug "Executing getStatus"
|
||||
log.debug "enable outside temps = $enableOutdoorTemps"
|
||||
def today= new Date()
|
||||
log.debug "https://www.mytotalconnectcomfort.com/portal/Device/CheckDataSession/${settings.honeywelldevice}?_=$today.time"
|
||||
|
||||
def params = [
|
||||
uri: "https://www.mytotalconnectcomfort.com/portal/Device/CheckDataSession/${settings.honeywelldevice}",
|
||||
headers: [
|
||||
'Accept': '*/*',
|
||||
'DNT': '1',
|
||||
'Cache' : 'false',
|
||||
'dataType': 'json',
|
||||
'Accept-Encoding': 'plain',
|
||||
'Cache-Control': 'max-age=0',
|
||||
'Accept-Language': 'en-US,en,q=0.8',
|
||||
'Connection': 'keep-alive',
|
||||
'Referer': 'https://www.mytotalconnectcomfort.com/portal',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36',
|
||||
'Cookie': data.cookiess ],
|
||||
]
|
||||
|
||||
log.debug "doing request"
|
||||
|
||||
httpGet(params) { response ->
|
||||
log.debug "Request was successful, $response.status"
|
||||
//log.debug "data = $response.data"
|
||||
log.debug "ld = $response.data.latestData"
|
||||
|
||||
def curTemp = response.data.latestData.uiData.DispTemperature
|
||||
def fanMode = response.data.latestData.fanData.fanMode
|
||||
def switchPos = response.data.latestData.uiData.SystemSwitchPosition
|
||||
def coolSetPoint = response.data.latestData.uiData.CoolSetpoint
|
||||
def heatSetPoint = response.data.latestData.uiData.HeatSetpoint
|
||||
def statusCool = response.data.latestData.uiData.StatusCool
|
||||
def statusHeat = response.data.latestData.uiData.StatusHeat
|
||||
def curHumidity = response.data.latestData.uiData.IndoorHumidity
|
||||
def Boolean hasOutdoorHumid = response.data.latestData.uiData.OutdoorHumidityAvailable
|
||||
def Boolean hasOutdoorTemp = response.data.latestData.uiData.OutdoorTemperatureAvailable
|
||||
def curOutdoorHumidity = response.data.latestData.uiData.OutdoorHumidity
|
||||
def curOutdoorTemp = response.data.latestData.uiData.OutdoorTemperature
|
||||
def displayUnits = response.data.latestData.uiData.DisplayUnits
|
||||
def fanIsRunning = response.data.latestData.fanData.fanIsRunning
|
||||
def equipmentStatus = response.data.latestData.uiData.EquipmentOutputStatus
|
||||
def Boolean hasIndoorHumid = response.data.latestData.uiData.IndoorHumiditySensorAvailable
|
||||
def curSetpointStatus = response.data.latestData.uiData.CurrentSetpointStatus
|
||||
def TempHoldTime = response.data.latestData.uiData.TemporaryHoldUntilTime
|
||||
def int TempHoldTimeHrs = TempHoldTime / 60
|
||||
def TempHoldTimeMins = TempHoldTime % 60
|
||||
|
||||
/*ld = [fanData:[fanModeCirculateAllowed:true, fanModeAutoAllowed:true, fanModeFollowScheduleAllowed:false,
|
||||
fanIsRunning:false, fanModeOnAllowed:true, fanMode:0],
|
||||
drData:[Load:127.5, HeatSetpLimit:0,
|
||||
OptOutable:false, DeltaHeatSP:-0.01, CoolSetpLimit:0, Phase:-1, DeltaCoolSP:-0.01],
|
||||
uiData:[OutdoorTemperature:128.0000, TemporaryHoldUntilTime:0, ScheduleHeatSp:67.0000,
|
||||
DeviceID:453824, DispTemperatureAvailable:true, VacationHold:0, VacationHoldUntilTime:0,
|
||||
CoolSetpoint:76.0000, ScheduleCoolSp:76.0000, SwitchHeatAllowed:true, CoolNextPeriod:67,
|
||||
IndoorHumidity:31.0000, SwitchAutoAllowed:true, SetpointChangeAllowed:true, HeatLowerSetptLimit:40.0000,
|
||||
OutdoorHumidStatus:128, SwitchOffAllowed:true, OutdoorHumidityAvailable:false,
|
||||
StatusCool:0, OutdoorTemperatureAvailable:false, EquipmentOutputStatus:0, StatusHeat:0,
|
||||
CurrentSetpointStatus:0, HoldUntilCapable:true, CoolUpperSetptLimit:99.0000, SwitchCoolAllowed:true,
|
||||
OutdoorHumidity:128.0000, DualSetpointStatus:false, SwitchEmergencyHeatAllowed:false, Commercial:false,
|
||||
CoolLowerSetptLimit:50.0000, OutdoorHumiditySensorNotFault:true, IndoorHumiditySensorAvailable:true,
|
||||
ScheduleCapable:true, DisplayUnits:F, DispTemperature:70.0000, Deadband:3.0000, HeatUpperSetptLimit:90.0000,
|
||||
IsInVacationHoldMode:false, OutdoorTemperatureSensorNotFault:true, HeatSetpoint:67.0000, DispTemperatureStatus:0,
|
||||
HeatNextPeriod:67, IndoorHumiditySensorNotFault:true, OutdoorTempStatus:128, IndoorHumidStatus:0,
|
||||
SystemSwitchPosition:4], canControlHumidification:false, hasFan:true]
|
||||
|
||||
log.trace("Fan operating state: ${response.data.latestData.fanData.fanIsRunning}")
|
||||
log.trace("EquipmentOutputStatus: ${response.data.latestData.uiData.EquipmentOutputStatus}")
|
||||
log.trace("IndoorHumidity: ${response.data.latestData.uiData.IndoorHumidity}")
|
||||
|
||||
log.trace("OutdoorTemp = ${response.data.latestData.uiData.OutdoorTemperature}")
|
||||
log.trace("fanMode: ${response.data.latestData.fanData.fanMode}")
|
||||
log.trace("SystenSwitchPosition: ${response.data.latestData.uiData.SystemSwitchPosition}")
|
||||
log.trace("StatusCool: ${response.data.latestData.uiData.StatusCool}")
|
||||
log.trace("StatusHeat: ${response.data.latestData.uiData.StatusHeat}")
|
||||
|
||||
log.trace("IndoorHumiditySensorAvailable: ${response.data.latestData.uiData.IndoorHumiditySensorAvailable}")
|
||||
log.trace("IndoorHumidityAvailable: ${response.data.latestData.uiData.IndoorHumidityAvailable}")
|
||||
|
||||
log.debug "OutdoorHumidityAvailable: response.data.latestData.uiData.OutdoorHumidityAvailable"
|
||||
log.debug "OutdoorTemperatureAvailable: $response.data.latestData.uiData.OutdoorTemperatureAvailable"
|
||||
|
||||
log.debug "OutdoorHumiditySensorNotFault = $response.data.latestData.uiData.OutdoorHumiditySensorNotFault"
|
||||
log.debug "OutdoorTemperatureSensorNotFault = $response.data.latestData.uiData.OutdoorTemperatureSensorNotFault"
|
||||
|
||||
log.debug "IndoorHumiditySensorNotFault: $response.data.latestData.uiData.IndoorHumiditySensorNotFault"
|
||||
log.debug "IndoorHumidStatus: $response.data.latestData.uiData.IndoorHumidStatus"
|
||||
log.debug "OutdoorHumidStatus: $response.data.latestData.uiData.OutdoorHumidStatus"
|
||||
log.debug "OutdoorHumidity: = $response.data.latestData.uiData.OutdoorHumidity"
|
||||
log.debug "OutdoorTemperature = $response.data.latestData.uiData.OutdoorTemperature"
|
||||
|
||||
log.debug "got curOutdoorTemp = $curOutdoorTemp"
|
||||
log.debug "got curOutdoorHumidity = $curOutdoorHumidity"
|
||||
log.debug "hasOutdoorHumid = $hasOutdoorHumid"
|
||||
log.debug "hasOutdoorTemp = $hasOutdoorTemp"
|
||||
*/
|
||||
|
||||
// log.debug "displayUnits = $displayUnits"
|
||||
state.DisplayUnits = $displayUnits
|
||||
|
||||
//Operating State Section
|
||||
//Set the operating state to off
|
||||
|
||||
def operatingState = "Unknown"
|
||||
|
||||
// lgk operating state not working here.. shows both on ie 1 when heat doesnt go on to 67 and heat till 76 and current is 73
|
||||
//Check the status of heat and cool
|
||||
|
||||
// lgk old method now use equipment status
|
||||
if (equipmentStatus == 1) {
|
||||
operatingState = "HEAT ON"
|
||||
} else if (equipmentStatus == 2) {
|
||||
operatingState = "COOL ON"
|
||||
} else if (equipmentStatus == 0) {
|
||||
operatingState = "IDLE"
|
||||
} else {
|
||||
operatingState = "Unknown"
|
||||
}
|
||||
|
||||
if(curSetpointStatus == 0) {
|
||||
operatingState = "$operatingState\nControl By\nFollowing\nSchedule"
|
||||
} else if(curSetpointStatus == 1) {
|
||||
operatingState = "$operatingState\nControl By\nHold Until\n" + String.format("%02d:%02d", TempHoldTimeHrs, TempHoldTimeMins)
|
||||
} else if(curSetpointStatus == 2) {
|
||||
operatingState = "$operatingState\nControl By\nPermanent\nHold"
|
||||
|
||||
} else {
|
||||
operatingState = "unknown"
|
||||
}
|
||||
|
||||
/*
|
||||
if(statusCool == 1 && (switchPos == 3 || switchPos == 5 || swithPos == 4)) {
|
||||
operatingState = "cooling"
|
||||
} else if (statusHeat == 1 && (switchPos == 1 || switchPos == 5 || switchPos == 4)) {
|
||||
operatingState = "heating"
|
||||
} else if (statusCool == 0 && statusHeat == 0) {
|
||||
operatingState = "idle"
|
||||
|
||||
} else {
|
||||
operatingState = "unknown"
|
||||
}
|
||||
*/
|
||||
|
||||
log.trace("Set operating State to: ${operatingState}")
|
||||
|
||||
// set fast state
|
||||
def fanState = "Unknown"
|
||||
|
||||
if (fanIsRunning == true)
|
||||
fanState = "On"
|
||||
else fanState = "Idle"
|
||||
|
||||
log.trace("Set Fan operating State to: ${fanState}")
|
||||
|
||||
//End Operating State
|
||||
|
||||
// log.debug curTemp
|
||||
// log.debug fanMode
|
||||
// log.debug switchPos
|
||||
|
||||
//fan mode 0=auto, 2=circ, 1=on
|
||||
|
||||
if(fanMode==0)
|
||||
fanMode = 'auto'
|
||||
if(fanMode==1)
|
||||
fanMode = 'on'
|
||||
if(fanMode==2)
|
||||
fanMode = 'circulate'
|
||||
|
||||
if(switchPos==1)
|
||||
switchPos = 'heat'
|
||||
if(switchPos==2)
|
||||
switchPos = 'off'
|
||||
if(switchPos==3)
|
||||
switchPos = 'cool'
|
||||
if(switchPos==4 || switchPos==5)
|
||||
switchPos = 'auto'
|
||||
|
||||
def formattedCoolSetPoint = String.format("%5.1f", coolSetPoint)
|
||||
def formattedHeatSetPoint = String.format("%5.1f", heatSetPoint)
|
||||
def formattedTemp = String.format("%5.1f", curTemp)
|
||||
|
||||
def finalCoolSetPoint = formattedCoolSetPoint as BigDecimal
|
||||
def finalHeatSetPoint = formattedHeatSetPoint as BigDecimal
|
||||
def finalTemp = formattedTemp as BigDecimal
|
||||
|
||||
//Send events
|
||||
sendEvent(name: 'thermostatOperatingState', value: operatingState)
|
||||
sendEvent(name: 'fanOperatingState', value: fanState)
|
||||
sendEvent(name: 'thermostatFanMode', value: fanMode)
|
||||
sendEvent(name: 'thermostatMode', value: switchPos)
|
||||
sendEvent(name: 'coolingSetpoint', value: finalCoolSetPoint )
|
||||
sendEvent(name: 'heatingSetpoint', value: finalHeatSetPoint )
|
||||
sendEvent(name: 'temperature', value: finalTemp, state: switchPos)
|
||||
if (hasIndoorHumid){sendEvent(name: 'relativeHumidity', value: curHumidity as Integer)}
|
||||
|
||||
if (settings.tzOffset == null)
|
||||
settings.tzOffset = -5
|
||||
|
||||
def now = new Date()
|
||||
def tf = new java.text.SimpleDateFormat("MM/dd/yyyy h:mm a")
|
||||
tf.setTimeZone(TimeZone.getTimeZone("GMT${settings.tzOffset}"))
|
||||
def newtime = "${tf.format(now)}" as String
|
||||
sendEvent(name: "lastUpdate", value: newtime, descriptionText: "Last Update: $newtime")
|
||||
|
||||
|
||||
if (enableOutdoorTemps == "Yes")
|
||||
{
|
||||
|
||||
if (hasOutdoorHumid)
|
||||
{
|
||||
sendEvent(name: 'outdoorHumidity', value: curOutdoorHumidity as Integer)
|
||||
}
|
||||
|
||||
if (hasOutdoorTemp)
|
||||
{
|
||||
sendEvent(name: 'outdoorTemperature', value: curOutdoorTemp as Integer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def getHumidifierStatus()
|
||||
{
|
||||
/*
|
||||
$.ajax({
|
||||
url: humUrl,
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
/portal/Device/Menu/GetHumData/454832';
|
||||
*/
|
||||
def params = [
|
||||
uri: "https://www.mytotalconnectcomfort.com/portal/Device/Menu/GetHumData/${settings.honeywelldevice}",
|
||||
headers: [
|
||||
'Accept': '*/*',
|
||||
'DNT': '1',
|
||||
'dataType': 'json',
|
||||
'cache': 'false',
|
||||
'Accept-Encoding': 'plain',
|
||||
'Cache-Control': 'max-age=0',
|
||||
'Accept-Language': 'en-US,en,q=0.8',
|
||||
'Connection': 'keep-alive',
|
||||
'Host': 'rs.alarmnet.com',
|
||||
'Referer': 'https://www.mytotalconnectcomfort.com/portal/Menu/${settings.honeywelldevice}',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36',
|
||||
'Cookie': data.cookiess ],
|
||||
]
|
||||
httpGet(params) { response ->
|
||||
log.debug "GetHumidity Request was successful, $response.status"
|
||||
log.debug "response = $response.data"
|
||||
|
||||
// log.debug "ld = $response.data.latestData"
|
||||
// log.debug "humdata = $response.data.latestData.humData"
|
||||
|
||||
log.trace("lowerLimit: ${response.data.latestData.humData.lowerLimit}")
|
||||
log.trace("upperLimit: ${response.data.humData.upperLimit}")
|
||||
log.trace("SetPoint: ${response.data.humData.Setpoint}")
|
||||
log.trace("DeviceId: ${response.data.humData.DeviceId}")
|
||||
log.trace("IndoorHumidity: ${response.data.humData.IndoorHumidity}")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def api(method, args = [], success = {}) {
|
||||
|
||||
}
|
||||
|
||||
// Need to be logged in before this is called. So don't call this. Call api.
|
||||
def doRequest(uri, args, type, success) {
|
||||
|
||||
}
|
||||
|
||||
def refresh() {
|
||||
log.debug "Executing 'refresh'"
|
||||
def unit = getTemperatureScale()
|
||||
log.debug "units = $unit"
|
||||
login()
|
||||
//getHumidifierStatus()
|
||||
getStatus()
|
||||
}
|
||||
|
||||
def login() {
|
||||
log.debug "Executing 'login'"
|
||||
|
||||
def params = [
|
||||
uri: 'https://www.mytotalconnectcomfort.com/portal',
|
||||
headers: [
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Encoding': 'sdch',
|
||||
'Host': 'www.mytotalconnectcomfort.com',
|
||||
'DNT': '1',
|
||||
'Origin': 'www.mytotalconnectcomfort.com/portal/',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36'
|
||||
],
|
||||
body: [timeOffset: '240', UserName: "${settings.username}", Password: "${settings.password}", RememberMe: 'false']
|
||||
]
|
||||
|
||||
data.cookiess = ''
|
||||
|
||||
httpPost(params) { response ->
|
||||
log.debug "Request was successful, $response.status"
|
||||
log.debug response.headers
|
||||
response.getHeaders('Set-Cookie').each {
|
||||
String cookie = it.value.split(';|,')[0]
|
||||
log.debug "Adding cookie to collection: $cookie"
|
||||
if(cookie != ".ASPXAUTH_TH_A=") {
|
||||
data.cookiess = data.cookiess+cookie+';'
|
||||
}
|
||||
}
|
||||
log.debug "cookies: $data.cookiess"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def isLoggedIn() {
|
||||
if(!data.auth) {
|
||||
log.debug "No data.auth"
|
||||
return false
|
||||
}
|
||||
|
||||
def now = new Date().getTime();
|
||||
return data.auth.expires_in > now
|
||||
}
|
||||
|
||||
|
||||
def updated()
|
||||
{
|
||||
log.debug "in updated"
|
||||
state.DisplayUnits = settings.tempScale
|
||||
log.debug "display units now = $state.DisplayUnits"
|
||||
|
||||
}
|
||||
|
||||
def installed() {
|
||||
state.DisplayUnits = settings.tempScale
|
||||
|
||||
log.debug "display units now = $state.DisplayUnits"
|
||||
}
|
||||
Reference in New Issue
Block a user