Advertisement
Guest User

therm_scrubbed.py

a guest
Jan 19th, 2016
330
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.97 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. # Original script by Brad Goodman
  4. # http://www.bradgoodman.com/
  5. # brad@bradgoodman.com
  6.  
  7. ####################### Fill in settings below #######################
  8.  
  9. USERNAME="XXXXXX@XXXXXX.XXX"
  10. PASSWORD="XXXXXX"
  11. DEVICE_ID=######
  12. HOST_AND_PORT="192.168.2.8:18080"
  13.  
  14. ############################ End settings ############################
  15.  
  16. import urllib2
  17. import urllib
  18. import json
  19. import datetime
  20. import re
  21. import time
  22. import math
  23. import base64
  24. import time
  25. import httplib
  26. import sys
  27. import tty,termios
  28. import getopt
  29. import os
  30. import stat
  31. import subprocess
  32. import string
  33. from subprocess import call
  34.  
  35. AUTH="https://mytotalconnectcomfort.com/portal"
  36.  
  37. cookiere=re.compile('\s*([^=]+)\s*=\s*([^;]*)\s*')
  38.  
  39. def client_cookies(cookiestr,container):
  40. if not container: container={}
  41. toks=re.split(';|,',cookiestr)
  42. for t in toks:
  43. k=None
  44. v=None
  45. m=cookiere.search(t)
  46. if m:
  47. k=m.group(1)
  48. v=m.group(2)
  49. if (k in ['path','Path','HttpOnly']):
  50. k=None
  51. v=None
  52. if k:
  53. #print k,v
  54. container[k]=v
  55. return container
  56.  
  57. def export_cookiejar(jar):
  58. s=""
  59. for x in jar:
  60. s+='%s=%s;' % (x,jar[x])
  61. return s
  62.  
  63. def get_login(action, value=None, hold_time=1):
  64.  
  65. cookiejar=None
  66. #print
  67. #print
  68. #print "Run at ",datetime.datetime.now()
  69. headers={"Content-Type":"application/x-www-form-urlencoded",
  70. "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  71. "Accept-Encoding":"sdch",
  72. "Host":"mytotalconnectcomfort.com",
  73. "DNT":"1",
  74. "Origin":"https://mytotalconnectcomfort.com/portal",
  75. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
  76. }
  77. conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
  78. conn.request("GET", "/portal/",None,headers)
  79. r0 = conn.getresponse()
  80. #print r0.status, r0.reason
  81.  
  82. for x in r0.getheaders():
  83. (n,v) = x
  84. #print "R0 HEADER",n,v
  85. if (n.lower() == "set-cookie"):
  86. cookiejar=client_cookies(v,cookiejar)
  87. #cookiejar = r0.getheader("Set-Cookie")
  88. location = r0.getheader("Location")
  89.  
  90. retries=5
  91. params=urllib.urlencode({"timeOffset":"240",
  92. "UserName":USERNAME,
  93. "Password":PASSWORD,
  94. "RememberMe":"false"})
  95. #print params
  96. newcookie=export_cookiejar(cookiejar)
  97. #print "Cookiejar now",newcookie
  98. headers={"Content-Type":"application/x-www-form-urlencoded",
  99. "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  100. "Accept-Encoding":"sdch",
  101. "Host":"mytotalconnectcomfort.com",
  102. "DNT":"1",
  103. "Origin":"https://mytotalconnectcomfort.com/portal/",
  104. "Cookie":newcookie,
  105. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36"
  106. }
  107. conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
  108. conn.request("POST", "/portal/",params,headers)
  109. r1 = conn.getresponse()
  110. #print r1.status, r1.reason
  111.  
  112. for x in r1.getheaders():
  113. (n,v) = x
  114. #print "GOT2 HEADER",n,v
  115. if (n.lower() == "set-cookie"):
  116. cookiejar=client_cookies(v,cookiejar)
  117. cookie=export_cookiejar(cookiejar)
  118. #print "Cookiejar now",cookie
  119. location = r1.getheader("Location")
  120.  
  121. if ((location == None) or (r1.status != 302)):
  122. #raise BaseException("Login fail" )
  123. print("ErrorNever got redirect on initial login status={0} {1}".format(r1.status,r1.reason))
  124. return
  125.  
  126.  
  127. # Skip second query - just go directly to our device_id, rather than letting it
  128. # redirect us to it.
  129.  
  130. code=str(DEVICE_ID)
  131.  
  132. t = datetime.datetime.now()
  133. utc_seconds = (time.mktime(t.timetuple()))
  134. utc_seconds = int(utc_seconds*1000)
  135. #print "Code ",code
  136.  
  137. location="/portal/Device/CheckDataSession/"+code+"?_="+str(utc_seconds)
  138. #print "THIRD"
  139. headers={
  140. "Accept":"*/*",
  141. "DNT":"1",
  142. #"Accept-Encoding":"gzip,deflate,sdch",
  143. "Accept-Encoding":"plain",
  144. "Cache-Control":"max-age=0",
  145. "Accept-Language":"en-US,en,q=0.8",
  146. "Connection":"keep-alive",
  147. "Host":"mytotalconnectcomfort.com",
  148. "Referer":"https://mytotalconnectcomfort.com/portal/",
  149. "X-Requested-With":"XMLHttpRequest",
  150. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36",
  151. "Cookie":cookie
  152. }
  153. conn = httplib.HTTPSConnection("mytotalconnectcomfort.com")
  154. #conn.set_debuglevel(999);
  155. #print "LOCATION R3 is",location
  156. conn.request("GET", location,None,headers)
  157. r3 = conn.getresponse()
  158. if (r3.status != 200):
  159. print("Error Didn't get 200 status on R3 status={0} {1}".format(r3.status,r3.reason))
  160. return
  161.  
  162. # Print thermostat information returned
  163.  
  164. if (action == "status"):
  165.  
  166. #print r3.status, r3.reason
  167. rawdata=r3.read()
  168. j = json.loads(rawdata)
  169. #print "R3 Dump"
  170. #print json.dumps(j,indent=2)
  171. #print json.dumps(j,sort_keys=True,indent=4, separators=(',', ': '))
  172. #print "Success:",j['success']
  173. #print "Live",j['deviceLive']
  174. #print "Indoor Temperature:",j['latestData']['uiData']["DispTemperature"]
  175. #print "Indoor Humidity:",j['latestData']['uiData']["IndoorHumidity"]
  176. #print "Cool Setpoint:",j['latestData']['uiData']["CoolSetpoint"]
  177. #print "Heat Setpoint:",j['latestData']['uiData']["HeatSetpoint"]
  178. #print "Hold Until :",j['latestData']['uiData']["TemporaryHoldUntilTime"]
  179. #print "Status Cool:",j['latestData']['uiData']["StatusCool"]
  180. #print "Status Heat:",j['latestData']['uiData']["StatusHeat"]
  181.  
  182. temp = j['latestData']['uiData']["DispTemperature"]
  183.  
  184. cmd = "curl --header 'Content-Type: text/plain' --request PUT --data '" + str(temp) + "' http://" + HOST_AND_PORT + "/rest/items/ThermUp_temp/state"
  185.  
  186. #print cmd
  187.  
  188. os.system(cmd)
  189.  
  190. return
  191.  
  192. headers={
  193. "Accept":'application/json; q=0.01',
  194. "DNT":"1",
  195. "Accept-Encoding":"gzip,deflate,sdch",
  196. 'Content-Type':'application/json; charset=UTF-8',
  197. "Cache-Control":"max-age=0",
  198. "Accept-Language":"en-US,en,q=0.8",
  199. "Connection":"keep-alive",
  200. "Host":"mytotalconnectcomfort.com",
  201. "Referer":"https://mytotalconnectcomfort.com/portal/",
  202. "X-Requested-With":"XMLHttpRequest",
  203. "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36",
  204. 'Referer':"/TotalConnectComfort/Device/CheckDataSession/"+code,
  205. "Cookie":cookie
  206. }
  207.  
  208. # Dats structure with data we will send back
  209.  
  210. payload = {
  211. "CoolNextPeriod": None,
  212. "CoolSetpoint": None,
  213. "DeviceID": DEVICE_ID,
  214. "FanMode": None,
  215. "HeatNextPeriod": None,
  216. "HeatSetpoint": None,
  217. "StatusCool": 0,
  218. "StatusHeat": 0,
  219. "SystemSwitch": None
  220. }
  221.  
  222. # Calculate the hold time for cooling/heating
  223.  
  224. t = datetime.datetime.now();
  225.  
  226. stop_time = ((t.hour+hold_time)%24) * 60 + t.minute
  227. stop_time = stop_time/15
  228.  
  229.  
  230. # Modify payload based on user input
  231.  
  232. if (action == "cool"):
  233. payload["CoolSetpoint"] = value
  234. payload["StatusCool"] = 1
  235. payload["StatusHeat"] = 1
  236. payload["CoolNextPeriod"] = stop_time
  237.  
  238. if (action == "heat"):
  239. payload["HeatSetpoint"] = value
  240. payload["StatusCool"] = 1
  241. payload["StatusHeat"] = 1
  242. payload["HeatNextPeriod"] = stop_time
  243.  
  244. if (action == "cancel"):
  245. payload["StatusCool"] = 0
  246. payload["StatusHeat"] = 0
  247.  
  248. # Prep and send payload
  249.  
  250. location="/portal/Device/SubmitControlScreenChanges"
  251.  
  252. rawj=json.dumps(payload)
  253.  
  254. conn = httplib.HTTPSConnection("mytotalconnectcomfort.com");
  255. #conn.set_debuglevel(999);
  256. #print "R4 will send"
  257. #print rawj
  258. conn.request("POST", location,rawj,headers)
  259. r4 = conn.getresponse()
  260. if (r4.status != 200):
  261. print("Error Didn't get 200 status on R4 status={0} {1}".format(r4.status,r4.reason))
  262. return
  263. else:
  264. print "Success!"
  265. # print "R4 got 200"
  266.  
  267.  
  268. def printUsage():
  269. print
  270. print "Cooling: -c temperature -t hold_time"
  271. print "Heating: -h temperature -t hold_time"
  272. print "Status: -s"
  273. print "Cancel: -x"
  274. print
  275. print "Example: Set temperature to cool to 80f for 1 hour: \n\t therm.py -c 80 -t 1"
  276. print
  277. print "If no -t hold_time is provided, it will default to one hour from command time."
  278. print
  279.  
  280.  
  281. def main():
  282.  
  283. get_login("status")
  284. sys.exit()
  285.  
  286. if __name__ == "__main__":
  287. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement