Last active
January 3, 2016 11:39
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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