Category: Raspi Projects

  • Thermostat Logging / Datamining

    So, I’m not so fancy as to have a Nest thermostat or anything, but I do have access to two WiFi enabled thermostats that have a closed-source app for iOS and Android, and a closed source web app. These tools are nice, but lack a lot of useful features. The company who made these did, however, release a public API which is pretty useful. Unfortunately, the thermostats never really caught on in the developer or the consumer world. There are a few people online who do work on them, and I’ve managed to figure a few things out.

    The thermostats I have access to are marketed under either Radio Thermostat CT50 or Filtrete 3M-50.

    The API has a few versions (I haven’t been able to tell a significant difference) that is published here.

    –Update-– That link is now broken – Radio Thermostat have since taken down their API documentation. Here’s a copy of the API documentation.

    The API works great–but the thermostats do take a bit of time to respond to any GET or POST actions. For instance, my python script that polls them takes about 5 seconds to come back with any data.

    So, I set up a mySQL database, user, and table for my project.  Easy enough. Then I wrote a script in Python to grab a few bits of information from the thermostat, like current temperature, commanded temperature, fan state, and thermostat state. Each thermostat has the ability to store a name for itself, so that’s in there too.

    But I wanted the ability to compare my data to outside temperature (ie, get a DeltaT) in order to see the outside temperature’s effect on the inside.  So, I looked around, and remembered some work I’d done with Weather Underground.  They have a free API that allows me up to 10 calls a minute!  I’d only use about 1 every 5 minutes.  So I signed up for that and read through the documentation and was able to get what I wanted and much, much more.  That API can be found here.

    My simple python script to grab this:

    #!usr/bin/env python

    import radiotherm
    #much thanks to Michael Hrivnak <mhrivnak@hrivnak.org> for his simple library!
    #i wrote a similar thing in java when i did this project version 1, this is way easier.
    #plus I learned mySQL, Python, php, and other stuff during this project. vs my old stupid method
    import MySQLdb
    import time
    import urllib2
    import json #jaaaaaaaaason

    #this small script grabs the temp for where the thermostats are located:raleigh, nc
    #weather underground key:131beb0f35b8df99
    #wunderground gives nice json! examples can be found on their website. most of this script is directly from their website.
    f = urllib2.urlopen('http://api.wunderground.com/api/******************/geolookup/conditions/q/NC/Raleigh.json')
    json_string = f.read()
    parsed_json = json.loads(json_string)
    temp_f = parsed_json['current_observation']['temp_f']
    f.close()

    #logging into the mysql server
    #the ol classic pw!
    db = MySQLdb.connect(host="localhost",
    user="monitor",
    passwd="*************",
    db="Temps")

    cur = db.cursor() #setting the cursor for the sql database

    #start to use this nice library.
    def getinfo(ip):
    tstat = radiotherm.get_thermostat(ip)
    #tstat.temp & dicts use dicts as output.

    temp = tstat.temp['raw'] #this grabs the raw value of temp from the therm and puts into a float
    FanState = tstat.fstate['raw'] #this grabs the raw value of fan on or off
    ThermState = tstat.tstate['raw'] #this grabs raw value of thermostat commanding cool, heat, off
    tname = tstat.name['raw'] #name of thermostat given by the radio thermostat company
    comm = tstat.t_cool['raw'] #commanded temp, not sure the difference b/w t_cool and it_cool
    return {'temp':temp, 'FanState':FanState ,'ThermState':ThermState,'ThermName':tname,'comm':comm}

    def writeinfo(dict):
    try:
    cur.execute("INSERT INTO tempdat VALUES (CURDATE(),NOW(),%s,%s,%s,%s,%s,%s)", (dict['ThermName'],dict['temp'],dict['ThermState'],dict['FanState'],temp_f,dict['comm'])

    db.commit()
    print "nData Committed!" , dict['ThermName']except:
    print "Error in committing, rolling back!"
    db.rollback()

    #while 1: #used to have it run in a while loop, cron is waaaaaaaay better.

    #these IPs are internal LAN addresses that won't change. I've set them up as static in my router.
    #The database entries will automatically know which is downstairs and upstairs
    writeinfo(getinfo('192.168.0.13'))
    writeinfo(getinfo('192.168.0.16'))

    #this was for tshooting/seeing the database grow, too big now! =P

    #cur.execute ("SELECT * FROM tempdat")

    #print "nDate Time Zone Temperature ThermState FanState Outside Commanded"
    #print "============================================================================================"

    #for reading in cur.fetchall():
    #print str(reading[0])+" "+str(reading[1])+" "+
    # reading[2]+" "+str(reading[3])+" "+str(reading[4])+" "+ str(reading[5])+" "+str(reading[6])+" "+str(reading[7])

    #time.sleep(300) #more for the old dumb while loop

    db.close()