Skip to content

Instantly share code, notes, and snippets.

@danlmarmot
Last active January 3, 2016 11:39
Show Gist options
  • Save danlmarmot/8458094 to your computer and use it in GitHub Desktop.
Save danlmarmot/8458094 to your computer and use it in GitHub Desktop.
Python script to read data from a Proliphix network thermostat's REST interface and store it in MongoDB. Handles initialization of Mongo collection if one doesn't exist.
#!/usr/bin/python
from pymongo import Connection
from collections import defaultdict
import os, sys, time
import pprint
import requests
import urllib
import re
try: import simplejson as json
except ImportError: import json
class settings(object): pass
settings.MONGO_CONN = 'single'
settings.MONGO_HOST = 'localhost'
settings.MONGO_PORT = 27017
settings.THERMO_DB = 'thermo'
settings.READINGS_COLL = 'readings'
settings.READINGS_COLL_SIZE = 1048576 # Max size, in bytes, of the MongoDB collection
settings.READINGS_COLL_MAX = 7500 # Max number of documents in the collection
settings.thermostatIP = '10.1.1.1'
settings.username = '<username>'
settings.password = '<password>'
def main():
mongoConn = None
try:
mongoConn = Connection(settings.MONGO_HOST, settings.MONGO_PORT)
except Exception, ConnectionError:
raise ConnectionError
thermoDB = mongoConn[settings.THERMO_DB]
collList=list(thermoDB.system.namespaces.find({"name": settings.THERMO_DB + "." + settings.READINGS_COLL}))
if len(collList) == 0:
thermoDB.create_collection(settings.READINGS_COLL, capped=True, size=1048576, max=200, autoIndexId=True)
readingsColl = thermoDB[settings.READINGS_COLL]
currentReadings = get_therm_temps(settings.thermostatIP,
settings.username,
settings.password,
remoteSensor1=True,
remoteSensor2=True)
currentReadings['timestamp'] = int(time.time())
try:
#print json.dumps(currentReadings, indent=4)
readingsColl.insert(currentReadings)
except Exception as e:
print "Exception thrown: " "%s" % (e.strerror,)
raise
finally:
mongoConn.close()
sys.exit(0)
def get_therm_temps(thermostatIP, username, password, remoteSensor1=False, remoteSensor2=False):
# Returns a dictionary
currentTemps = {}
# Build the query string
# OID 4.1.2 is the current state. States: 2=off, 3=heat, 6=cool
# OID 4.3.2.1 is the local sensor temp. Example reading: 721 = 72.1F
thermostatQueryDict = {}
thermostatQueryDict['OID4.1.2'] = ''
thermostatQueryDict['OID4.3.2.1'] = ''
if remoteSensor1:
thermostatQueryDict['OID4.3.2.2'] = ''
if remoteSensor2:
thermostatQueryDict['OID4.3.2.3'] = ''
thermostatURI = 'http://' + thermostatIP + '/get?' + urllib.urlencode(thermostatQueryDict)
try:
fullResponse = requests.get(thermostatURI, auth=(username, password))
thermResponse = fullResponse.content
except requests.ConnectionError, e:
print "Exception thrown: " "%s" % (e.strerror,)
sys.exit(1)
except requests.HTTPError, e:
print "Exception thrown: " "%s" % (e.strerror,)
sys.exit(1)
matchRE = 'OID4.1.2=(.+?)&'
match = re.search(matchRE,thermResponse)
if match:
currentTemps['thermMode'] = str(match.group(1))
currentTemps['inTemp'] = format_therm_temps('OID4.3.2.1=(.+?)&',thermResponse)
currentTemps['outTemp'] = format_therm_temps('OID4.3.2.2=(.+?)&',thermResponse)
currentTemps['kellerTemp'] = format_therm_temps('OID4.3.2.3=(.+?)&',thermResponse)
return currentTemps
def format_therm_temps(matchRE,thermData,format="float"):
match = re.search(matchRE,thermData)
if not match:
return
result = float(match.group(1)) / 10
if format == "float":
return result
else:
return str(result)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment