Friday, June 26, 2015

A python script to control my Honeywell WiFi Thermostat

I was always jealous of Google Nest users who have such an open API to interface with their thermostat as well as the ability to connect to home automation hubs or services like IFTTT. I had bought a Honeywell WiFi Thermostat (RTH9580WF) because I got an amazing price on it. It always worked fine for me since it had a webpage as well as iOS and Android apps to control it. But now that I am interested in home automation, I am finding the Honeywell thermostat to be very limiting.

After scouring the web, I was able to find and hack a python script to be able to control my thermostat. Thanks to code from Brad Goodman, my modified version is working how I like it to.


Link to my python script


There are three things you need to edit to have the script work for you. First, edit the USERNAME variable with the email login and PASSWORD with the password to your mytotalconnectcomfort.com account. When you log in and enter the page for your thermostat control, the web url will contain the device ID for that thermostat. For example, web address https://mytotalconnectcomfort.com/portal/Device/Control/542695 means that my device ID is 542695. You will enter this number for DEVICE_ID in my python script without any quotation marks.

When downloading the script, remember to check that it has execution permissions with chmod +x therm.py on linux. You can see the arguments available by doing python therm.py -help. The following are the options available:
  • Cooling: -c temperature -t hold_time
  • Heating: -h temperature -t hold_time
  • Status: -s
  • Cancel: -x
The hold_time is in the unit of hours. so -t 1 would be 1 hour. The temperature is configured to be fahrenheit, but can be set to celsius. Cancel means to cancel the current temporary settings. And status prints the following:
% python therm.py -s
Indoor Temperature: 82.0
Indoor Humidity: 37.0
Cool Setpoint: 82.0
Heat Setpoint: 74.0
Hold Until : 0
Status Cool: 0
Status Heat: 0
An example of using the script to set the temperature to cool to 76F for 2 hours would be:
python therm.py -c 76 -t 2
In the future I will be showing how I use this script to allow my thermostat to be controlled by IFTTT and Amazon Echo.

26 comments:

  1. I tried playing with this script to control my Honeywell thermostat, but only some of the functions work.
    I can get to change the cool setpoint, cancel the hold, and show status.
    However, I can't get it to set the heat setpoint (it does the same thing as if I didn't use the right syntax). I also can't get it to hold for anything other than 1 hour.
    Am I doing something wrong, or does the script not able to do these thing?
    Thanks.

    ReplyDelete
    Replies
    1. Hi.

      You're right! I made a mistake of having the -h argument be used for both help and heat. I have fixed the help to be -help instead so the heat setting should work now. The code has been updated in the Github link.

      As for the time, it is set to only work with integers. So setting it to 2 hours, or 3 hours, should work. Based on the way it is set to calculate the time the way Honeywell wants it, anything smaller (like 1.5 hours) is not possible with the code.

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I get this:
    Run at 2015-10-05 14:11:22.770361
    Mon Oct 5 14:11:23 2015 ErrorNever got redirect on initial login status=200 OK
    Anybody know why??

    ReplyDelete
    Replies
    1. Yeah, I just got the same thing, in my case it was a bad password.

      Delete
  4. did you get this to be able to use IFTT and amazon echo, i want this so Bad! as I have the Same Thermostat, and I quickly bought it thinking i would be able to control it Via IFTT and Amazon Echo..to no avail, you said in the future you would show it, it is now November and Cold here in WI.!! lol let me know...Thanks

    ReplyDelete
  5. I decided to go in a different direction. I used the Phython code as a guide to write equivalent PHP code (I'm more comfortable with PHP). I then created a Google Calendar specifically for my thermostat, and created entries when I want it to make changes (with the specific settings in the "Description" field of the event). I set it to send me an e-mail notification at the time the event starts, and I set up a rule in my Gmail to forward those to an address on my web host. That address redirects to my PHP script, which parses the notification, pulls out the commands, and sends them to my thermostat. I still have more work to do - I haven't added in fan or mode control yet, and I should add some error-checking - but it seems to work so far.

    ReplyDelete
    Replies
    1. Can you please share? I more familiar with PHP myself!

      Delete
  6. This is great. Thanks for all the work and input.
    Android: It was the password.
    Now.. does anybody know how to get status on 'emiheat'?
    I thought status return '0,1,2' would reflect 'no heat,heat,emiheat' but it does not.

    ReplyDelete
  7. Hey

    On the request to /portal/Device/CheckDataSession/DEVICE_ID I get a 500 server error. I've retried the URL in chrome and I get the same result.. I have the same unit as you link to above. I'm in the US if that makes any difference

    ReplyDelete
  8. Thanks so much for your work on this, I am so close but hitting just a couple errors. Alexa reads me the proper temp from thermostat. And when I ask her to change temp she says shes doing it but it never reflects a change on totalcomfort, the hold time reflects a change but not the temp. She even says the temp is set to *new* degrees if I ask her for settings, but it does not actually change on the device. And when I run this script from command I always receive:
    print "Indoor Temperature:",j['latestData']['uiData']["DispTemperature"]
    syntax error

    seems weird, any ideas? thank you again!

    ReplyDelete
    Replies
    1. Strange that you are getting a syntax error when running the script directly.

      Did you copy and paste the code to a file or download it directly? I would go back to github, click the raw button on the top right and then do a File > Save from your web browser.

      Delete
    2. Replace the double quotes with single quotes around DispTemperature.

      Delete
    3. Replace the double quotes with single quotes around DispTemperature.

      Delete
  9. This may help others with the same problem: If you get print statement syntax errors the issue most likely is the version of Python. The latest Python version is 3.5.1 but this script is written for an earlier version. I switched to Python 2.7 which is the last version of the Python 2.x series and this script runs perfectly!!!

    ReplyDelete
  10. This may help others with the same problem: If you get print statement syntax errors the issue most likely is the version of Python. The latest Python version is 3.5.1 but this script is written for an earlier version. I switched to Python 2.7 which is the last version of the Python 2.x series and this script runs perfectly!!!

    ReplyDelete
  11. Well, I'm new to Python, but have everything installed, fixed an indentation error (last line), and the "help" command works... but when I try to run it "for real," I get this error:

    Error Didn't get 200 status on R4 status=500 Internal Server Error

    Uhm... what do? Thanks in advance!

    ReplyDelete
  12. Something about heavy to semi-heavy technological jargon really sooths me. I hope you have more posts like this. It feels to me like a completely different world. Luckily my husband actually understood it (I'm so embarrassed) and was absolutely delighted. I'll let you know how things go (looking forward to your next instructional piece).

    Ambrose @ Brown & Reaves Services, Inc.

    ReplyDelete
  13. Nice script, Dan, worked first time. I was looking for a way to monitor my house temperature from my Home Security script, and this fits the bill. I also wanted to track my house temperature as it cools down in the evenings after I go to bed. I added a print for the time/date into your status function, and scheduled it using cron, and I was able to get an hourly temperature - and as I suspected it takes a LONG time for the house to cool. I've now set the night temperature an hour earlier, and I'm saving many dollars in heating costs - thanks!

    ReplyDelete
  14. I successfully used this script to poll my Honeywell wifi thermostat purchased from Home Depot. The back has two model numbers - TH6320WF02 and RTH6580WF1001. I'll go with the latter on since this post refers to one that starts with the same prefix. My unit was about $100 which is a deal compared to NEST at $249. My only problem was I had to get the DEVICE ID from a different place than the URL as suggested above. If you use that device ID, you'll get a SERVER ERROR when the python script runs. The trick here is to go to Honeywell's website and log in to your account. Navigate until you have the graphic of your thermostat loaded on your screen then view the PAGE SOURCE in your browser. There is an XML tag for DEVICE ID which will be different than the number used in the URL for that page. That's the one you need to use.

    ReplyDelete
  15. So awesome! Worked right away. I worry with these proprietary frameworks, but fortunately they're not that sophisticated. Without doing too much research, I had leaned towards some open framework/rasperrypi thing, but you allow me to run my own optimizations. Thanks

    ReplyDelete
  16. This comment has been removed by the author.

    ReplyDelete
  17. is there a way to ignore the thermostat temperature reading, or set it to a fixed value?

    ReplyDelete
  18. When I run the script I get this output:

    Error Didn't get 200 status on R4 status=500 Internal Server Error

    Any idea on how to fix this?

    ReplyDelete
    Replies
    1. I am able to get status, start/stop fan, set cool just fine but when I try to set heat, I get the same error message. I just scoured the code and did not find anything that stood out.

      Delete
  19. urls are different for international users (i'm in the uk), getting the 200 status.
    url from webpage is https://international.mytotalconnectcomfort.com/Locations/View/123456

    ReplyDelete