def updateXively(): lprint ("Updating Xively ") sys.stdout.flush() # Currently I have to use UTC for the time, # there's a bug somewhere in the library or # Xively. It doesn't matter though because # it's easy to convert now = datetime.datetime.utcnow() # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Yes, there are better ways to do the stuff below, # but I wanted to use a single statement to get it # from the data base an update the field going to # Xively. It turns out that is is a rather odd # looking statement, but it works. # However, I noticed that fetchone() returns a tuple # with only one value in it (value,) which means # I have to get at it with a [0]. tmp = c.execute("select motor from pool").fetchone()[0]; if (tmp == 'High'): # a little special handling for the pool motor motor = 2 elif (tmp == 'Low'): motor = 1 else: motor = 0 feed.datastreams = [ xively.Datastream(id='outside_temp', current_value = c.execute( "select temperature from Barometer") .fetchone()[0], at=now), xively.Datastream(id='power_usage', current_value = c.execute( "select rpower from power") .fetchone()[0], at=now), xively.Datastream(id='voltage', current_value = c.execute( "select voltage from power") .fetchone()[0], at=now), xively.Datastream(id='apparent_power', current_value = c.execute( "select apower from power") .fetchone()[0], at=now), xively.Datastream(id='current', current_value = c.execute( "select current from power") .fetchone()[0], at=now), xively.Datastream(id='frequency', current_value = c.execute( "select frequency from power") .fetchone()[0], at=now), xively.Datastream(id='power_factor', current_value = c.execute( "select pfactor from power") .fetchone()[0], at=now), xively.Datastream(id='inside_temp', current_value = c.execute( "select avg(\"temp-reading\") from thermostats") .fetchone()[0], at=now), xively.Datastream(id='pool_motor', current_value = motor, at=now), xively.Datastream(id='pool_temp', current_value = c.execute( "select ptemp from pool") .fetchone()[0], at=now) ] try: feed.update() # and update Xively with the latest # update the time in the database c.execute("update xively set utime=?;",(dbTime(),)) dbconn.commit() dbconn.close() # close the data base except: lprint ("error: " + str(sys.exc_info()[0]))
def updateXively(): lprint("Updating Xively ") sys.stdout.flush() # Currently I have to use UTC for the time, # there's a bug somewhere in the library or # Xively. It doesn't matter though because # it's easy to convert now = datetime.datetime.utcnow() # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Yes, there are better ways to do the stuff below, # but I wanted to use a single statement to get it # from the data base an update the field going to # Xively. It turns out that is is a rather odd # looking statement, but it works. # However, I noticed that fetchone() returns a tuple # with only one value in it (value,) which means # I have to get at it with a [0]. tmp = c.execute("select motor from pool").fetchone()[0] if (tmp == 'High'): # a little special handling for the pool motor motor = 2 elif (tmp == 'Low'): motor = 1 else: motor = 0 feed.datastreams = [ xively.Datastream( id='outside_temp', current_value=c.execute( "select temperature from Barometer").fetchone()[0], at=now), xively.Datastream( id='power_usage', current_value=c.execute("select rpower from power").fetchone()[0], at=now), xively.Datastream( id='voltage', current_value=c.execute("select voltage from power").fetchone()[0], at=now), xively.Datastream( id='apparent_power', current_value=c.execute("select apower from power").fetchone()[0], at=now), xively.Datastream( id='current', current_value=c.execute("select current from power").fetchone()[0], at=now), xively.Datastream(id='frequency', current_value=c.execute( "select frequency from power").fetchone()[0], at=now), xively.Datastream( id='power_factor', current_value=c.execute("select pfactor from power").fetchone()[0], at=now), xively.Datastream( id='inside_temp', current_value=c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0], at=now), xively.Datastream(id='pool_motor', current_value=motor, at=now), xively.Datastream( id='pool_temp', current_value=c.execute("select ptemp from pool").fetchone()[0], at=now) ] try: feed.update() # and update Xively with the latest # update the time in the database c.execute("update xively set utime=?;", (dbTime(), )) dbconn.commit() dbconn.close() # close the data base except: lprint("error: " + str(sys.exc_info()[0]))
def updateGrovestreams(): # This is VERY different from their examples. I named # my streams with something I could understand and read # Probably not the best way to do it, but it works really # well for me. component_id = "desert-home-id" rpowerStream_id = "power_usage" otempStream_id = "outside_temp" apowerStream_id = "apparent_power" voltageStream_id = "voltage" currentStream_id = "current" pfactorStream_id = "power_factor" itempStream_id = "inside_temp" ptempStream_id = "pool_temp" pmotorStream_id = "pool_motor" frequencyStream_id = "frequency" # This object really helps when displaying # the rather complex data below pp = pprint.PrettyPrinter(depth=10) #get the millis since epoch # in unix the epoch began back in 1970, look it up now = datetime.now() nowEpoch = int(time.mktime(now.timetuple())) * 1000 #assemble feed and convert it to a JSON string feed = {}; feed['feed'] = {} feed['feed']['component'] = [] if DEBUG: pp.pprint(feed) print sys.stdout.flush() comp = {} comp['stream'] = [] comp['componentId'] = component_id feed['feed']['component'].append(comp) if DEBUG: pp.pprint(feed) print sys.stdout.flush() # Now I'm going to fill in the stream values, open database # I took a brute force approach to building the dictionary that # is converted into JSON. I could have been much more elegant # in building it, but the folks just starting out would have # had a tough time understanding it dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # So, you make a stream to stuff things into. It's actually # a python dictionary that we'll pass to a JSON encoder a ways # down into the code. I'll be adding entries to this as I pull # items out of the database stream1 = {} stream1['streamId'] = rpowerStream_id stream1['time'] = [] stream1['data'] = [] comp['stream'].append(stream1) current_value = c.execute("select rpower from power").fetchone()[0] stream1['time'].append(nowEpoch) stream1['data'].append(float(current_value)) # this is a cool way to debug this kind of thing. if DEBUG: pp.pprint(feed) print sys.stdout.flush() # notice how I get an item out of the database # and add it to the dictionary. I'll do this # several times stream2 = {} stream2['streamId'] = otempStream_id stream2['time'] = [] stream2['data'] = [] comp['stream'].append(stream2) current_value = c.execute( "select temperature from Barometer").fetchone()[0] stream2['time'].append(nowEpoch) stream2['data'].append(float(current_value)) stream3 = {} stream3['streamId'] = apowerStream_id stream3['time'] = [] stream3['data'] = [] comp['stream'].append(stream3) current_value = c.execute( "select apower from power").fetchone()[0] stream3['time'].append(nowEpoch) stream3['data'].append(float(current_value)) stream4 = {} stream4['streamId'] = voltageStream_id stream4['time'] = [] stream4['data'] = [] comp['stream'].append(stream4) current_value = c.execute( "select voltage from power").fetchone()[0] stream4['time'].append(nowEpoch) stream4['data'].append(float(current_value)) stream5 = {} stream5['streamId'] = currentStream_id stream5['time'] = [] stream5['data'] = [] comp['stream'].append(stream5) current_value = c.execute( "select current from power").fetchone()[0] stream5['time'].append(nowEpoch) stream5['data'].append(float(current_value)) stream6 = {} stream6['streamId'] = pfactorStream_id stream6['time'] = [] stream6['data'] = [] comp['stream'].append(stream6) current_value = c.execute( "select pfactor from power").fetchone()[0] stream6['time'].append(nowEpoch) stream6['data'].append(float(current_value)) stream7 = {} stream7['streamId'] = itempStream_id stream7['time'] = [] stream7['data'] = [] comp['stream'].append(stream7) current_value = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] stream7['time'].append(nowEpoch) stream7['data'].append(float(current_value)) stream8 = {} stream8['streamId'] = ptempStream_id stream8['time'] = [] stream8['data'] = [] comp['stream'].append(stream8) current_value = c.execute( "select ptemp from pool").fetchone()[0] stream8['time'].append(nowEpoch) stream8['data'].append(float(current_value)) stream9 = {} stream9['streamId'] = pmotorStream_id stream9['time'] = [] stream9['data'] = [] comp['stream'].append(stream9) tmp = c.execute("select motor from pool").fetchone()[0]; if (tmp == 'High'): # a little special handling for the pool motor motor = 2 elif (tmp == 'Low'): motor = 1 else: motor = 0 stream9['time'].append(nowEpoch) stream9['data'].append(int(motor)) stream10 = {} stream10['streamId'] = frequencyStream_id stream10['time'] = [] stream10['data'] = [] comp['stream'].append(stream10) current_value = c.execute( "select frequency from power").fetchone()[0] stream10['time'].append(nowEpoch) stream10['data'].append(float(current_value)) # all the values are filled in, close the database # update the time in the database c.execute("update grovestream set utime=?;",(dbTime(),)) dbconn.commit() dbconn.close() # close the data base # This will print the entire dictionary I just constructed # so you can see what is going on if DEBUG: pp.pprint(feed) print sys.stdout.flush() # exit() # I put this in for debugging. It exits before # the JSON string is constructed and sent off to grovestreams # Of course you want to keep it commented until needed # # And this is where the JSON string is built encoder = jsonEncoder.JSONEncoder() json = encoder.encode(feed); # and this will print it so you can see what is happening if DEBUG: print json # for debugging print sys.stdout.flush() #Upload the feed try: lprint ("Updating GroveStream") conn = httplib.HTTPConnection('www.grovestreams.com', timeout=10) url = '/api/feed?&org=%s&api_key=%s' % (org, api_key) compress = True if compress: body = compressBuf(json) headers = {"Content-type": "application/json", "Content-Encoding" : "gzip"} else: body = json headers = {"Content-type": "application/json", "charset":"UTF-8"} conn.request("PUT", url, body, headers) response = conn.getresponse() status = response.status if status != 200 and status != 201: try: if (response.reason != None): lprint('reason: ' + response.reason + ' body: ' + response.read()) else: lprint('body: ' + response.read()) except Exception: lprint('HTTP Fail Status: %d' % (status) ) return except Exception as e: lprint('HTTP Send Error: ' + str(e)) return finally: if conn != None: conn.close()
def lprint(text): print dbTime(), text sys.stdout.flush()
def updateThingSpeak(): lprint("Updating ThingSpeak ") # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Getting it out of the database a field at a time # is probably less efficient than getting the whole record, # but it works. # # On ThingSpeak I only update real power, power factor, voltage, # frequency, outside temperature and inside temperature # so I'm simply going to put the values in variables instead of # some complex (and probably faster) compound statement. outsideTemp = c.execute("select temperature from Barometer").fetchone()[0] # This a really cool thing about some languages # the variable types are dynamic, so I can just change it # from a string to a int on the fly. outsideTemp = int(float(outsideTemp) + .5) power = c.execute("select rpower from power").fetchone()[0] power = int(float(power) + .5) voltage = c.execute("select voltage from power").fetchone()[0] voltage = int(float(voltage) + .5) apparentPower = c.execute("select apower from power").fetchone()[0] apparentPower = float(apparentPower) current = c.execute("select current from power").fetchone()[0] current = int(float(current) + .5) frequency = c.execute("select frequency from power").fetchone()[0] frequency = float(frequency) powerFactor = c.execute("select pfactor from power").fetchone()[0] powerFactor = float(powerFactor) insideTemp = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] insideTemp = int(float(insideTemp) + .5) # OK, got all the stuff I want to update dbconn.close() # close the data base in case the HTTP update fails # # This is a debug statement that I put in to show # not only what the values were, but also how they # can be formatted. # print ("Power = %d \nVoltage = %d \nApparent Power = %d " # "\nCurrent = %d \nFrequency %.2f \nPower Factor = %.2f " # "\nOutside Temp = %d \nInside Temp = %d" % # (power, voltage, apparentPower, current, # frequency, powerFactor, outsideTemp, insideTemp)) # OK, now I've got all the data I want to record on ThingSpeak # So, I have to get involved with that thing called a REST interface # It's actually not too bad, it's just the way people pass # data to a web page, you see it all the time if you watch # how the URL on your browser changes. # # urlencode takes a python tuple as input, but I just create it # as a parameter so you can see what it really is. params = urllib.urlencode({ 'field1': power, 'field2': powerFactor, 'field3': voltage, 'field4': frequency, 'field5': insideTemp, 'field6': outsideTemp, 'key': thingSpeakKey }) # if you want to see the result of the url encode, just uncomment # the line below. This stuff gets confusing, so give it a try #print params # # Now, just send it off as a POST to ThingSpeak headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain" } try: # there are times that the internet times out on this kind of thing # this will just skip the update and show a message in the log conn = httplib.HTTPConnection("api.thingspeak.com:80", timeout=30) conn.request("POST", "/update", params, headers) except: lprint("error: " + str(sys.exc_info()[0])) return response = conn.getresponse() #print "Thingspeak Response:", response.status, response.reason # I only check for the 'OK' in the reason field. That's # so I can print a failure to any log file I happen to set # up. I don't want to print a lot of stuff that I have to # manage somehow. if (response.reason != 'OK'): lprint("Error, " + str(response.status) + " " + str(response.reason)) return # without updating the database conn.close # Now that everything worked, update the time in the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() c.execute("update thingspeak set utime=?;", (dbTime(), )) dbconn.commit() dbconn.close() # close the data base
def on_message(client, userdata, msg): print(dbTime()+' '+str(msg.payload)) sys.stdout.flush()
def on_message(client, userdata, msg): print(dbTime() + ' ' + str(msg.payload)) sys.stdout.flush()
def updateEmonCms(): lprint("Updating emoncms ") sys.stdout.flush() # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Getting it out of the database a field at a time # is probably less efficient than getting the whole record, # but it works. # # On emoncms I update real power, power factor, voltage, # frequency, outside temperature and inside temperature # so I'm simply going to put the values in variables instead of # some complex (and probably faster) compound statement. outsideTemp = c.execute("select temperature from Barometer").fetchone()[0] # This a really cool thing about some languages # the variable types are dynamic, so I can just change it # from a string to a int on the fly. outsideTemp = int(float(outsideTemp) + .5) power = c.execute("select rpower from power").fetchone()[0] power = int(float(power) + .5) voltage = c.execute("select voltage from power").fetchone()[0] voltage = int(float(voltage) + .5) apparentPower = c.execute("select apower from power").fetchone()[0] apparentPower = float(apparentPower) current = c.execute("select current from power").fetchone()[0] current = int(float(current) + .5) frequency = c.execute("select frequency from power").fetchone()[0] frequency = float(frequency) powerFactor = c.execute("select pfactor from power").fetchone()[0] powerFactor = float(powerFactor) insideTemp = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] insideTemp = int(float(insideTemp) + .5) # OK, got all the stuff I want to update dbconn.close() # close the data base in case the HTTP handoff fails # # This is a debug statement that I put in to show # not only what the values were, but also how they # can be formatted. # print ("Power = %d \nVoltage = %d \nApparent Power = %d " # "\nCurrent = %d \nFrequency %.2f \nPower Factor = %.2f " # "\nOutside Temp = %d \nInside Temp = %d" % # (power, voltage, apparentPower, current, # frequency, powerFactor, outsideTemp, insideTemp)) # OK, now I've got all the data I want to record on emoncms # so I have to put it in json form. json isn't that hard if you # don't have multiple levels, so I'll just do it with a string # format. It's just a set of ordered pairs for this. params = ( "RealPower:%d,PowerFactor:%.2f," "PowerVoltage:%d,PowerFrequency:%.2f," "InsideTemp:%d,OutsideTemp:%d" % (power, powerFactor, voltage, frequency, insideTemp, outsideTemp)) # if you want to see the result of the formatting, just uncomment # the line below. This stuff gets confusing, so give it a try #print params # # Now, just send it off to emoncms try: # I had to add the timeout parameter to allow for internet problems. conn = httplib.HTTPConnection("emoncms.org:80", timeout=45) request = "/input/post?apikey=" + EMONKEY + "&" + "json=" + params #print request # emoncms uses a GET not a POST conn.request("GET", request) except: lprint("error: " + str(sys.exc_info()[0])) return response = conn.getresponse() #print "emoncms Response:", response.status, response.reason # I only check for the 'OK' in the reason field. That's # so I can print a failure to any log file I happen to set # up. I don't want to print a lot of stuff that I have to # manage somehow. However, emoncms seldom returns an error, # I messed this interaction up a number of times and never got # an error. if (response.reason != 'OK'): lprint("error, " + str(response.status) + " " + str(response.reason)) return # without update to the database conn.close # Now that everything worked, update the time in the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() c.execute("update emoncms set utime=?;", (dbTime(), )) dbconn.commit() dbconn.close() # close the data base
def updateEmonCms(): lprint ("Updating emoncms ") sys.stdout.flush() # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Getting it out of the database a field at a time # is probably less efficient than getting the whole record, # but it works. # # On emoncms I update real power, power factor, voltage, # frequency, outside temperature and inside temperature # so I'm simply going to put the values in variables instead of # some complex (and probably faster) compound statement. outsideTemp = c.execute( "select temperature from Barometer").fetchone()[0] # This a really cool thing about some languages # the variable types are dynamic, so I can just change it # from a string to a int on the fly. outsideTemp = int(float(outsideTemp) +.5) power = c.execute( "select rpower from power").fetchone()[0] power = int(float(power)+.5) voltage = c.execute( "select voltage from power").fetchone()[0] voltage = int(float(voltage)+.5) apparentPower = c.execute( "select apower from power").fetchone()[0] apparentPower = float(apparentPower) current = c.execute( "select current from power").fetchone()[0] current = int(float(current)+.5) frequency = c.execute( "select frequency from power").fetchone()[0] frequency = float(frequency) powerFactor = c.execute( "select pfactor from power").fetchone()[0] powerFactor = float(powerFactor) insideTemp = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] insideTemp = int(float(insideTemp)+.5) # OK, got all the stuff I want to update dbconn.close() # close the data base in case the HTTP handoff fails # # This is a debug statement that I put in to show # not only what the values were, but also how they # can be formatted. # print ("Power = %d \nVoltage = %d \nApparent Power = %d " # "\nCurrent = %d \nFrequency %.2f \nPower Factor = %.2f " # "\nOutside Temp = %d \nInside Temp = %d" % # (power, voltage, apparentPower, current, # frequency, powerFactor, outsideTemp, insideTemp)) # OK, now I've got all the data I want to record on emoncms # so I have to put it in json form. json isn't that hard if you # don't have multiple levels, so I'll just do it with a string # format. It's just a set of ordered pairs for this. params = ("RealPower:%d,PowerFactor:%.2f," "PowerVoltage:%d,PowerFrequency:%.2f," "InsideTemp:%d,OutsideTemp:%d" % (power,powerFactor,voltage,frequency,insideTemp, outsideTemp)) # if you want to see the result of the formatting, just uncomment # the line below. This stuff gets confusing, so give it a try #print params # # Now, just send it off to emoncms try: # I had to add the timeout parameter to allow for internet problems. conn = httplib.HTTPConnection("emoncms.org:80", timeout=45) request = "/input/post?apikey=" + EMONKEY + "&" + "json=" + params #print request # emoncms uses a GET not a POST conn.request("GET", request) except: lprint ("error: " + str(sys.exc_info()[0])) return response = conn.getresponse() #print "emoncms Response:", response.status, response.reason # I only check for the 'OK' in the reason field. That's # so I can print a failure to any log file I happen to set # up. I don't want to print a lot of stuff that I have to # manage somehow. However, emoncms seldom returns an error, # I messed this interaction up a number of times and never got # an error. if (response.reason != 'OK'): lprint ("error, " + str(response.status) + " " + str(response.reason)) return # without update to the database conn.close # Now that everything worked, update the time in the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() c.execute("update emoncms set utime=?;",(dbTime(),)) dbconn.commit() dbconn.close() # close the data base
def updateGrovestreams(): # This is VERY different from their examples. I named # my streams with something I could understand and read # Probably not the best way to do it, but it works really # well for me. component_id = "desert-home-id" rpowerStream_id = "power_usage" otempStream_id = "outside_temp" apowerStream_id = "apparent_power" voltageStream_id = "voltage" currentStream_id = "current" pfactorStream_id = "power_factor" itempStream_id = "inside_temp" ptempStream_id = "pool_temp" pmotorStream_id = "pool_motor" frequencyStream_id = "frequency" # This object really helps when displaying # the rather complex data below pp = pprint.PrettyPrinter(depth=10) #get the millis since epoch # in unix the epoch began back in 1970, look it up now = datetime.now() nowEpoch = int(time.mktime(now.timetuple())) * 1000 #assemble feed and convert it to a JSON string feed = {} feed['feed'] = {} feed['feed']['component'] = [] if DEBUG: pp.pprint(feed) print sys.stdout.flush() comp = {} comp['stream'] = [] comp['componentId'] = component_id feed['feed']['component'].append(comp) if DEBUG: pp.pprint(feed) print sys.stdout.flush() # Now I'm going to fill in the stream values, open database # I took a brute force approach to building the dictionary that # is converted into JSON. I could have been much more elegant # in building it, but the folks just starting out would have # had a tough time understanding it dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # So, you make a stream to stuff things into. It's actually # a python dictionary that we'll pass to a JSON encoder a ways # down into the code. I'll be adding entries to this as I pull # items out of the database stream1 = {} stream1['streamId'] = rpowerStream_id stream1['time'] = [] stream1['data'] = [] comp['stream'].append(stream1) current_value = c.execute("select rpower from power").fetchone()[0] stream1['time'].append(nowEpoch) stream1['data'].append(float(current_value)) # this is a cool way to debug this kind of thing. if DEBUG: pp.pprint(feed) print sys.stdout.flush() # notice how I get an item out of the database # and add it to the dictionary. I'll do this # several times stream2 = {} stream2['streamId'] = otempStream_id stream2['time'] = [] stream2['data'] = [] comp['stream'].append(stream2) current_value = c.execute( "select temperature from Barometer").fetchone()[0] stream2['time'].append(nowEpoch) stream2['data'].append(float(current_value)) stream3 = {} stream3['streamId'] = apowerStream_id stream3['time'] = [] stream3['data'] = [] comp['stream'].append(stream3) current_value = c.execute("select apower from power").fetchone()[0] stream3['time'].append(nowEpoch) stream3['data'].append(float(current_value)) stream4 = {} stream4['streamId'] = voltageStream_id stream4['time'] = [] stream4['data'] = [] comp['stream'].append(stream4) current_value = c.execute("select voltage from power").fetchone()[0] stream4['time'].append(nowEpoch) stream4['data'].append(float(current_value)) stream5 = {} stream5['streamId'] = currentStream_id stream5['time'] = [] stream5['data'] = [] comp['stream'].append(stream5) current_value = c.execute("select current from power").fetchone()[0] stream5['time'].append(nowEpoch) stream5['data'].append(float(current_value)) stream6 = {} stream6['streamId'] = pfactorStream_id stream6['time'] = [] stream6['data'] = [] comp['stream'].append(stream6) current_value = c.execute("select pfactor from power").fetchone()[0] stream6['time'].append(nowEpoch) stream6['data'].append(float(current_value)) stream7 = {} stream7['streamId'] = itempStream_id stream7['time'] = [] stream7['data'] = [] comp['stream'].append(stream7) current_value = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] stream7['time'].append(nowEpoch) stream7['data'].append(float(current_value)) stream8 = {} stream8['streamId'] = ptempStream_id stream8['time'] = [] stream8['data'] = [] comp['stream'].append(stream8) current_value = c.execute("select ptemp from pool").fetchone()[0] stream8['time'].append(nowEpoch) stream8['data'].append(float(current_value)) stream9 = {} stream9['streamId'] = pmotorStream_id stream9['time'] = [] stream9['data'] = [] comp['stream'].append(stream9) tmp = c.execute("select motor from pool").fetchone()[0] if (tmp == 'High'): # a little special handling for the pool motor motor = 2 elif (tmp == 'Low'): motor = 1 else: motor = 0 stream9['time'].append(nowEpoch) stream9['data'].append(int(motor)) stream10 = {} stream10['streamId'] = frequencyStream_id stream10['time'] = [] stream10['data'] = [] comp['stream'].append(stream10) current_value = c.execute("select frequency from power").fetchone()[0] stream10['time'].append(nowEpoch) stream10['data'].append(float(current_value)) # all the values are filled in, close the database # update the time in the database c.execute("update grovestream set utime=?;", (dbTime(), )) dbconn.commit() dbconn.close() # close the data base # This will print the entire dictionary I just constructed # so you can see what is going on if DEBUG: pp.pprint(feed) print sys.stdout.flush() # exit() # I put this in for debugging. It exits before # the JSON string is constructed and sent off to grovestreams # Of course you want to keep it commented until needed # # And this is where the JSON string is built encoder = jsonEncoder.JSONEncoder() json = encoder.encode(feed) # and this will print it so you can see what is happening if DEBUG: print json # for debugging print sys.stdout.flush() #Upload the feed try: lprint("Updating GroveStream") conn = httplib.HTTPConnection('www.grovestreams.com', timeout=10) url = '/api/feed?&org=%s&api_key=%s' % (org, api_key) compress = True if compress: body = compressBuf(json) headers = { "Content-type": "application/json", "Content-Encoding": "gzip" } else: body = json headers = {"Content-type": "application/json", "charset": "UTF-8"} conn.request("PUT", url, body, headers) response = conn.getresponse() status = response.status if status != 200 and status != 201: try: if (response.reason != None): lprint('reason: ' + response.reason + ' body: ' + response.read()) else: lprint('body: ' + response.read()) except Exception: lprint('HTTP Fail Status: %d' % (status)) return except Exception as e: lprint('HTTP Send Error: ' + str(e)) return finally: if conn != None: conn.close()
def updateThingSpeak(): lprint ("Updating ThingSpeak ") # open the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() # Getting it out of the database a field at a time # is probably less efficient than getting the whole record, # but it works. # # On ThingSpeak I only update real power, power factor, voltage, # frequency, outside temperature and inside temperature # so I'm simply going to put the values in variables instead of # some complex (and probably faster) compound statement. outsideTemp = c.execute( "select temperature from Barometer").fetchone()[0] # This a really cool thing about some languages # the variable types are dynamic, so I can just change it # from a string to a int on the fly. outsideTemp = int(float(outsideTemp) +.5) power = c.execute( "select rpower from power").fetchone()[0] power = int(float(power)+.5) voltage = c.execute( "select voltage from power").fetchone()[0] voltage = int(float(voltage)+.5) apparentPower = c.execute( "select apower from power").fetchone()[0] apparentPower = float(apparentPower) current = c.execute( "select current from power").fetchone()[0] current = int(float(current)+.5) frequency = c.execute( "select frequency from power").fetchone()[0] frequency = float(frequency) powerFactor = c.execute( "select pfactor from power").fetchone()[0] powerFactor = float(powerFactor) insideTemp = c.execute( "select avg(\"temp-reading\") from thermostats").fetchone()[0] insideTemp = int(float(insideTemp)+.5) # OK, got all the stuff I want to update dbconn.close() # close the data base in case the HTTP update fails # # This is a debug statement that I put in to show # not only what the values were, but also how they # can be formatted. # print ("Power = %d \nVoltage = %d \nApparent Power = %d " # "\nCurrent = %d \nFrequency %.2f \nPower Factor = %.2f " # "\nOutside Temp = %d \nInside Temp = %d" % # (power, voltage, apparentPower, current, # frequency, powerFactor, outsideTemp, insideTemp)) # OK, now I've got all the data I want to record on ThingSpeak # So, I have to get involved with that thing called a REST interface # It's actually not too bad, it's just the way people pass # data to a web page, you see it all the time if you watch # how the URL on your browser changes. # # urlencode takes a python tuple as input, but I just create it # as a parameter so you can see what it really is. params = urllib.urlencode({'field1': power, 'field2':powerFactor, 'field3':voltage, 'field4':frequency, 'field5':insideTemp, 'field6':outsideTemp, 'key':thingSpeakKey}) # if you want to see the result of the url encode, just uncomment # the line below. This stuff gets confusing, so give it a try #print params # # Now, just send it off as a POST to ThingSpeak headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"} try: # there are times that the internet times out on this kind of thing # this will just skip the update and show a message in the log conn = httplib.HTTPConnection("api.thingspeak.com:80", timeout=30) conn.request("POST", "/update", params, headers) except: lprint ("error: " + str(sys.exc_info()[0])) return response = conn.getresponse() #print "Thingspeak Response:", response.status, response.reason # I only check for the 'OK' in the reason field. That's # so I can print a failure to any log file I happen to set # up. I don't want to print a lot of stuff that I have to # manage somehow. if (response.reason != 'OK'): lprint ("Error, " + str(response.status) + " " + str(response.reason)) return # without updating the database conn.close # Now that everything worked, update the time in the database dbconn = sqlite3.connect(DATABASE) c = dbconn.cursor() c.execute("update thingspeak set utime=?;",(dbTime(),)) dbconn.commit() dbconn.close() # close the data base
def lprint(text): print dbTime(),text sys.stdout.flush()