Hi, I’m learning your “HoneyWell Wifi Thermostat scripts for status” at post 4.
what is this location? http://10.1.100.23:10005/rest/items/IndTemp
Are you running the openhab at server http://10.1.100.23 ?
Why don’t you just leave it at script folder?
It seem you save the $powerstatus" also at http://10.1.100.23:10005/rest/items/HostBatteryPercentage
Thank you
Hello,
Yea, 10.1.100.23 was my openhab host. /rest is the rest api built into openhab. The rest api is the default location to have scripts like bash etc update your items in openhab.
Yes $powerstatus is from a bash script that talks to the openhab API.
“Why don’t you just leave it at script folder?” Not sure what you mean by this.
Hello,
For anyone looking for a cheap hosted IPv6 VM to play with check out http://ecare.cidcomm.com/cart.php
Hey Jay…
How do you controle wether to use geofencing or not. I doubt it´s optimal going for a walk and returning home, and then the garage door is opening? How to prevent that from happening?
Hi iam trying your scripts for the honeywell thermostat but i get the error below
11:25:08.790 [ERROR] [clipse.smarthome.io.net.exec.ExecUtil] - couldn't execute commandLine '/etc/tstat'
java.io.IOException: Cannot run program "/etc/tstat": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) [?:?]
at java.lang.Runtime.exec(Runtime.java:620) [?:?]
at java.lang.Runtime.exec(Runtime.java:450) [?:?]
at java.lang.Runtime.exec(Runtime.java:347) [?:?]
at org.eclipse.smarthome.io.net.exec.ExecUtil.executeCommandLine(ExecUtil.java:63) [118:org.eclipse.smarthome.io.net:0.10.0.oh230]
at org.eclipse.smarthome.model.script.actions.Exec.executeCommandLine(Exec.java:43) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1085) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1060) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:82) [141:org.eclipse.smarthome.model.script.runtime:0.10.0.oh230]
at org.eclipse.smarthome.model.rule.runtime.internal.engine.ExecuteRuleJob.execute(ExecuteRuleJob.java:67) [138:org.eclipse.smarthome.model.rule.runtime:0.10.0.oh230]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [109:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [109:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method) ~[?:?]
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247) ~[?:?]
at java.lang.ProcessImpl.start(ProcessImpl.java:134) ~[?:?]
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029) ~[?:?]
... 28 more
Where do i have to place the tstat script? Actually the scripts!!
Thank you in advance.
ps. i am running openhab 2.3
Also when i am running the script tstat i get some errors.
Getting Data from MyTotalControl Website
Checking Indoor Temp
curl: (3) Illegal characters found in URL
28
Checking Heat Setpoint
curl: (3) Illegal characters found in URL
curl: (3) Illegal characters found in URL
21
Checking Heat On/Off Status
curl: (3) Illegal characters found in URL
1
Checking Fan Status
curl: (3) Illegal characters found in URL
None
Checking Hold Status
curl: (3) Illegal characters found in URL
1080
: numeric argument required
Any help appreciated.
Hi John,
These scripts are all for Debian Linux. are you running Debian Linux?
Also these scripts and code are for OH 1.8. 2.3 is completely redesigned so they most likely wont work.
I am on a raspberry with rasspbian jessie installed. The scripts seem to work individually but i get those errors.
Did you put all the custom scripts in the /etc folder? Its saying it cannot see them there.
Nothing. Wherever i try to put it i get the same error.
16:50:00.095 [ERROR] [clipse.smarthome.io.net.exec.ExecUtil] - couldn't execute commandLine '/etc/tstat'
java.io.IOException: Cannot run program "/etc/tstat": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) [?:?]
at java.lang.Runtime.exec(Runtime.java:620) [?:?]
at java.lang.Runtime.exec(Runtime.java:450) [?:?]
at java.lang.Runtime.exec(Runtime.java:347) [?:?]
at org.eclipse.smarthome.io.net.exec.ExecUtil.executeCommandLine(ExecUtil.java:63) [118:org.eclipse.smarthome.io.net:0.10.0.oh230]
at org.eclipse.smarthome.model.script.actions.Exec.executeCommandLine(Exec.java:43) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1085) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1060) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) [139:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) [158:org.eclipse.xtext.xbase:2.12.0.v20170519-0752]
at org.eclipse.smarthome.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:82) [141:org.eclipse.smarthome.model.script.runtime:0.10.0.oh230]
at org.eclipse.smarthome.model.rule.runtime.internal.engine.ExecuteRuleJob.execute(ExecuteRuleJob.java:67) [138:org.eclipse.smarthome.model.rule.runtime:0.10.0.oh230]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [109:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [109:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method) ~[?:?]
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247) ~[?:?]
at java.lang.ProcessImpl.start(ProcessImpl.java:134) ~[?:?]
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029) ~[?:?]
... 28 more
When i try to run it from shell with
sudo bash tstat
the script runs but i get some errors in the script
Getting Data from MyTotalControl Website
Checking Indoor Temp
curl: (3) Illegal characters found in URL
28
Checking Heat Setpoint
curl: (3) Illegal characters found in URL
curl: (3) Illegal characters found in URL
21
Checking Heat On/Off Status
curl: (3) Illegal characters found in URL
1
Checking Fan Status
curl: (3) Illegal characters found in URL
None
Checking Hold Status
curl: (3) Illegal characters found in URL
1080
: numeric argument required
Looks like permissions partially. Run OH as root or change the folder permissions. chmod a=rwx /etc
I think i solved the problem with executeCommandLine(“sudo /etc/openhab2/scripts/tstat”) in the rule.
Now i am still having problem with refreshing the values in openhab as i get the error below when the script is executed.
Getting Data from MyTotalControl Website
Checking Indoor Temp
curl: (3) Illegal characters found in URL
28
Checking Heat Setpoint
curl: (3) Illegal characters found in URL
curl: (3) Illegal characters found in URL
21
Checking Heat On/Off Status
curl: (3) Illegal characters found in URL
1
Checking Fan Status
curl: (3) Illegal characters found in URL
None
Checking Hold Status
curl: (3) Illegal characters found in URL
1080
: numeric argument required
As you can see it retrieves the values from totalconnect but the values dont appear in openhab interface
Also when i try to send a curl post from terminal
curl --header "Content-Type: text/plain" --request POST --data "31" http://192.168.1.250:8080/rest/items/IndTemp
The item receives it normaly!!!
I am loosing my mind here!!!
Could be the incoming value from honeywell is messed up and feeding it to the script and breaking it.
Ok one step further. The script seems now to be working after some changes, i get the received commands to the items but the item state doesn’t change. i also get an error for ‘as DecimalType’ in the rule.
Here is how i changed the script
echo Checking Indoor Temp
TEMPSTATUS=$( grep "Indoor Temperature" $TEMPDATA | sed -n -e 's/^.*Indoor Temperature: //p')
curl --header "Content-Type: text/plain" --request POST http://192.168.1.250:8080/rest/items/IndTemp --data "$TEMPSTATUS"
echo $TEMPSTATUS
and here is the log from console
19:38:04.615 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'IndTemp' received command 28
19:38:04.756 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'IndHeat' received command 19
19:38:04.847 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Update Temp App': Could not cast NULL to org.eclipse.smarthome.core.library.types.DecimalType; line 180, column 27, length 28
19:38:04.968 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'IndHeatSet': Could not cast NULL to org.eclipse.smarthome.core.library.types.DecimalType; line 164, column 26, length 31
19:38:04.906 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'IndHeatSet' received command 19
19:38:05.472 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'IndHeaterStatus' received command 1
19:38:05.567 [INFO ] [smarthome.event.ItemStateChangedEvent] - LocalComputer_Memory_Used changed from 642 to 639
19:38:05.671 [INFO ] [smarthome.event.ItemStateChangedEvent] - LocalComputer_Cpu_Load changed from 35.4 to 51.9
19:38:05.778 [INFO ] [smarthome.event.ItemCommandEvent ] - Item 'IndHoldStatus' received command 1080
As you can see the items receive the command but nothing in the interface.
Finaly i think i got it working!!! The only thing that i couldnt figure out is the rule tha runs the tstat script every 5 min. It seems to be running but no changes to my items. i overcame the problem by creating a scheduled task with crontab.
Here are my config files for anyone interested using these scripts with openhab 2.3.
items file
// Honeywell Thermostat
Number IndHeat "Current Set Point [%.1f°C]" <temperature> (persist)
Number IndHoldStatus "Hold Status [MAP(thermostat2.map):%d]" <temperature> (persist)
Number IndHeaterStatus "Heat On/Off [MAP(thermostat.map):%d]" (persist)
Number IndTemp "Indoor Temp [%.1f°C]" <temperature> (persist)
Number SendTemp "[%.1f°C]" (persist)
Number IndHeatSet "Set Temp [%.1f°C]" <temperature> (persist)
String IndHeatRes "Resume Schedule" (persist) { autoupdate="false",exec=">[ON:python /etc/openhab2/scripts/therm.py -x] >[OFF:python /etc/openhab2/scripts/therm.py -x]" }
sitemap file
Text label="Thermostat" icon="thermostat" {
Frame {
Text item=IndHoldStatus
Text item=IndHeaterStatus icon="heating"
//Text item=IndFanStatus
Text item=IndTemp
Text item=IndHeat
Setpoint item=IndHeatSet minValue=16 maxValue=23 step=0.5
Switch item=IndHeatRes label="Resume Schedule" mappings=[ON="Resume"] icon="Date"
Rules
//Honeywell Thermostat
// Send selected temperature to MyTotalConnectComfort Portal
rule "IndHeatSet"
when
Item IndHeatSet received command
then
SendTemp.sendCommand(IndHeatSet.state)
end
// Set Heat Setpoint
rule "Send SetPoint to MyTotalConnectComfort Portal"
when
Item SendTemp received command
then
executeCommandLine(" /etc/openhab2/scripts/therm.py -h " + receivedCommand)
end
// Sync Setpoint with the set temp app
rule "Update Temp App"
when
Item IndHeat received command
then
IndHeatSet.postUpdate(IndHeat.state)
end
And the 2 scripts placed in etc\openhab2\scripts folder of my openhab2 installation
therm.py
#!/usr/bin/python
# By Brad Goodman
# http://www.bradgoodman.com/
# brad@bradgoodman.com
####################### Fill in settings below #######################
USERNAME="yourusername"
PASSWORD="yourpassword"
DEVICE_ID=deviceid
############################ End settings ############################
import urllib2
import urllib
import json
import datetime
import re
import time
import math
import base64
import time
import httplib
import sys
import getopt
import os
import stat
import subprocess
import string
AUTH="https://mytotalconnectcomfort.com/portal"
cookiere=re.compile('\s*([^=]+)\s*=\s*([^;]*)\s*')
def client_cookies(cookiestr,container):
if not container: container={}
toks=re.split(';|,',cookiestr)
for t in toks:
k=None
v=None
m=cookiere.search(t)
if m:
k=m.group(1)
v=m.group(2)
if (k in ['path','Path','HttpOnly']):
k=None
v=None
if k:
#print k,v
container[k]=v
return container
def export_cookiejar(jar):
s=""
for x in jar:
s+='%s=%s;' % (x,jar[x])
return s
def get_login(action, value=None):
cookiejar=None
#print
#print
#print "Run at ",datetime.datetime.now()
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":"mytotalconnectcomfort.com",
"DNT":"1",
"Origin":"https://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"
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
conn.request("GET", "/portal/",None,headers)
r0 = conn.getresponse()
#print r0.status, r0.reason
for x in r0.getheaders():
(n,v) = x
#print "R0 HEADER",n,v
if (n.lower() == "set-cookie"):
cookiejar=client_cookies(v,cookiejar)
#cookiejar = r0.getheader("Set-Cookie")
location = r0.getheader("Location")
retries=5
params=urllib.urlencode({"timeOffset":"240",
"UserName":USERNAME,
"Password":PASSWORD,
"RememberMe":"false"})
#print params
newcookie=export_cookiejar(cookiejar)
#print "Cookiejar now",newcookie
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":"mytotalconnectcomfort.com",
"DNT":"1",
"Origin":"https://mytotalconnectcomfort.com/portal/",
"Cookie":newcookie,
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
conn.request("POST", "/portal/",params,headers)
r1 = conn.getresponse()
#print r1.status, r1.reason
for x in r1.getheaders():
(n,v) = x
#print "GOT2 HEADER",n,v
if (n.lower() == "set-cookie"):
cookiejar=client_cookies(v,cookiejar)
cookie=export_cookiejar(cookiejar)
#print "Cookiejar now",cookie
location = r1.getheader("Location")
if ((location == None) or (r1.status != 302)):
#raise BaseException("Login fail" )
print("ErrorNever got redirect on initial login status={0} {1}".format(r1.status,r1.reason))
return
# Skip second query - just go directly to our device_id, rather than letting it
# redirect us to it.
code=str(DEVICE_ID)
t = datetime.datetime.now()
utc_seconds = (time.mktime(t.timetuple()))
utc_seconds = int(utc_seconds*1000)
#print "Code ",code
location="/portal/Device/CheckDataSession/"+code+"?_="+str(utc_seconds)
#print "THIRD"
headers={
"Accept":"*/*",
"DNT":"1",
#"Accept-Encoding":"gzip,deflate,sdch",
"Accept-Encoding":"plain",
"Cache-Control":"max-age=0",
"Accept-Language":"en-US,en,q=0.8",
"Connection":"keep-alive",
"Host":"mytotalconnectcomfort.com",
"Referer":"https://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":cookie
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
conn.set_debuglevel(999);
#print "LOCATION R3 is",location
conn.request("GET", location,None,headers)
r3 = conn.getresponse()
if (r3.status != 200):
print("Error Didn't get 200 status on R3 status={0} {1}".format(r3.status,r3.reason))
return
# Print thermostat information returned
if (action == "status"):
#print r3.status, r3.reason
rawdata=r3.read()
j = json.loads(rawdata)
#print "R3 Dump"
#print json.dumps(j,indent=2)
#print json.dumps(j,sort_keys=True,indent=4, separators=(',', ': '))
#print "Success:",j['success']
#print "Live",j['deviceLive']
print "Indoor Temperature:",j['latestData']['uiData']["DispTemperature"]
#print "Indoor Humidity:",j['latestData']['uiData']["IndoorHumidity"]
#print "Cool Setpoint:",j['latestData']['uiData']["CoolSetpoint"]
print "Heat Setpoint:",j['latestData']['uiData']["HeatSetpoint"]
print "Hold Until :",j['latestData']['uiData']["TemporaryHoldUntilTime"]
# print "Status Cool:",j['latestData']['uiData']["StatusCool"]
print "Status Heat:",j['latestData']['uiData']["StatusHeat"]
#print "Status Fan:",j['latestData']['fanData']["fanMode"]
return
headers={
"Accept":'application/json; q=0.01',
"DNT":"1",
"Accept-Encoding":"gzip,deflate,sdch",
'Content-Type':'application/json; charset=UTF-8',
"Cache-Control":"max-age=0",
"Accept-Language":"en-US,en,q=0.8",
"Connection":"keep-alive",
"Host":"mytotalconnectcomfort.com",
"Referer":"https://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",
'Referer':"/TotalConnectComfort/Device/CheckDataSession/"+code,
"Cookie":cookie
}
# Data structure with data we will send back
payload = {
"CoolNextPeriod": None,
"CoolSetpoint": None,
"DeviceID": DEVICE_ID,
"FanMode": None,
"HeatNextPeriod": None,
"HeatSetpoint": None,
"StatusCool": 0,
"StatusHeat": 0,
"SystemSwitch": None
}
# Calculate the hold time for cooling/heating
# t = datetime.datetime.now();
# stop_time = ((t.hour+hold_time)%24) * 60 + t.minute
# stop_time = stop_time/15
# Modify payload based on user input
if (action == "cool"):
payload["CoolSetpoint"] = value
payload["StatusCool"] = 1
payload["StatusHeat"] = 1
payload["CoolNextPeriod"] = 99
if (action == "heat"):
payload["HeatSetpoint"] = value
payload["StatusCool"] = 1
payload["StatusHeat"] = 1
payload["HeatNextPeriod"] = 'null'
if (action == "cancel"):
payload["StatusCool"] = 0
payload["StatusHeat"] = 0
if (action == "fan"):
payload["FanMode"] = value
# Prep and send payload
location="/portal/Device/SubmitControlScreenChanges"
rawj=json.dumps(payload)
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com");
conn.set_debuglevel(999);
#print "R4 will send"
#print rawj
conn.request("POST", location,rawj,headers)
r4 = conn.getresponse()
if (r4.status != 200):
print("Error Didn't get 200 status on R4 status={0} {1}".format(r4.status,r4.reason))
return
else:
print "Success in configuring thermostat!"
# print "R4 got 200"
def printUsage():
print
print "Cooling: -c temperature -t hold_time"
print "Heating: -h temperature -t hold_time"
print "Status: -s"
print "Cancel: -x"
print "Fan: -f [0=auto|1=on]"
print
print "Example: Set temperature to cool to 80f for 1 hour: \n\t therm.py -c 80 -t 1"
print
print "If no -t hold_time is provided, it will default to one hour from command time."
print
def main():
if sys.argv[1] == "-s":
get_login("status")
sys.exit()
if sys.argv[1] == "-x":
get_login("cancel")
sys.exit()
if (len(sys.argv) < 3) or (sys.argv[1] == "-help"):
printUsage()
sys.exit()
if sys.argv[1] == "-c":
get_login("cool", sys.argv[2])
sys.exit()
if sys.argv[1] == "-h":
get_login("heat", sys.argv[2])
sys.exit()
if sys.argv[1] == "-f":
get_login("fan", sys.argv[2])
sys.exit()
if __name__ == "__main__":
############################ End settings ############################
import urllib2
import urllib
import json
import datetime
import re
import time
import math
import base64
import time
import httplib
import sys
import getopt
import os
import stat
import subprocess
import string
AUTH="https://mytotalconnectcomfort.com/portal"
cookiere=re.compile('\s*([^=]+)\s*=\s*([^;]*)\s*')
def client_cookies(cookiestr,container):
if not container: container={}
toks=re.split(';|,',cookiestr)
for t in toks:
k=None
v=None
m=cookiere.search(t)
if m:
k=m.group(1)
v=m.group(2)
if (k in ['path','Path','HttpOnly']):
k=None
v=None
if k:
#print k,v
container[k]=v
return container
def export_cookiejar(jar):
s=""
for x in jar:
s+='%s=%s;' % (x,jar[x])
return s
def get_login(action, value=None, hold_time=0):
cookiejar=None
#print
#print
#print "Run at ",datetime.datetime.now()
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":"mytotalconnectcomfort.com",
"DNT":"1",
"Origin":"https://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"
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
conn.request("GET", "/portal/",None,headers)
r0 = conn.getresponse()
#print r0.status, r0.reason
for x in r0.getheaders():
(n,v) = x
#print "R0 HEADER",n,v
if (n.lower() == "set-cookie"):
cookiejar=client_cookies(v,cookiejar)
#cookiejar = r0.getheader("Set-Cookie")
location = r0.getheader("Location")
retries=5
params=urllib.urlencode({"timeOffset":"240",
"UserName":USERNAME,
"Password":PASSWORD,
"RememberMe":"false"})
#print params
newcookie=export_cookiejar(cookiejar)
#print "Cookiejar now",newcookie
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":"mytotalconnectcomfort.com",
"DNT":"1",
"Origin":"https://mytotalconnectcomfort.com/portal/",
"Cookie":newcookie,
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
conn.request("POST", "/portal/",params,headers)
r1 = conn.getresponse()
#print r1.status, r1.reason
for x in r1.getheaders():
(n,v) = x
#print "GOT2 HEADER",n,v
if (n.lower() == "set-cookie"):
cookiejar=client_cookies(v,cookiejar)
cookie=export_cookiejar(cookiejar)
#print "Cookiejar now",cookie
location = r1.getheader("Location")
if ((location == None) or (r1.status != 302)):
#raise BaseException("Login fail" )
print("ErrorNever got redirect on initial login status={0} {1}".format(r1.status,r1.reason))
return
# Skip second query - just go directly to our device_id, rather than letting it
# redirect us to it.
code=str(DEVICE_ID)
t = datetime.datetime.now()
utc_seconds = (time.mktime(t.timetuple()))
utc_seconds = int(utc_seconds*1000)
#print "Code ",code
location="/portal/Device/CheckDataSession/"+code+"?_="+str(utc_seconds)
#print "THIRD"
headers={
"Accept":"*/*",
"DNT":"1",
#"Accept-Encoding":"gzip,deflate,sdch",
"Accept-Encoding":"plain",
"Cache-Control":"max-age=0",
"Accept-Language":"en-US,en,q=0.8",
"Connection":"keep-alive",
"Host":"mytotalconnectcomfort.com",
"Referer":"https://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":cookie
}
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
#conn.set_debuglevel(999);
#print "LOCATION R3 is",location
conn.request("GET", location,None,headers)
r3 = conn.getresponse()
if (r3.status != 200):
print("Error Didn't get 200 status on R3 status={0} {1}".format(r3.status,r3.reason))
return
# Print thermostat information returned
if (action == "status"):
#print r3.status, r3.reason
rawdata=r3.read()
j = json.loads(rawdata)
#print "R3 Dump"
#print json.dumps(j,indent=2)
#print json.dumps(j,sort_keys=True,indent=4, separators=(',', ': '))
#print "Success:",j['success']
#print "Live",j['deviceLive']
print "Indoor Temperature:",j['latestData']['uiData']["DispTemperature"]
#print "Indoor Humidity:",j['latestData']['uiData']["IndoorHumidity"]
#print "Cool Setpoint:",j['latestData']['uiData']["CoolSetpoint"]
print "Heat Setpoint:",j['latestData']['uiData']["HeatSetpoint"]
print "Hold Until :",j['latestData']['uiData']["TemporaryHoldUntilTime"]
#print "Status Cool:",j['latestData']['uiData']["StatusCool"]
print "Status Heat:",j['latestData']['uiData']["StatusHeat"]
#print "Status Fan:",j['latestData']['fanData']["fanMode"]
return
headers={
"Accept":'application/json; q=0.01',
"DNT":"1",
"Accept-Encoding":"gzip,deflate,sdch",
'Content-Type':'application/json; charset=UTF-8',
"Cache-Control":"max-age=0",
"Accept-Language":"en-US,en,q=0.8",
"Connection":"keep-alive",
"Host":"mytotalconnectcomfort.com",
"Referer":"https://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",
'Referer':"/TotalConnectComfort/Device/CheckDataSession/"+code,
"Cookie":cookie
}
# Data structure with data we will send back
payload = {
"CoolNextPeriod": None,
"CoolSetpoint": None,
"DeviceID": DEVICE_ID,
"FanMode": None,
"HeatNextPeriod": None,
"HeatSetpoint": None,
"StatusCool": 0,
"StatusHeat": 0,
"SystemSwitch": None
}
# Calculate the hold time for cooling/heating
#t = datetime.datetime.now();
#stop_time = ((t.hour+hold_time)%24) * 60 + t.minute
#stop_time = stop_time/15
# Modify payload based on user input
if (action == "cool"):
payload["CoolSetpoint"] = value
payload["StatusCool"] = 1
payload["StatusHeat"] = 1
payload["CoolNextPeriod"] = 'null'
if (action == "heat"):
payload["HeatSetpoint"] = value
payload["StatusCool"] = 1
payload["StatusHeat"] = 1
payload["HeatNextPeriod"] = 'null'
if (action == "cancel"):
payload["StatusCool"] = 0
payload["StatusHeat"] = 0
if (action == "fan"):
payload["FanMode"] = value
# Prep and send payload
location="/portal/Device/SubmitControlScreenChanges"
rawj=json.dumps(payload)
conn = httplib.HTTPSConnection("mytotalconnectcomfort.com");
#conn.set_debuglevel(999);
#print "R4 will send"
#print rawj
conn.request("POST", location,rawj,headers)
r4 = conn.getresponse()
if (r4.status != 200):
print("Error Didn't get 200 status on R4 status={0} {1}".format(r4.status,r4.reason))
return
else:
print "Success in configuring thermostat!"
# print "R4 got 200"
def printUsage():
print
print "Cooling: -c temperature -t hold_time"
print "Heating: -h temperature -t hold_time"
print "Status: -s"
print "Cancel: -x"
print "Fan: -f [0=auto|1=on]"
print
print "Example: Set temperature to cool to 80f for 1 hour: \n\t therm.py -c 80 -t 1"
print
print "If no -t hold_time is provided, it will default to one hour from command time."
print
def main():
if sys.argv[1] == "-s":
get_login("status")
sys.exit()
if sys.argv[1] == "-x":
get_login("cancel")
sys.exit()
if (len(sys.argv) < 3) or (sys.argv[1] == "-help"):
printUsage()
sys.exit()
if sys.argv[1] == "-c":
get_login("cool", sys.argv[2])
sys.exit()
if sys.argv[1] == "-h":
get_login("heat", sys.argv[2])
sys.exit()
if sys.argv[1] == "-f":
get_login("fan", sys.argv[2])
sys.exit()
if __name__ == "__main__":
main()
tstat
#!/bin/bash
#
# Script by Jamie R. Cid
# jay@cidcomm.com
#
#Get data from MyTotalControl and send to OH. This grabs one copy of the data and stores it instead of doing it for every request below. That's how you get blocked ;)
echo Getting Data from MyTotalControl Website
/etc/openhab2/scripts/therm.py -s > /var/log/honeywell.log
TEMPDATA="/var/log/honeywell.log"
#
#
echo Checking Indoor Temp
TEMPSTATUS=$( grep "Indoor Temperature" $TEMPDATA | sed -n -e 's/^.*Indoor Temperature: //p')
curl --header "Content-Type: text/plain" -X POST "http://192.168.1.250:8080/rest/items/IndTemp" -d "$TEMPSTATUS"
echo $TEMPSTATUS
#
echo Checking Heat Setpoint
HEATSTATUS=$( grep "Heat Setpoint" $TEMPDATA | sed -n -e 's/^.*Heat Setpoint: //p')
curl --header "Content-Type: text/plain" -X POST "http://192.168.1.250:8080/rest/items/IndHeat" -d "$HEATSTATUS"
curl --header "Content-Type: text/plain" -X POST "http://192.168.1.250:8080/rest/items/IndHeatSet" -d "$HEATSTATUS"
echo $HEATSTATUS
#
echo Checking Hold Status
HOLDSTATUS=$( grep "Hold Until" $TEMPDATA | sed -n -e 's/^.*Hold Until : //p')
curl --header "Content-Type: text/plain" -X POST "http://192.168.1.250:8080/rest/items/IndHoldStatus" -d "$HOLDSTATUS"
echo $HOLDSTATUS
#
echo Checking Heat On/Off Status
HEATERSTATUS=$( grep "Status Heat" $TEMPDATA | sed -n -e 's/^.*Status Heat: //p')
curl --header "Content-Type: text/plain" -X POST "http://192.168.1.250:8080/rest/items/IndHeaterStatus" -d "$HEATERSTATUS"
echo $HEATERSTATUS
#
#
exit 0
Sorry for the long post but i hope it will help anyone want to implement it to openhab 2.3
Many thanks to jcid1 for the original config.
Is there a command to set the thermostat to permanent hold?
Will this work with mulitple thermostats? I have system that has 3 zones.
Can anyone post what you have set up in your transformation maps? I have everything displaying and behaving properly but I can’t get my mapping straight. I keep getting errors saying it can’t map.