def handleBarometer(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData pressure = jData["Barometer"]["pressure"] temperature = jData["Barometer"]["temperature"] #print "Pressure is: " + pressure #print "Temperature is: " + temperature try: dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("insert into barometer (reading, utime)" "values(%s, %s);", (pressure, dbTimeStamp())) c.execute( "insert into ftemperature (reading, utime)" "values(%s, %s);", (temperature, dbTimeStamp())) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
def handleBarometer(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData pressure = jData["Barometer"]["pressure"] temperature = jData["Barometer"]["temperature"] #print "Pressure is: " + pressure #print "Temperature is: " + temperature try: dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("insert into barometer (reading, utime)" "values(%s, %s);", (pressure,dbTimeStamp())) c.execute("insert into ftemperature (reading, utime)" "values(%s, %s);", (temperature,dbTimeStamp())) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def recordInDatabase(): #lprint("Recording weather data") # First update the daily totals in the Weather dictionary getDailys() if ("default" in Weather.values()): lprint("Weather data not ready yet") lprint(Weather) return dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() try: c.execute( "insert into rtemperature (reading, utime)" "values(%s, %s);", (Weather["roofTemperature"], dbTimeStamp())) c.execute("insert into humidity (reading, utime)" "values(%s, %s);", (Weather["humidity"], dbTimeStamp())) c.execute( "insert into wind (speed, directionc, directiond, utime)" "values(%s,%s,%s,%s);", (Weather["windSpeed"], Weather["windDirectionC"], Weather["windDirectionD"], dbTimeStamp())) c.execute("insert into raincounter (reading, utime)" "values(%s, %s);", (Weather["rainCounter"], dbTimeStamp())) dbconn.commit() # just in case the code below fails # now adjust the daily mins and maxs # This record gets updated all day and a new one gets created # whenever a reading comes in after midnight. This means that # the cumulative number are held under midnight of the previous # day. This makes it a little confusing when calculating things # like rainfall because you get the record for yesterday to # represent the last reading of yesterday. As in max(today) - # yesterday will give you today's rainfall. c.execute( '''INSERT INTO daily (hightemp, lowtemp, windhigh, barometer, raincount, utime) VALUES (%s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE hightemp = values(hightemp), lowtemp = values(lowtemp), windhigh = values(windhigh), barometer = values(barometer), raincount = values(raincount); ''', ( Weather["maxTempToday"], Weather["minTempToday"], Weather["maxWindSpeedToday"], Weather["latestBarometric"], Weather["rainCounter"], midnight(), )) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
def recordInDatabase(): #lprint("Recording weather data") # First update the daily totals in the Weather dictionary getDailys() if ("default" in Weather.values()): lprint("Weather data not ready yet") lprint(Weather) return dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() try: c.execute("insert into rtemperature (reading, utime)" "values(%s, %s);", (Weather["roofTemperature"],dbTimeStamp())) c.execute("insert into humidity (reading, utime)" "values(%s, %s);", (Weather["humidity"],dbTimeStamp())) c.execute("insert into wind (speed, directionc, directiond, utime)" "values(%s,%s,%s,%s);", (Weather["windSpeed"], Weather["windDirectionC"], Weather["windDirectionD"], dbTimeStamp())) c.execute("insert into raincounter (reading, utime)" "values(%s, %s);", (Weather["rainCounter"],dbTimeStamp())) dbconn.commit() # just in case the code below fails # now adjust the daily mins and maxs # This record gets updated all day and a new one gets created # whenever a reading comes in after midnight. This means that # the cumulative number are held under midnight of the previous # day. This makes it a little confusing when calculating things # like rainfall because you get the record for yesterday to # represent the last reading of yesterday. As in max(today) - # yesterday will give you today's rainfall. c.execute('''INSERT INTO daily (hightemp, lowtemp, windhigh, barometer, raincount, utime) VALUES (%s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE hightemp = values(hightemp), lowtemp = values(lowtemp), windhigh = values(windhigh), barometer = values(barometer), raincount = values(raincount); ''', (Weather["maxTempToday"], Weather["minTempToday"], Weather["maxWindSpeedToday"], Weather["latestBarometric"], Weather["rainCounter"], midnight(),)) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def handleHouseFreezer(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData #print "temp : ", jData["housefreezer"]["temperature"] #print "defroster : ", jData["housefreezer"]["defroster"] #print "utime : ", jData["housefreezer"]["utime"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() whichone = dbTimeStamp() hc.execute("insert into housefreezer (temperature, defroster, utime)" "values(%s,%s,%s);", (jData["housefreezer"]["temperature"], jData["housefreezer"]["defroster"], whichone)) hc.execute("select watts from smartswitch where name = 'freezer';") watts = hc.fetchone()[0] hc.execute("update housefreezer set watts = %s" "where utime = %s;", (watts, whichone)); hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def updateDatabase(whichone, status, force=False): ''' This is running on a Pi and is not event driven, so polling like this will result in considerable wear to the SD card. So, I'm going to read the database to see if it needs to be changed before I change it. According to everything I've read, reads are free, it's the writes that eat up the card. ''' dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("select status from wemo where name = %s;", (whichone, )) oldstatus = c.fetchone() if oldstatus[0] != status or force == True: lprint("Had to update database %s, %s" % (whichone, status)) try: c.execute( "update wemo " "set status = %s, utime = %s where name = %s;", (status, dbTimeStamp(), whichone)) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
def handleWaterHeater(data): print "updating water heater in database" try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return print jData print "voltage : ", jData["WaterHeater"]["V"] print "current : ", jData["WaterHeater"]["I"] print "power : ", jData["WaterHeater"]["P"] print "energy : ", jData["WaterHeater"]["E"] print "top temp : ", jData["WaterHeater"]["TT"] print "bottom temp : ", jData["WaterHeater"]["BT"] print "power applied : ", jData["WaterHeater"]["PA"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() whichone = dbTimeStamp() hc.execute("insert into waterheater (voltage, current, power, energy,ttemp,btemp,waterh)" "values(%s,%s,%s,%s,%s,%s,%s);", (jData["WaterHeater"]["V"], jData["WaterHeater"]["I"], jData["WaterHeater"]["P"], jData["WaterHeater"]["E"], jData["WaterHeater"]["TT"], jData["WaterHeater"]["BT"], jData["WaterHeater"]["PA"] )) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def ThermostatStatus(): # The scheduler will run this as a separate thread # so I have to open and close the database within # this routine # print(time.strftime("%A, %B %d at %H:%M:%S")) # open the database and set up the cursor try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() for whichOne in ["North", "South"]: hc.execute("select address from thermostats " "where location=%s; ", (whichOne,)) thermoIp = hc.fetchone() try: status = getThermoStatus(thermoIp) except: break # print whichOne + " reports: " + str(status) hc.execute( "update thermostats set `temp-reading` = %s, " "status = %s, " "`s-temp` = %s, " "`s-mode` = %s, " "`s-fan` = %s, " "peak = %s," "utime = %s" "where location = %s;", (status[0], status[1], status[2], status[3], status[4], status[5], dbTimeStamp(), whichOne), ) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
def getDailys(): # get maxs, mins and such out of the database to pick # up where we left off in case of failure and restart. # Midnight yesterday is considered the first instant of today. m = midnight(1) # This time was recorded as the last reading yesterday n = dbTimeStamp() dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute \ ("select min(reading/1.0) from ftemperature where utime between %s and %s;", (m, n)) Weather["minTempToday"] = c.fetchone()[0] c.execute \ ("select max(reading/1.0) from ftemperature where utime between %s and %s;", (m, n)) Weather["maxTempToday"] = c.fetchone()[0] c.execute \ ("select max(speed/1.0) from wind where utime between %s and %s;", (m, n)) Weather["maxWindSpeedToday"] = c.fetchone()[0] c.execute \ ("SELECT reading FROM barometer ORDER BY utime DESC LIMIT 1;") Weather["latestBarometric"] = c.fetchone()[0] dbconn.close()
def handleGarage(data): #print("Got Garage") #print(data) # This is not JSON, it's a comma separated list rxList = data.split(',') if rxList[0] != 'Garage': logIt("published as Garage, but found {}".format(rxList[0])) if len(rxList) > 2: #this means it's a status from the garage # not a command to the garage #print "updating garage in database" # Now stick it in the database try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute( "update garage set door1 = %s, " "door2 = %s," "waterh = %s," "utime = %s;", (rxList[1], rxList[2], rxList[3].rstrip(), dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close()
def handleTempSensor(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData #print "name : ", jData["TempSensor"]["name"] #print "command : ", jData["TempSensor"]["command"] #print "processor V: ", jData["TempSensor"]["voltage"] #print "room T : ", jData["TempSensor"]["temperature"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() lprint("recording tempsensor ", jData['TempSensor']['name']) hc.execute( "insert into tempsensor(name," "pvolt, temp, utime)" "values (%s, %s, %s, %s);", (jData["TempSensor"]["name"], jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp())) hdbconn.commit() hdbconn.close() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close()
def handleGarage(data): #print("Got Garage") #print(data) # This is not JSON, it's a comma separated list rxList = data.split(',') if rxList[0] != 'Garage': logIt("published as Garage, but found {}".format(rxList[0])) if len(rxList) > 2: #this means it's a status from the garage # not a command to the garage #print "updating garage in database" # Now stick it in the database try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() # hc.execute("update garage set door1 = %s, " # "door2 = %s," # "waterh = %s," # "utime = %s;", # (rxList[1], rxList[2],rxList[3].rstrip(), # dbTimeStamp())) hc.execute("insert into garage (door1, door2, waterh, utime)" "values(%s, %s, %s, %s);", (rxList[1], rxList[2], rxList[3].rstrip(), dbTimeStamp() )) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) hdbconn.close()
def handleHouseFreezer(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData #print "temp : ", jData["housefreezer"]["temperature"] #print "defroster : ", jData["housefreezer"]["defroster"] #print "utime : ", jData["housefreezer"]["utime"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() whichone = dbTimeStamp() hc.execute( "insert into housefreezer (temperature, defroster, utime)" "values(%s,%s,%s);", (jData["housefreezer"]["temperature"], jData["housefreezer"]["defroster"], whichone)) hc.execute("select watts from smartswitch where name = 'freezer';") watts = hc.fetchone()[0] hc.execute("update housefreezer set watts = %s" "where utime = %s;", (watts, whichone)) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
def handleTempSensor(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData #print "name : ", jData["TempSensor"]["name"] #print "command : ", jData["TempSensor"]["command"] #print "processor V: ", jData["TempSensor"]["voltage"] #print "room T : ", jData["TempSensor"]["temperature"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() #lprint ("recording tempsensor ", jData['TempSensor']['name']) hc.execute("insert into tempsensor(name," "pvolt, temp, utime)" "values (%s, %s, %s, %s);", (jData["TempSensor"]["name"], jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp())) hdbconn.commit() hdbconn.close() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) hdbconn.close()
def handleTempSensor(data): try: jData = json.loads(data) except ValueError as err: lprint(err) lprint("The buffer:") lprint(str(msg.payload)) return #print jData #print "name : ", jData["TempSensor"]["name"] #print "command : ", jData["TempSensor"]["command"] #print "processor V: ", jData["TempSensor"]["voltage"] #print "room T : ", jData["TempSensor"]["temperature"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("select count(*) from tempsensor where name = %s;", (jData['TempSensor']['name'],)) count = hc.fetchone()[0] if count == 0: lprint ("Adding new tempSensor") hc.execute("insert into tempsensor(name," "pvolt, temp, utime)" "values (%s, %s, %s, %s);", (jData["TempSensor"]["name"], jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp())) else: #lprint ("updating tempsensor ", jData['TempSensor']['name']) hc.execute("update tempsensor set " "pvolt = %s," "temp = %s," "utime = %s where name = %s ;", (jData['TempSensor']['voltage'], jData['TempSensor']['temperature'], dbTimeStamp(), jData['TempSensor']['name'] )) hdbconn.commit() hdbconn.close() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) hdbconn.close()
def specialTempSensor(hc): # get the time out of the database timeString = hc.execute( "select utime from tempsensor where name = 'Temp1'") timeString = hc.fetchone()[0] # convert the string into seconds then = long(timeString) # get the local time now = long(dbTimeStamp()) # I can finally make the comparison if (now - then > 5 * 60): return 0 hc.execute("select pvolt from tempsensor where name = 'Temp1'") return hc.fetchone()[0]
def updatePower(): #print ('rpower %s, apower %s, pfactor %s, voltage %s, current %s, frequency %s' # %(rpower, apower, pfactor, voltage, current, frequency)) #print "updating power in database" try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("insert into power (rpower, apower, pfactor, voltage, current, frequency, utime)" "values(%s,%s,%s,%s,%s,%s,%s);", (rpower, apower, pfactor, voltage, current, frequency, dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def specialTempSensor(hc): # get the time out of the database timeString = hc.execute( "select utime from tempsensor where name = 'Temp1'") timeString = hc.fetchone()[0] # convert the string into seconds then = long(timeString) # get the local time now = long(dbTimeStamp()) # I can finally make the comparison if ( now - then > 5*60): return 0 hc.execute( "select pvolt from tempsensor where name = 'Temp1'") return hc.fetchone()[0]
def updateDatabase(whichone, status, force=False): ''' This is running on a Pi and is not event driven, so polling like this will result in considerable wear to the SD card. So, I'm going to read the database to see if it needs to be changed before I change it. According to everything I've read, reads are free, it's the writes that eat up the card. ''' dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("select status from wemo where name = %s;", (whichone,)) oldstatus = c.fetchone() if oldstatus[0] != status or force == True: lprint ("Had to update database %s, %s"%(whichone, status)) try: c.execute("update wemo " "set status = %s, utime = %s where name = %s;", (status, dbTimeStamp(), whichone)) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))
def ThermostatStatus(): # The scheduler will run this as a separate thread # so I have to open and close the database within # this routine #print(time.strftime("%A, %B %d at %H:%M:%S")) # open the database and set up the cursor try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() for whichOne in ['North', 'South']: hc.execute( "select address from thermostats " "where location=%s; ", (whichOne, )) thermoIp = hc.fetchone() try: status = getThermoStatus(thermoIp) except: break #print whichOne + " reports: " + str(status) hc.execute( "update thermostats set `temp-reading` = %s, " "status = %s, " "`s-temp` = %s, " "`s-mode` = %s, " "`s-fan` = %s, " "peak = %s," "utime = %s" "where location = %s;", (status[0], status[1], status[2], status[3], status[4], status[5], dbTimeStamp(), whichOne)) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1]))
"where longaddress = %s; ", addrToString(data['source_addr_long']), ) switchrecord = c.fetchone() if switchrecord is not None: lprint("Device %s is rejoining the network" % (switchrecord[0])) else: lprint("Adding new device") c.execute( "insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" "values (%s, %s, %s, %s, %s, %s, %s);", ('unknown', addrToString(data['source_addr_long']), addrToString(data['source_addr']), 'unknown', '0', '0', dbTimeStamp())) dbconn.commit() except mdb.Error, e: print("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() elif (clusterId == 0x0500): # This is the security cluster showClusterData(data['source_addr_long'], data['source_addr'], clusterId, data['rf_data']) # When the switch first connects, it come up in a state that needs # initialization, this command seems to take care of that. # So, look at the value of the data and send the command. if data['rf_data'][3:7] == '\x15\x00\x39\x10': print "sending initialization" zb.send('tx_explicit', dest_addr_long=data['source_addr_long'],
def messageReceived(data): #print 'gotta packet' #print data clusterId = (ord(data['cluster'][0])*256) + ord(data['cluster'][1]) #print 'Cluster ID:', hex(clusterId), if (clusterId == 0x13): # This is the device announce message. # due to timing problems with the switch itself, I don't # respond to this message, I save the response for later after the # Match Descriptor request comes in. You'll see it down below. # if you want to see the data that came in with this message, just # uncomment the 'print data' comment up above print 'Device Announce Message' elif (clusterId == 0x8005): # this is the Active Endpoint Response This message tells you # what the device can do, but it isn't constructed correctly to match # what the switch can do according to the spec. This is another # message that gets it's response after I receive the Match Descriptor print 'Active Endpoint Response' elif (clusterId == 0x0006): # Match Descriptor Request; this is the point where I finally # respond to the switch. Several messages are sent to cause the # switch to join with the controller at a network level and to cause # it to regard this controller as valid. # # First the Active Endpoint Request payload1 = '\x00\x00' zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x00', cluster = '\x00\x05', profile = '\x00\x00', data = payload1 ) print 'sent Active Endpoint' # Now the Match Descriptor Response payload2 = '\x00\x00\x00\x00\x01\x02' zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x00', cluster = '\x80\x06', profile = '\x00\x00', data = payload2 ) print 'Sent Match Descriptor' # Now there are two messages directed at the hardware # code (rather than the network code. The switch has to # receive both of these to stay joined. payload3 = '\x11\x01\x01' zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x02', cluster = '\x00\xf6', profile = '\xc2\x16', data = payload2 ) payload4 = '\x19\x01\xfa\x00\x01' zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x02', cluster = '\x00\xf0', profile = '\xc2\x16', data = payload4 ) print 'Sent hardware join messages' # now that it should have joined, I'll add a record to the database to # hold the status. I'll just name the device 'unknown' so it can # be updated by hand using sqlite3 directly. If the device already exists, # I'll leave the name alone and just use the existing record # Yes, this means you'll have to go into the database and assign it a name # dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() try: # See if the device is already in the database # if not, add a record with the name 'unknown', # then go correct the name using the human interface # to sqlite3 c.execute("select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']),)) switchrecord = c.fetchone() if switchrecord is not None: lprint ("Device %s is rejoining the network" %(switchrecord[0])) else: lprint ("Adding new device") c.execute("insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" "values (%s, %s, %s, %s, %s, %s, %s);", ('unknown', addrToString(data['source_addr_long']), addrToString(data['source_addr']), 'unknown', '0', '0', dbTimeStamp())) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close()
c = dbconn.cursor() # get device name from database try: c.execute( "select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']), )) name = c.fetchone()[0].capitalize() #lprint ("%s Instaneous Power, %d Watts" %(name, usage)) # do database updates c.execute( "update smartswitch " "set watts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString(data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() elif (clusterCmd == 0x82): usage = (ord(data['rf_data'][3]) + (ord(data['rf_data'][4]) * 256) + (ord(data['rf_data'][5]) * 256 * 256) + (ord(data['rf_data'][6]) * 256 * 256 * 256)) upTime = (ord(data['rf_data'][7]) + (ord(data['rf_data'][8]) * 256) + (ord(data['rf_data'][9]) * 256 * 256) + (ord(data['rf_data'][10]) * 256 * 256 * 256)) dbconn = mdb.connect(host=dbHost,
try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute( "update pool set motor = %s, " "waterfall = %s," "light = %s," "fountain = %s," "solar = %s," "ptemp = %s," "atemp = %s," "utime = %s;", (motor, waterfall, light, fountain, solar, ptemp, atemp, dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close() elif rxList[0] == 'Septic': #print("Got Septic Packet") #print(rxList) try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("update septic set level = %s, utime = %s;", (rxList[1].rstrip(), dbTimeStamp()))
id='14', current_value=getIt( wc, "select reading from barometer order by rdate desc limit 1"), at=now), xively.Datastream( id='15', current_value=getIt( hc, "select temp from tempsensor where name = 'Temp1'"), at=now), xively.Datastream(id='16', current_value=specialTempSensor(hc), at=now) ] try: # update the time in the database feed.update() # and update Xively with the latest hc.execute("update oldxively set utime=%s;", (dbTimeStamp(), )) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() # close the data base except: lprint("error: " + str(sys.exc_info()[0])) wdbconn.close() hdbconn.close() if __name__ == "__main__": lprint("started") logging.basicConfig() # get the values I need from the rc file
def handleMessage(data): try: #print 'gotta packet' #showData(data) if (data['id'] == 'rx_explicit'): #print "RX Explicit" #showData(data) clusterId = (ord(data['cluster'][0])*256) + ord(data['cluster'][1]) #print 'Cluster ID:', hex(clusterId), if (data['profile']=='\x00\x00'): # The General Profile print 'Cluster ID:', hex(clusterId), print "profile id:", repr(data['profile']) if (clusterId == 0x0000): print ("Network (16-bit) Address Request") #showData(data) elif (clusterId == 0x0004): # Simple Descriptor Request, print("Simple Descriptor Request") #showData(data) elif (clusterId == 0x0005): # Active Endpoint Request, print("Active Endpoint Request") #showData(data) elif (clusterId == 0x0006): print "Match Descriptor Request" #showData(data) time.sleep(2) print "Sending match descriptor response" zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x00', cluster = '\x80\x06', profile = '\x00\x00', options = '\x01', data = '\x04\x00\x00\x00\x01\x02' ) # The contact switch is a bit slow, give it # some time to digest the messages. time.sleep(2) zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x02', dest_endpoint = '\x02', cluster = '\x00\xf6', profile = '\xc2\x16', data = '\x11\x01\xfc' ) time.sleep(2) elif (clusterId == 0x0008): # I couldn't find a definition for this print("This was probably sent to the wrong profile") elif (clusterId == 0x13): # This is the device announce message. print 'Device Announce Message' # this will tell me the address of the new thing # so I'm going to send an active endpoint request print 'Sending active endpoint request' epc = '\xaa'+data['source_addr'][1]+data['source_addr'][0] print "".join("%02x " % ord(b) for b in epc) zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = '\x00', dest_endpoint = '\x00', cluster = '\x00\x05', profile = '\x00\x00', options = '\x01', data = epc ) elif (clusterId == 0x8000): print("Network (16-bit) Address Response") #showData(data) elif (clusterId == 0x8005): # this is the Active Endpoint Response This message tells you # what the device can do, but it isn't constructed correctly to match # what the switch can do according to the spec. This is another # message that gets it's response after I receive the Match Descriptor print 'Active Endpoint Response' # elif (clusterId == 0x0006): # # Match Descriptor Request; this is the point where I finally # # respond to the switch. Several messages are sent to cause the # # switch to join with the controller at a network level and to cause # # it to regard this controller as valid. # # # # First the Active Endpoint Request # payload1 = '\x00\x00' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x00', # cluster = '\x00\x05', # profile = '\x00\x00', # data = payload1 # ) # print 'sent Active Endpoint' # # Now the Match Descriptor Response # payload2 = '\x00\x00\x00\x00\x01\x02' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x00', # cluster = '\x80\x06', # profile = '\x00\x00', # data = payload2 # ) # print 'Sent Match Descriptor' # # Now there are two messages directed at the hardware # # code (rather than the network code. The switch has to # # receive both of these to stay joined. # payload3 = '\x11\x01\x01' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x02', # cluster = '\x00\xf6', # profile = '\xc2\x16', # data = payload2 # ) # payload4 = '\x19\x01\xfa\x00\x01' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x02', # cluster = '\x00\xf0', # profile = '\xc2\x16', # data = payload4 # ) # print 'Sent hardware join messages' # # now that it should have joined, I'll add a record to the database to # # hold the status. I'll just name the device 'unknown' so it can # # be updated by hand using sqlite3 directly. If the device already exists, # # I'll leave the name alone and just use the existing record # # Yes, this means you'll have to go into the database and assign it a name # # # dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, # db=dbName) # c = dbconn.cursor() # try: # # See if the device is already in the database # # if not, add a record with the name 'unknown', # # then go correct the name using the human interface # # to sqlite3 # c.execute("select name from smartswitch " # "where longaddress = %s; ", # (addrToString(data['source_addr_long']),)) # switchrecord = c.fetchone() # if switchrecord is not None: # lprint ("Device %s is rejoining the network" %(switchrecord[0])) # else: # lprint ("Adding new device") # c.execute("insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" # "values (%s, %s, %s, %s, %s, %s, %s);", # ('unknown', # addrToString(data['source_addr_long']), # addrToString(data['source_addr']), # 'unknown', # '0', # '0', # dbTimeStamp())) # dbconn.commit() # except mdb.Error, e: # lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) # dbconn.close() elif (clusterId == 0x8038): print("Management Network Update Request"); else: lprint ("Unimplemented Cluster ID", hex(clusterId)) print elif (data['profile']=='\xc2\x16'): # Alertme Specific if (clusterId == 0xee): clusterCmd = ord(data['rf_data'][2]) status = '' if (clusterCmd == 0x80): if (ord(data['rf_data'][3]) & 0x01): status = "ON" else: status = "OFF" dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']),)) #print c.fetchone()[0].capitalize(), #print "Switch is", status try: c.execute("update smartswitch " "set status = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (status, addrToString(data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() elif (clusterId == 0xef): clusterCmd = ord(data['rf_data'][2]) status = data['rf_data'] # cut down on typing if (clusterCmd == 0x81): usage = unpack('<H', status[3:5])[0] dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() # get device name from database try: c.execute("select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']),)) name = c.fetchone()[0].capitalize() #lprint ("%s Instaneous Power, %d Watts" %(name, usage)) # do database updates c.execute("update smartswitch " "set watts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString(data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() elif (clusterCmd == 0x82): usage = unpack('<L', status[3:7])[0] / 3600 upTime = unpack('<L', status[7:11])[0] dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute("select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']),)) name = c.fetchone()[0].capitalize() #lprint ("%s Minute Stats: Usage, %d Watt Hours; Uptime, %d Seconds" %(name, usage/3600, upTime)) # update database stuff try: c.execute("update smartswitch " "set twatts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString(data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() elif (clusterId == 0xf0): showClusterData(data['source_addr_long'],data['source_addr'],clusterId,data['rf_data']) # If the cluster cmd byte is 'xfb', it's a status if data['rf_data'][2] == '\xfb': status = data['rf_data'] # just to make typing easier if status[3] == '\x1f': print " Door Sensor", print str(float(unpack("<h", status[8:10])[0])\ / 100.0 * 1.8 + 32) + "F", if ord(status[-1]) & 0x01 == 1: print "reed switch open", else: print "reed switch closed", if ord(status[-1]) & 0x02 == 0: print "tamper switch open", else: print "tamper switch closed", elif status[3] == '\x1c': # Never found anything useful in this print "Power Switch", elif status[3] == '\x1d': print " Key Fob", print str(float(unpack("<h", status[8:10])[0])\ / 100.0 * 1.8 + 32) + "F", unpack('<I',status[4:8])[0] print 'Counter', unpack('<I',status[4:8])[0], elif status[3] == '\x1e': # This indicates a door sensor # with an invalid temperature reading # the other items are OK print " Door Sensor", print "Temperature invalid", if ord(status[-1]) & 0x01 == 1: print "reed switch open", else: print "reed switch closed", if ord(status[-1]) & 0x02 == 0: print "tamper switch open", else: print "tamper switch closed", #This may be the missing link to this thing print 'sending missing link', zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = data['dest_endpoint'], dest_endpoint = data['source_endpoint'], cluster = '\x00\xf0', profile = '\xc2\x16', data = '\x11\x39\xfd' ) pass else: print " Don't know this device yet", print '' pass
elif rxList[0] == "Time": # print("Got Time Packet") pass elif rxList[0] == "Garage": # print("Got Garage Packet") # print(rxList) if len(rxList) > 2: # this means it's a status from the garage # not a command to the garage # print "updating garage in database" # Now stick it in the database try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute( "update garage set door1 = %s, " "door2 = %s," "waterh = %s," "utime = %s;", (rxList[1], rxList[2], rxList[3].rstrip(), dbTimeStamp()), ) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close() elif rxList[0] == "Pool": # print("Got Pool Packet") # print(rxList) motor = rxList[1].split(" ")[1] waterfall = rxList[2].split(" ")[1] light = rxList[3].split(" ")[1] fountain = rxList[4].split(" ")[1] solar = rxList[5].split(" ")[1] ptemp = rxList[6].split(" ")[1] atemp = rxList[7].split(" ")[1]
def handlePacket(data): global CurrentPower, DayMaxPower, DayMinPower global CurrentOutTemp, DayOutMaxTemp, DayOutMinTemp # print data # for debugging so you can see things # this packet is returned every time you do a transmit # (can be configured out), to tell you that the XBee # actually send the darn thing if data["id"] == "tx_status": if ord(data["deliver_status"]) != 0: print "Transmit error = ", print data["deliver_status"].encode("hex") print data # The receive packet is the workhorse, all the good stuff # happens with this packet. elif data["id"] == "rx": # First, try for the new JSON format from the # device. I'm converting them one at a time # to send JSON strings to the house controller try: jData = json.loads(data["rf_data"][:-1]) if "TempSensor" in jData.keys(): # print jData # print "name : ", jData["TempSensor"]["name"] # print "command : ", jData["TempSensor"]["command"] # print "processor V: ", jData["TempSensor"]["voltage"] # print "room T : ", jData["TempSensor"]["temperature"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("select count(*) from tempsensor where name = %s;", (jData["TempSensor"]["name"],)) count = hc.fetchone()[0] if count == 0: lprint("Adding new tempSensor") hc.execute( "insert into tempsensor(name," "pvolt, temp, utime)" "values (%s, %s, %s, %s);", ( jData["TempSensor"]["name"], jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp(), ), ) else: # lprint ("updating tempsensor ", jData['TempSensor']['name']) hc.execute( "update tempsensor set " "pvolt = %s," "temp = %s," "utime = %s where name = %s ;", ( jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp(), jData["TempSensor"]["name"], ), ) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close() if jData["TempSensor"]["command"] != "nothing": # got a command from the sensor talkHTML(irisControl, "command?whichone=monitor&what=toggle") if "Barometer" in jData.keys(): # print jData # Get the time sent with the readings and # adjust it since I send local time around the house # for ease of conversion on the Arduinos # lprint ("Barometric Pressure is", jData['Barometer']['pressure'], # "Temperature is", jData['Barometer']['temperature'], # "Recorded Time is", jData['Barometer']['utime'], # "Which should be converted to",dbTime(jData['Barometer']['utime'])) # do database stuff try: wdbconn = mdb.connect(host=wdbHost, user=wdbUser, passwd=wdbPassword, db=wdbName) wc = wdbconn.cursor() wc.execute( "insert into barometer (reading, utime)" "values(%s, %s);", (jData["Barometer"]["pressure"], jData["Barometer"]["utime"]), ) wc.execute( "insert into ftemperature (reading, utime)" "values(%s, %s);", (jData["Barometer"]["temperature"], jData["Barometer"]["utime"]), ) wdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) wdbconn.close()
def handlePacket(data): global CurrentPower, DayMaxPower, DayMinPower global CurrentOutTemp, DayOutMaxTemp, DayOutMinTemp #print data # for debugging so you can see things # this packet is returned every time you do a transmit # (can be configured out), to tell you that the XBee # actually send the darn thing if data['id'] == 'tx_status': if ord(data['deliver_status']) != 0: print 'Transmit error = ', print data['deliver_status'].encode('hex') print data # The receive packet is the workhorse, all the good stuff # happens with this packet. elif data['id'] == 'rx': # First, try for the new JSON format from the # device. I'm converting them one at a time # to send JSON strings to the house controller try: jData = json.loads(data['rf_data'][:-1]) if "TempSensor" in jData.keys(): #print jData #print "name : ", jData["TempSensor"]["name"] #print "command : ", jData["TempSensor"]["command"] #print "processor V: ", jData["TempSensor"]["voltage"] #print "room T : ", jData["TempSensor"]["temperature"] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute( "select count(*) from tempsensor where name = %s;", (jData['TempSensor']['name'], )) count = hc.fetchone()[0] if count == 0: lprint("Adding new tempSensor") hc.execute( "insert into tempsensor(name," "pvolt, temp, utime)" "values (%s, %s, %s, %s);", (jData["TempSensor"]["name"], jData["TempSensor"]["voltage"], jData["TempSensor"]["temperature"], dbTimeStamp())) else: #lprint ("updating tempsensor ", jData['TempSensor']['name']) hc.execute( "update tempsensor set " "pvolt = %s," "temp = %s," "utime = %s where name = %s ;", (jData['TempSensor']['voltage'], jData['TempSensor']['temperature'], dbTimeStamp(), jData['TempSensor']['name'])) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close() if (jData['TempSensor']['command'] != 'nothing'): #got a command from the sensor talkHTML(irisControl, "command?whichone=monitor&what=toggle") if "Barometer" in jData.keys(): #print jData # Get the time sent with the readings and # adjust it since I send local time around the house # for ease of conversion on the Arduinos #lprint ("Barometric Pressure is", jData['Barometer']['pressure'], # "Temperature is", jData['Barometer']['temperature'], # "Recorded Time is", jData['Barometer']['utime'], # "Which should be converted to",dbTime(jData['Barometer']['utime'])) # do database stuff try: wdbconn = mdb.connect(host=wdbHost, user=wdbUser, passwd=wdbPassword, db=wdbName) wc = wdbconn.cursor() wc.execute( "insert into barometer (reading, utime)" "values(%s, %s);", (jData["Barometer"]["pressure"], jData["Barometer"]["utime"])) wc.execute( "insert into ftemperature (reading, utime)" "values(%s, %s);", (jData["Barometer"]["temperature"], jData["Barometer"]["utime"])) wdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) wdbconn.close()
# not a command to the garage #print "updating garage in database" # Now stick it in the database try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute( "update garage set door1 = %s, " "door2 = %s," "waterh = %s," "utime = %s;", (rxList[1], rxList[2], rxList[3].rstrip(), dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) hdbconn.close() elif rxList[0] == 'Pool': #print("Got Pool Packet") #print(rxList) motor = rxList[1].split(' ')[1] waterfall = rxList[2].split(' ')[1] light = rxList[3].split(' ')[1] fountain = rxList[4].split(' ')[1] solar = rxList[5].split(' ')[1] ptemp = rxList[6].split(' ')[1] atemp = rxList[7].split(' ')[1]
at=now), xively.Datastream(id='14', current_value = getIt(wc,"select reading from barometer order by rdate desc limit 1"), at=now), xively.Datastream(id='15', current_value = getIt(hc, "select temp from tempsensor where name = 'Temp1'"), at=now), xively.Datastream(id='16', current_value = specialTempSensor(hc), at=now) ] try: # update the time in the database feed.update() # and update Xively with the latest hc.execute("update oldxively set utime=%s;",(dbTimeStamp(),)) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() # close the data base except: lprint ("error: " + str(sys.exc_info()[0])) wdbconn.close() hdbconn.close() if __name__ == "__main__": lprint ("started") logging.basicConfig() # get the values I need from the rc file
def handleMessage(data): try: #print 'gotta packet' #showData(data) if (data['id'] == 'rx_explicit'): #print "RX Explicit" #showData(data) clusterId = (ord(data['cluster'][0]) * 256) + ord( data['cluster'][1]) #print 'Cluster ID:', hex(clusterId), if (data['profile'] == '\x00\x00'): # The General Profile print 'Cluster ID:', hex(clusterId), print "profile id:", repr(data['profile']) if (clusterId == 0x0000): print("Network (16-bit) Address Request") #showData(data) elif (clusterId == 0x0004): # Simple Descriptor Request, print("Simple Descriptor Request") #showData(data) elif (clusterId == 0x0005): # Active Endpoint Request, print("Active Endpoint Request") #showData(data) elif (clusterId == 0x0006): print "Match Descriptor Request" #showData(data) time.sleep(2) print "Sending match descriptor response" zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x00', cluster='\x80\x06', profile='\x00\x00', options='\x01', data='\x04\x00\x00\x00\x01\x02') # The contact switch is a bit slow, give it # some time to digest the messages. time.sleep(2) zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x02', dest_endpoint='\x02', cluster='\x00\xf6', profile='\xc2\x16', data='\x11\x01\xfc') time.sleep(2) elif (clusterId == 0x0008): # I couldn't find a definition for this print("This was probably sent to the wrong profile") elif (clusterId == 0x13): # This is the device announce message. print 'Device Announce Message' # this will tell me the address of the new thing # so I'm going to send an active endpoint request print 'Sending active endpoint request' epc = '\xaa' + data['source_addr'][1] + data[ 'source_addr'][0] print "".join("%02x " % ord(b) for b in epc) zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x00', cluster='\x00\x05', profile='\x00\x00', options='\x01', data=epc) elif (clusterId == 0x8000): print("Network (16-bit) Address Response") #showData(data) elif (clusterId == 0x8005): # this is the Active Endpoint Response This message tells you # what the device can do, but it isn't constructed correctly to match # what the switch can do according to the spec. This is another # message that gets it's response after I receive the Match Descriptor print 'Active Endpoint Response' # elif (clusterId == 0x0006): # # Match Descriptor Request; this is the point where I finally # # respond to the switch. Several messages are sent to cause the # # switch to join with the controller at a network level and to cause # # it to regard this controller as valid. # # # # First the Active Endpoint Request # payload1 = '\x00\x00' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x00', # cluster = '\x00\x05', # profile = '\x00\x00', # data = payload1 # ) # print 'sent Active Endpoint' # # Now the Match Descriptor Response # payload2 = '\x00\x00\x00\x00\x01\x02' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x00', # cluster = '\x80\x06', # profile = '\x00\x00', # data = payload2 # ) # print 'Sent Match Descriptor' # # Now there are two messages directed at the hardware # # code (rather than the network code. The switch has to # # receive both of these to stay joined. # payload3 = '\x11\x01\x01' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x02', # cluster = '\x00\xf6', # profile = '\xc2\x16', # data = payload2 # ) # payload4 = '\x19\x01\xfa\x00\x01' # zb.send('tx_explicit', # dest_addr_long = data['source_addr_long'], # dest_addr = data['source_addr'], # src_endpoint = '\x00', # dest_endpoint = '\x02', # cluster = '\x00\xf0', # profile = '\xc2\x16', # data = payload4 # ) # print 'Sent hardware join messages' # # now that it should have joined, I'll add a record to the database to # # hold the status. I'll just name the device 'unknown' so it can # # be updated by hand using sqlite3 directly. If the device already exists, # # I'll leave the name alone and just use the existing record # # Yes, this means you'll have to go into the database and assign it a name # # # dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, # db=dbName) # c = dbconn.cursor() # try: # # See if the device is already in the database # # if not, add a record with the name 'unknown', # # then go correct the name using the human interface # # to sqlite3 # c.execute("select name from smartswitch " # "where longaddress = %s; ", # (addrToString(data['source_addr_long']),)) # switchrecord = c.fetchone() # if switchrecord is not None: # lprint ("Device %s is rejoining the network" %(switchrecord[0])) # else: # lprint ("Adding new device") # c.execute("insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" # "values (%s, %s, %s, %s, %s, %s, %s);", # ('unknown', # addrToString(data['source_addr_long']), # addrToString(data['source_addr']), # 'unknown', # '0', # '0', # dbTimeStamp())) # dbconn.commit() # except mdb.Error, e: # lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) # dbconn.close() elif (clusterId == 0x8038): print("Management Network Update Request") else: lprint("Unimplemented Cluster ID", hex(clusterId)) print elif (data['profile'] == '\xc2\x16'): # Alertme Specific if (clusterId == 0xee): clusterCmd = ord(data['rf_data'][2]) status = '' if (clusterCmd == 0x80): if (ord(data['rf_data'][3]) & 0x01): status = "ON" else: status = "OFF" dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute( "select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']), )) #print c.fetchone()[0].capitalize(), #print "Switch is", status try: c.execute( "update smartswitch " "set status = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (status, addrToString( data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() elif (clusterId == 0xef): clusterCmd = ord(data['rf_data'][2]) status = data['rf_data'] # cut down on typing if (clusterCmd == 0x81): usage = unpack('<H', status[3:5])[0] dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() # get device name from database try: c.execute( "select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']), )) name = c.fetchone()[0].capitalize() #lprint ("%s Instaneous Power, %d Watts" %(name, usage)) # do database updates c.execute( "update smartswitch " "set watts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString( data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() elif (clusterCmd == 0x82): usage = unpack('<L', status[3:7])[0] / 3600 upTime = unpack('<L', status[7:11])[0] dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() c.execute( "select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']), )) name = c.fetchone()[0].capitalize() #lprint ("%s Minute Stats: Usage, %d Watt Hours; Uptime, %d Seconds" %(name, usage/3600, upTime)) # update database stuff try: c.execute( "update smartswitch " "set twatts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString( data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close() elif (clusterId == 0xf0): showClusterData(data['source_addr_long'], data['source_addr'], clusterId, data['rf_data']) # If the cluster cmd byte is 'xfb', it's a status if data['rf_data'][2] == '\xfb': status = data['rf_data'] # just to make typing easier if status[3] == '\x1f': print " Door Sensor", print str(float(unpack("<h", status[8:10])[0])\ / 100.0 * 1.8 + 32) + "F", if ord(status[-1]) & 0x01 == 1: print "reed switch open", else: print "reed switch closed", if ord(status[-1]) & 0x02 == 0: print "tamper switch open", else: print "tamper switch closed", elif status[3] == '\x1c': # Never found anything useful in this print "Power Switch", elif status[3] == '\x1d': print " Key Fob", print str(float(unpack("<h", status[8:10])[0])\ / 100.0 * 1.8 + 32) + "F", unpack('<I', status[4:8])[0] print 'Counter', unpack('<I', status[4:8])[0], elif status[3] == '\x1e': # This indicates a door sensor # with an invalid temperature reading # the other items are OK print " Door Sensor", print "Temperature invalid", if ord(status[-1]) & 0x01 == 1: print "reed switch open", else: print "reed switch closed", if ord(status[-1]) & 0x02 == 0: print "tamper switch open", else: print "tamper switch closed", #This may be the missing link to this thing print 'sending missing link', zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint=data['dest_endpoint'], dest_endpoint=data['source_endpoint'], cluster='\x00\xf0', profile='\xc2\x16', data='\x11\x39\xfd') pass else: print " Don't know this device yet", print '' pass
"where longaddress = %s; ", addrToString(data['source_addr_long']),) switchrecord = c.fetchone() if switchrecord is not None: lprint ("Device %s is rejoining the network" %(switchrecord[0])) else: lprint ("Adding new device") c.execute("insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" "values (%s, %s, %s, %s, %s, %s, %s);", ('unknown', addrToString(data['source_addr_long']), addrToString(data['source_addr']), 'unknown', '0', '0', dbTimeStamp())) dbconn.commit() except mdb.Error, e: print ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() elif (clusterId == 0x0500): # This is the security cluster showClusterData(data['source_addr_long'],data['source_addr'],clusterId,data['rf_data']) # When the switch first connects, it come up in a state that needs # initialization, this command seems to take care of that. # So, look at the value of the data and send the command. if data['rf_data'][3:7] == '\x15\x00\x39\x10': print "sending initialization" zb.send('tx_explicit', dest_addr_long = data['source_addr_long'], dest_addr = data['source_addr'], src_endpoint = data['dest_endpoint'],
db=dbName) c = dbconn.cursor() # get device name from database try: c.execute("select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']),)) name = c.fetchone()[0].capitalize() #lprint ("%s Instaneous Power, %d Watts" %(name, usage)) # do database updates c.execute("update smartswitch " "set watts = %s, " "shortaddress = %s, " "utime = %s where longaddress = %s; ", (usage, addrToString(data['source_addr']), dbTimeStamp(), addrToString(data['source_addr_long']))) dbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) dbconn.close() elif (clusterCmd == 0x82): usage = (ord(data['rf_data'][3]) + (ord(data['rf_data'][4]) * 256) + (ord(data['rf_data'][5]) * 256 * 256) + (ord(data['rf_data'][6]) * 256 * 256 * 256) ) upTime = (ord(data['rf_data'][7]) + (ord(data['rf_data'][8]) * 256) + (ord(data['rf_data'][9]) * 256 * 256) + (ord(data['rf_data'][10]) * 256 * 256 * 256) ) dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName)
def messageReceived(data): #print 'gotta packet' #print data clusterId = (ord(data['cluster'][0]) * 256) + ord(data['cluster'][1]) #print 'Cluster ID:', hex(clusterId), if (clusterId == 0x13): # This is the device announce message. # due to timing problems with the switch itself, I don't # respond to this message, I save the response for later after the # Match Descriptor request comes in. You'll see it down below. # if you want to see the data that came in with this message, just # uncomment the 'print data' comment up above print 'Device Announce Message' elif (clusterId == 0x8005): # this is the Active Endpoint Response This message tells you # what the device can do, but it isn't constructed correctly to match # what the switch can do according to the spec. This is another # message that gets it's response after I receive the Match Descriptor print 'Active Endpoint Response' elif (clusterId == 0x0006): # Match Descriptor Request; this is the point where I finally # respond to the switch. Several messages are sent to cause the # switch to join with the controller at a network level and to cause # it to regard this controller as valid. # # First the Active Endpoint Request payload1 = '\x00\x00' zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x00', cluster='\x00\x05', profile='\x00\x00', data=payload1) print 'sent Active Endpoint' # Now the Match Descriptor Response payload2 = '\x00\x00\x00\x00\x01\x02' zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x00', cluster='\x80\x06', profile='\x00\x00', data=payload2) print 'Sent Match Descriptor' # Now there are two messages directed at the hardware # code (rather than the network code. The switch has to # receive both of these to stay joined. payload3 = '\x11\x01\x01' zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x02', cluster='\x00\xf6', profile='\xc2\x16', data=payload2) payload4 = '\x19\x01\xfa\x00\x01' zb.send('tx_explicit', dest_addr_long=data['source_addr_long'], dest_addr=data['source_addr'], src_endpoint='\x00', dest_endpoint='\x02', cluster='\x00\xf0', profile='\xc2\x16', data=payload4) print 'Sent hardware join messages' # now that it should have joined, I'll add a record to the database to # hold the status. I'll just name the device 'unknown' so it can # be updated by hand using sqlite3 directly. If the device already exists, # I'll leave the name alone and just use the existing record # Yes, this means you'll have to go into the database and assign it a name # dbconn = mdb.connect(host=dbHost, user=dbUser, passwd=dbPassword, db=dbName) c = dbconn.cursor() try: # See if the device is already in the database # if not, add a record with the name 'unknown', # then go correct the name using the human interface # to sqlite3 c.execute( "select name from smartswitch " "where longaddress = %s; ", (addrToString(data['source_addr_long']), )) switchrecord = c.fetchone() if switchrecord is not None: lprint("Device %s is rejoining the network" % (switchrecord[0])) else: lprint("Adding new device") c.execute( "insert into smartswitch(name,longaddress, shortaddress, status, watts, twatts, utime)" "values (%s, %s, %s, %s, %s, %s, %s);", ('unknown', addrToString(data['source_addr_long']), addrToString(data['source_addr']), 'unknown', '0', '0', dbTimeStamp())) dbconn.commit() except mdb.Error, e: lprint("Database Error %d: %s" % (e.args[0], e.args[1])) dbconn.close()
ptemp = rxList[6].split(' ')[1] atemp = rxList[7].split(' ')[1] try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("update pool set motor = %s, " "waterfall = %s," "light = %s," "fountain = %s," "solar = %s," "ptemp = %s," "atemp = %s," "utime = %s;", (motor, waterfall, light, fountain, solar, ptemp, atemp, dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1])) hdbconn.close() elif rxList[0] == 'Septic': #print("Got Septic Packet") #print(rxList) try: hdbconn = mdb.connect(host=hdbHost, user=hdbUser, passwd=hdbPassword, db=hdbName) hc = hdbconn.cursor() hc.execute("update septic set level = %s, utime = %s;", (rxList[1].rstrip(), dbTimeStamp())) hdbconn.commit() except mdb.Error, e: lprint ("Database Error %d: %s" % (e.args[0],e.args[1]))