Exemplo n.º 1
0
            print '-- %s: %s' % (e.__class__.__name__, e)


        # Reset our 5 minute timer
        sensorhistory.reset5mintimer()
        

    # We're going to twitter at midnight, 8am and 4pm
    # Determine the hour of the day (ie 6:42 -> '6')
    currhour = datetime.datetime.now().hour
    # twitter every 8 hours
    if (((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)):
        print "twittertime!"
        twittertimer = time.time();
        if not LOGFILENAME:
            message = appengineauth.gettweetreport()
        else:
            # sum up all the sensors' data
            wattsused = 0
            whused = 0
            for history in sensorhistories.sensorhistories:
                wattsused += history.avgwattover5min()
                whused += history.dayswatthr
                
            message = "Currently using "+str(int(wattsused))+" Watts, "+str(int(whused))+" Wh today so far #tweetawatt"
            # write something ourselves
        if message:
            print message
            TwitterIt(twitterusername, twitterpassword, message)

    if GRAPHIT:
Exemplo n.º 2
0
def update_graph(idleevent):
    global avgwattdataidx, sensorhistories, twittertimer, DEBUG, currday

    # DAW - 5/18/11 - wrap the whole xbee packet inspection code in an exception handler
    try:

        # grab one packet from the xbee, or timeout
        packet = xbee.find_packet(ser)
        if not packet:
            return        # we timedout

        xb = xbee(packet)             # parse the packet
        #print xb.address_16
        if DEBUG:       # for debugging sometimes we only want one
            print xb

        # DAW - 5/18/11 - prevent exception that was caused by invalid xbee packet address
        if xb.address_16 < 0 or xb.address_16 > len(vrefcalibration):
            LogMsg("ERROR - invalid packet address: " + xb.address_16)
            return

        # we'll only store n-1 samples since the first one is usually messed up
        voltagedata = [-1] * (len(xb.analog_samples) - 1)
        ampdata = [-1] * (len(xb.analog_samples ) -1)
        # grab 1 thru n of the ADC readings, referencing the ADC constants
        # and store them in nice little arrays
        for i in range(len(voltagedata)):
            voltagedata[i] = xb.analog_samples[i+1][VOLTSENSE]
            ampdata[i] = xb.analog_samples[i+1][CURRENTSENSE]

        if DEBUG:
            print "ampdata: "+str(ampdata)
            print "voltdata: "+str(voltagedata)
        # get max and min voltage and normalize the curve to '0'
        # to make the graph 'AC coupled' / signed
        min_v = 1024     # XBee ADC is 10 bits, so max value is 1023
        max_v = 0
        for i in range(len(voltagedata)):
            if (min_v > voltagedata[i]):
                min_v = voltagedata[i]
            if (max_v < voltagedata[i]):
                max_v = voltagedata[i]

        # figure out the 'average' of the max and min readings
        avgv = (max_v + min_v) / 2
        # also calculate the peak to peak measurements
        vpp =  max_v-min_v

        for i in range(len(voltagedata)):
            #remove 'dc bias', which we call the average read
            voltagedata[i] -= avgv
            # We know that the mains voltage is 120Vrms = +-170Vpp
            voltagedata[i] = (voltagedata[i] * MAINSVPP) / vpp

        # normalize current readings to amperes
        for i in range(len(ampdata)):
            # VREF is the hardcoded 'DC bias' value, its
            # about 492 but would be nice if we could somehow
            # get this data once in a while maybe using xbeeAPI
            if vrefcalibration[xb.address_16]:
                ampdata[i] -= vrefcalibration[xb.address_16]
            else:
                ampdata[i] -= vrefcalibration[0]
            # the CURRENTNORM is our normalizing constant
            # that converts the ADC reading to Amperes
            ampdata[i] /= CURRENTNORM

        #print "Voltage, in volts: ", voltagedata
        #print "Current, in amps:  ", ampdata

        # calculate instant. watts, by multiplying V*I for each sample point
        wattdata = [0] * len(voltagedata)
        for i in range(len(wattdata)):
            wattdata[i] = voltagedata[i] * ampdata[i]

        # sum up the current drawn over one 1/60hz cycle
        avgamp = 0

        # DAW - 2/26/11 - check for less than 17 samples - would sometimes cause index out of range exception
        if (len(ampdata) < 17):
            return

        # 16.6 samples per second, one cycle = ~17 samples
        # close enough for govt work :(

        for i in range(17):
            avgamp += abs(ampdata[i])
        avgamp /= 17.0

        # DAW - average of all 18 amp readings
        avgamp2 = 0
        for i in range(len(ampdata)):
            avgamp2 += abs(ampdata[i])
        avgamp2 /= len(ampdata)

        # DAW - average of all 18 volt readings
        avgvolt = 0
        for i in range(len(voltagedata)):
            avgvolt += abs(voltagedata[i])
        avgvolt /= len(voltagedata)

        # sum up power drawn over one 1/60hz cycle
        avgwatt = 0
        # DAW - 2/26/11 - check for less than 17 samples - would sometimes cause index out of range exception
        if len(wattdata) < 17:
            return

        # 16.6 samples per second, one cycle = ~17 samples
        for i in range(17):
            avgwatt += abs(wattdata[i])
        avgwatt /= 17.0

        # DAW - average of all 18 watt readings
        avgwatt2 = 0
        for i in range(len(wattdata)):
            avgwatt2 += abs(wattdata[i])
        avgwatt2 /= len(wattdata)
    except:
        LogMsg("Error in packet handling, ignoring")
        return

    # Print out our most recent measurements
    print str(xb.address_16)+"\tCurrent draw, in amperes: "+str(avgamp)
    print "\tWatt draw, in VA: "+str(avgwatt)
    # DAW print out extra data
    print "\t RSSI: " + str(xb.rssi) + " Volt: " + str(avgvolt) + " Amps: " + str(avgamp2) + " Watts: " + str(avgwatt2)

    if (avgamp > 13):
        return            # hmm, bad data

    if GRAPHIT:
        # Add the current watt usage to our graph history
        avgwattdata[avgwattdataidx] = avgwatt
        avgwattdataidx += 1
        if (avgwattdataidx >= len(avgwattdata)):
            # If we're running out of space, shift the first 10% out
            tenpercent = int(len(avgwattdata)*0.1)
            for i in range(len(avgwattdata) - tenpercent):
                avgwattdata[i] = avgwattdata[i+tenpercent]
            for i in range(len(avgwattdata) - tenpercent, len(avgwattdata)):
                avgwattdata[i] = 0
            avgwattdataidx = len(avgwattdata) - tenpercent

    # retreive the history for this sensor
    sensorhistory = sensorhistories.find(xb.address_16)
    #print sensorhistory

    # add up the delta-watthr used since last reading
    # Figure out how many watt hours were used since last reading
    elapsedseconds = time.time() - sensorhistory.lasttime
    dwatthr = (avgwatt * elapsedseconds) / (60.0 * 60.0)  # 60 seconds in 60 minutes = 1 hr
    sensorhistory.lasttime = time.time()
    print "\t\tWh used in last ",elapsedseconds," seconds: ",dwatthr
    sensorhistory.addwatthr(dwatthr)

    if DEBUG:
        print "sensorhistory.avgwattover5min is " + str(sensorhistory.avgwattover5min())
        print time.strftime("%Y %m %d, %H:%M")+", "+str(sensorhistory.sensornum)+", "+str(sensorhistory.avgwattover5min())+"\n"

    # Determine the minute of the hour (ie 6:42 -> '42')
    currminute = (int(time.time())/60) % 10
    # Figure out if its been five minutes since our last save
    if (((time.time() - sensorhistory.fiveminutetimer) >= 60.0)
        and (currminute % 5 == 0)
        ):
        # Print out debug data, Wh used in last 5 minutes
        avgwattsused = sensorhistory.avgwattover5min()
        print time.strftime("%Y %m %d, %H:%M")+", "+str(sensorhistory.sensornum)+", "+str(sensorhistory.avgwattover5min())+"\n"

        # Lets log it! Seek to the end of our log file
        if logfile:
            logfile.seek(0, 2) # 2 == SEEK_END. ie, go to the end of the file
            logfile.write(time.strftime("%Y %m %d, %H:%M")+", "+
                          str(sensorhistory.sensornum)+", "+
                          str(sensorhistory.avgwattover5min())+"\n")
            logfile.flush()

        # Or, send it to the app engine
        if not LOGFILENAME:
            appengineauth.sendreport(xb.address_16, avgwattsused)

        # DAW - 1/18/11 - log avg watts used to nimbits
        # avgwattstosend = "%.2f" % avgwattsused
        if NIMBITS_ID:
            try:
                urllib.urlopen("http://gigamega-beta.appspot.com/service/currentvalue?value=" +
                    str(avgwattsused) + "&point=" + NIMBITS_ID + "&[email protected]&secret=e90d9c41-6529-4cf8-b248-92335c577cc7")
            except IOError:
                print 'Error sending to nimbits'

        # DAW - 2/7/11 - log avg watts used to Pachube
        if PACHUBE_ID:
            try:
                pac.update([eeml.Data(int(PACHUBE_ID), avgwattsused, unit=eeml.Watt())]) # unit=eeml.Unit('Volt', type='basicSI', symbol='V'))])
                pac.put()
            except:
                print 'Error sending to Pachube'

        # DAW - 8/7/10 - moved here from below - otherwise, reset5mintimer can cause watts to be 0 when tweet occurs
        # We're going to twitter at midnight, 8am and 4pm

        # Determine the hour of the day (ie 6:42 -> '6')
        currhour = datetime.datetime.now().hour
        # twitter every 8 hours
        # DAW - if debugging, twitter (actually just log to file) every minute
        #if ((((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)) or (DEBUG and ((time.time() - twittertimer) >= 60.0))):
        # DAW - twitter every 4 hours
        if (((time.time() - twittertimer) >= 3660.0) and (currhour % 4 == 0)):
            print "twittertime!"
            twittertimer = time.time();
            if not LOGFILENAME:
                message = appengineauth.gettweetreport()
            else:
                # sum up all the sensors' data
                wattsused = 0
                whused = 0
                if DEBUG:
                    print "num sensor histories", len(sensorhistories.sensorhistories)
                newday = False
                thisday = datetime.datetime.now().day
                if currday != thisday:
                    newday = True
                    if DEBUG:
                        message = "New day, clearing dayswatthr " + str(currday) + " to " + str(thisday)
                        LogMsg(message)
                    currday = thisday
                for history in sensorhistories.sensorhistories:
                    if DEBUG:
                        print "in twitter loop, found history", history.sensornum, history.cumulative5mwatthr
                    wattsused += history.avgwattover5min()
                    whused += history.dayswatthr
                    # DAW - 8/7/10 - clear day's count when day changes
                    if newday:
                        history.dayswatthr = 0

                message = "Currently using "+str(int(wattsused))+" Watts, "+str(int(whused))+" Wh today so far #tweetawatt"

                # DAW - 8/7/10 - if it's midnight, clear the day's count

                # write something ourselves
            if message:
                print message
                # DAW - if debugging, write to CSV file for debug purposes rather than twittering
                if DEBUG:
                    LogMsg(message)
                else:
                    #TwitterIt(twitterusername, twitterpassword, message)
                    TwitterIt(message)

        # Reset our 5 minute timer
        sensorhistory.reset5mintimer()

    if GRAPHIT:
        # Redraw our pretty picture
        fig.canvas.draw_idle()
        # Update with latest data
        wattusageline.set_ydata(avgwattdata)
        voltagewatchline.set_ydata(voltagedata)
        ampwatchline.set_ydata(ampdata)
        # Update our graphing range so that we always see all the data
        maxamp = max(ampdata)
        minamp = min(ampdata)
        maxamp = max(maxamp, -minamp)
        mainsampwatcher.set_ylim(maxamp * -1.2, maxamp * 1.2)
        wattusage.set_ylim(0, max(avgwattdata) * 1.2)
Exemplo n.º 3
0
        except (IOError, socket.error), e:
            print '-- %s: %s' % (e.__class__.__name__, e)

        # Reset our 5 minute timer
        sensorhistory.reset5mintimer()

    # We're going to twitter at midnight, 8am and 4pm
    # Determine the hour of the day (ie 6:42 -> '6')
    currhour = datetime.datetime.now().hour
    # twitter every 8 hours
    if (((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)):
        print "twittertime!"
        twittertimer = time.time()
        if not LOGFILENAME:
            message = appengineauth.gettweetreport()
        else:
            # sum up all the sensors' data
            wattsused = 0
            whused = 0
            for history in sensorhistories.sensorhistories:
                wattsused += history.avgwattover5min()
                whused += history.dayswatthr

            message = "Currently using " + str(
                int(wattsused)) + " Watts, " + str(
                    int(whused)) + " Wh today so far #tweetawatt"
            # write something ourselves
        if message:
            print message
            TwitterIt(twitterusername, twitterpassword, message)
Exemplo n.º 4
0
def update_graph(idleevent):
    global avgwattdataidx, sensorhistories, twittertimer, DEBUG, incoffee, coffeecutoff
    shouldtweet = False
     
    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if not packet:
        return        # we timedout
    
    xb = xbee(packet)             # parse the packet
    #print xb.address_16
    if DEBUG:       # for debugging sometimes we only want one
        print xb
        
    # we'll only store n-1 samples since the first one is usually messed up
    voltagedata = [-1] * (len(xb.analog_samples) - 1)
    ampdata = [-1] * (len(xb.analog_samples ) -1)
    # grab 1 thru n of the ADC readings, referencing the ADC constants
    # and store them in nice little arrays
    for i in range(len(voltagedata)):
        voltagedata[i] = xb.analog_samples[i+1][VOLTSENSE]
        ampdata[i] = xb.analog_samples[i+1][CURRENTSENSE]

    if DEBUG:
        print "ampdata: "+str(ampdata)
        print "voltdata: "+str(voltagedata)
    # get max and min voltage and normalize the curve to '0'
    # to make the graph 'AC coupled' / signed
    min_v = 1024     # XBee ADC is 10 bits, so max value is 1023
    max_v = 0
    for i in range(len(voltagedata)):
        if (min_v > voltagedata[i]):
            min_v = voltagedata[i]
        if (max_v < voltagedata[i]):
            max_v = voltagedata[i]

    # figure out the 'average' of the max and min readings
    avgv = (max_v + min_v) / 2
    # also calculate the peak to peak measurements
    vpp =  max_v-min_v

    for i in range(len(voltagedata)):
        #remove 'dc bias', which we call the average read
        voltagedata[i] -= avgv
        # We know that the mains voltage is 120Vrms = +-170Vpp
        voltagedata[i] = (voltagedata[i] * MAINSVPP) / vpp

    # normalize current readings to amperes
    for i in range(len(ampdata)):
        # VREF is the hardcoded 'DC bias' value, its
        # about 492 but would be nice if we could somehow
        # get this data once in a while maybe using xbeeAPI
        if vrefcalibration[xb.address_16]:
            ampdata[i] -= vrefcalibration[xb.address_16]
        else:
            ampdata[i] -= vrefcalibration[0]
        # the CURRENTNORM is our normalizing constant
        # that converts the ADC reading to Amperes
        ampdata[i] /= CURRENTNORM

    print "Voltage, in volts: ", voltagedata
    print "Current, in amps:  ", ampdata

    # calculate instant. watts, by multiplying V*I for each sample point
    wattdata = [0] * len(voltagedata)
    for i in range(len(wattdata)):
        wattdata[i] = voltagedata[i] * ampdata[i]

    # sum up the current drawn over one 1/60hz cycle
    avgamp = 0
    # 16.6 samples per second, one cycle = ~17 samples
    # close enough for govt work :(
    for i in range(17):
        avgamp += abs(ampdata[i])
    avgamp /= 17.0

    # sum up power drawn over one 1/60hz cycle
    avgwatt = 0
    # 16.6 samples per second, one cycle = ~17 samples
    for i in range(17):         
        avgwatt += abs(wattdata[i])
    avgwatt /= 17.0

    if (avgamp > 13):
        return            # hmm, bad data

    # Print out our most recent measurements
    print str(xb.address_16)+"\tCurrent draw, in amperes: "+str(avgamp)
    print "\tWatt draw, in VA: "+str(avgwatt)

    if(avgwatt > coffeecutoff and incoffee == False):
      print "MAKING COFFEE!!!\n"
      incoffee = True
      shouldtweet = True
    elif(avgwatt < coffeecutoff and incoffee == True):
      print "NO MORE COFFEE :(\n"
      incoffee = False
      shouldtweet = True

    if GRAPHIT:
        # Add the current watt usage to our graph history
        avgwattdata[avgwattdataidx] = avgwatt
        avgwattdataidx += 1
        if (avgwattdataidx >= len(avgwattdata)):
            # If we're running out of space, shift the first 10% out
            tenpercent = int(len(avgwattdata)*0.1)
            for i in range(len(avgwattdata) - tenpercent):
                avgwattdata[i] = avgwattdata[i+tenpercent]
            for i in range(len(avgwattdata) - tenpercent, len(avgwattdata)):
                avgwattdata[i] = 0
            avgwattdataidx = len(avgwattdata) - tenpercent

    # retreive the history for this sensor
    sensorhistory = sensorhistories.find(xb.address_16)
    print sensorhistory
    
    # add up the delta-watthr used since last reading
    # Figure out how many watt hours were used since last reading
    elapsedseconds = time.time() - sensorhistory.lasttime
    dwatthr = (avgwatt * elapsedseconds) / (60.0 * 60.0)  # 60 seconds in 60 minutes = 1 hr
    sensorhistory.lasttime = time.time()
    print "\t\tWh used in last ",elapsedseconds," seconds: ",dwatthr
    sensorhistory.addwatthr(dwatthr)
    
    # Determine the minute of the hour (ie 6:42 -> '42')
    currminute = (int(time.time())/60) % 10
    # Figure out if its been five minutes since our last save
    if (((time.time() - sensorhistory.fiveminutetimer) >= 60.0)
        and (currminute % 5 == 0)
        ):
        # Print out debug data, Wh used in last 5 minutes
        avgwattsused = sensorhistory.avgwattover5min()
        print time.strftime("%Y %m %d, %H:%M")+", "+str(sensorhistory.sensornum)+", "+str(sensorhistory.avgwattover5min())+"\n"
               
        # Lets log it! Seek to the end of our log file
        if logfile:
            logfile.seek(0, 2) # 2 == SEEK_END. ie, go to the end of the file
            logfile.write(time.strftime("%Y %m %d, %H:%M")+", "+
                          str(sensorhistory.sensornum)+", "+
                          str(sensorhistory.avgwattover5min())+"\n")
            logfile.flush()
            
        # Or, send it to the app engine
        if not LOGFILENAME:
            appengineauth.sendreport(xb.address_16, avgwattsused)
        
        
        # Reset our 5 minute timer
        sensorhistory.reset5mintimer()
        

    # We're going to twitter at midnight, 8am and 4pm
    # Determine the hour of the day (ie 6:42 -> '6')
    currhour = datetime.datetime.now().hour
    # twitter every 8 hours
    if (shouldtweet): #((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)):
	shouldtweet = False
        print "twittertime!"
        twittertimer = time.time();
        if not LOGFILENAME:
            message = appengineauth.gettweetreport()
        else:
            # sum up all the sensors' data
            wattsused = 0
            whused = 0
            for history in sensorhistories.sensorhistories:
                wattsused += history.avgwattover5min()
                whused += history.dayswatthr
                
            message = "Currently using "+str(int(wattsused))+" Watts, "+str(int(whused))+" Wh today so far #tweetawatt"

            if(incoffee):
              message = "Made coffee!!! %s #happyday" % (datetime.datetime.now())
            else:
              message = "No more coffee %s #sadface" % (datetime.datetime.now())
            # write sometdatetime.datetime.now() hindatetime.datetime.now() g ourselves
        if message:
            print message
            TwitterIt(twitterusername, twitterpassword, message)

    if GRAPHIT:
        # Redraw our pretty picture
        fig.canvas.draw_idle()
        # Update with latest data
        wattusageline.set_ydata(avgwattdata)
        voltagewatchline.set_ydata(voltagedata)
        ampwatchline.set_ydata(ampdata)
        # Update our graphing range so that we always see all the data
        maxamp = max(ampdata)
        minamp = min(ampdata)
        maxamp = max(maxamp, -minamp)
        mainsampwatcher.set_ylim(maxamp * -1.2, maxamp * 1.2)
        wattusage.set_ylim(0, max(avgwattdata) * 1.2)
Exemplo n.º 5
0
def update_graph(idleevent):
    global avgwattdataidx, sensorhistories, twittertimer, onlywatchfor
     
    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if packet:
        xb = xbee(packet)
        print xb.address_16
        if (onlywatchfor != 0):
            if (xb.address_16 != onlywatchfor):
                return
            print xb
        
        # we'll only store n-1 samples since the first one is usually messed up
        voltagedata = [-1] * (len(xb.analog_samples) - 1)
        ampdata = [-1] * (len(xb.analog_samples ) -1)
        # grab 1 thru n of the ADC readings, referencing the ADC constants
        # and store them in nice little arrays
        for i in range(len(voltagedata)):
            voltagedata[i] = xb.analog_samples[i+1][VOLTSENSE]
            ampdata[i] = xb.analog_samples[i+1][CURRENTSENSE]

        #print ampdata
        
        # get max and min voltage and normalize the curve to '0'
        # to make the graph 'AC coupled' / signed
        min_v = 1024     # XBee ADC is 10 bits, so max value is 1023
        max_v = 0
        for i in range(len(voltagedata)):
            if (min_v > voltagedata[i]):
                min_v = voltagedata[i]
            if (max_v < voltagedata[i]):
                max_v = voltagedata[i]

        # figure out the 'average' of the max and min readings
        avgv = (max_v + min_v) / 2
        # also calculate the peak to peak measurements
        vpp =  max_v-min_v

        for i in range(len(voltagedata)):
            #remove 'dc bias', which we call the average read
            voltagedata[i] -= avgv
            # We know that the mains voltage is 120Vrms = +-170Vpp
            voltagedata[i] = (voltagedata[i] * MAINSVPP) / vpp

        # normalize current readings to amperes
        for i in range(len(ampdata)):
            # VREF is the hardcoded 'DC bias' value, its
            # about 492 but would be nice if we could somehow
            # get this data once in a while maybe using xbeeAPI
            if vrefs[xb.address_16]:
                ampdata[i] -= vrefs[xb.address_16]
            else:
                ampdata[i] -= vrefs[0]
            # the CURRENTNORM is our normalizing constant
            # that converts the ADC reading to Amperes
            ampdata[i] /= CURRENTNORM

        #print "Voltage, in volts: ", voltagedata
        #print "Current, in amps:  ", ampdata

        # calculate instant. watts, by multiplying V*I for each sample point
        wattdata = [0] * len(voltagedata)
        for i in range(len(wattdata)):
            wattdata[i] = voltagedata[i] * ampdata[i]

        # sum up the current drawn over one 1/60hz cycle
        avgamp = 0
        # 16.6 samples per second, one cycle = ~17 samples
        # close enough for govt work :(
        for i in range(17):
            avgamp += abs(ampdata[i])
        avgamp /= 17.0

        # sum up power drawn over one 1/60hz cycle
        avgwatt = 0
        # 16.6 samples per second, one cycle = ~17 samples
        for i in range(17):         
            avgwatt += abs(wattdata[i])
        avgwatt /= 17.0


        # Print out our most recent measurements
        print str(xb.address_16)+"\tCurrent draw, in amperes: "+str(avgamp)
        print "\tWatt draw, in VA: "+str(avgwatt)

        # Add the current watt usage to our graph history
        avgwattdata[avgwattdataidx] = avgwatt
        avgwattdataidx += 1
        if (avgwattdataidx >= len(avgwattdata)):
            # If we're running out of space, shift the first 10% out
            tenpercent = int(len(avgwattdata)*0.1)
            for i in range(len(avgwattdata) - tenpercent):
                avgwattdata[i] = avgwattdata[i+tenpercent]
            for i in range(len(avgwattdata) - tenpercent, len(avgwattdata)):
                avgwattdata[i] = 0
            avgwattdataidx = len(avgwattdata) - tenpercent

        # retreive the history for this sensor
        sensorhistory = findsensorhistory(xb.address_16)
        #print sensorhistory

        # add up the delta-watthr used since last reading
        # Figure out how many watt hours were used since last reading
        elapsedseconds = time.time() - sensorhistory.lasttime
        dwatthr = (avgwatt * elapsedseconds) / (60.0 * 60.0)  # 60 seconds in 60 minutes = 1 hr
        sensorhistory.lasttime = time.time()
        print "\t\tWh used in last ",elapsedseconds," seconds: ",dwatthr
        sensorhistory.addwatthr(dwatthr)

        # Determine the minute of the hour (ie 6:42 -> '42')
        currminute = (int(time.time())/60) % 10
        # Figure out if its been five minutes since our last save
        if (((time.time() - sensorhistory.fiveminutetimer) >= 60.0) and (currminute % 5 == 0)):
            # Print out debug data, Wh used in last 5 minutes
            avgwattsused = sensorhistory.avgwattover5min()
            print time.strftime("%Y %m %d, %H:%M"),", ",sensorhistory.cumulativewatthr,"Wh = ",avgwattsused," W average"

            # Also, send it to the app engine
            appengineauth.sendreport(xb.address_16, avgwattsused)
            
            # Reset our 5 minute timer
            sensorhistory.reset5mintimer()


        # We're going to twitter at midnight, 8am and 4pm
        # Determine the hour of the day (ie 6:42 -> '6')
        currhour = datetime.datetime.now().hour
        if (((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)):
          print "twittertime!"
          twittertimer = time.time();
          TwitterIt(twitterusername, twitterpassword,
                    appengineauth.gettweetreport())
        # Redraw our pretty picture
        fig.canvas.draw_idle()
        # Update with latest data
        wattusageline.set_ydata(avgwattdata)
        voltagewatchline.set_ydata(voltagedata)
        ampwatchline.set_ydata(ampdata)
        # Update our graphing range so that we always see all the data
        maxamp = max(ampdata)
        minamp = min(ampdata)
        maxamp = max(maxamp, -minamp)
        mainsampwatcher.set_ylim(maxamp * -1.2, maxamp * 1.2)
        wattusage.set_ylim(0, max(avgwattdata) * 1.2)
Exemplo n.º 6
0
def update_graph(idleevent):
    global avgwattdataidx, sensorhistories, twittertimer, onlywatchfor

    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if packet:
        xb = xbee(packet)
        print xb.address_16
        if (onlywatchfor != 0):
            if (xb.address_16 != onlywatchfor):
                return
            print xb

        # we'll only store n-1 samples since the first one is usually messed up
        voltagedata = [-1] * (len(xb.analog_samples) - 1)
        ampdata = [-1] * (len(xb.analog_samples) - 1)
        # grab 1 thru n of the ADC readings, referencing the ADC constants
        # and store them in nice little arrays
        for i in range(len(voltagedata)):
            voltagedata[i] = xb.analog_samples[i + 1][VOLTSENSE]
            ampdata[i] = xb.analog_samples[i + 1][CURRENTSENSE]

        #print ampdata

        # get max and min voltage and normalize the curve to '0'
        # to make the graph 'AC coupled' / signed
        min_v = 1024  # XBee ADC is 10 bits, so max value is 1023
        max_v = 0
        for i in range(len(voltagedata)):
            if (min_v > voltagedata[i]):
                min_v = voltagedata[i]
            if (max_v < voltagedata[i]):
                max_v = voltagedata[i]

        # figure out the 'average' of the max and min readings
        avgv = (max_v + min_v) / 2
        # also calculate the peak to peak measurements
        vpp = max_v - min_v

        for i in range(len(voltagedata)):
            #remove 'dc bias', which we call the average read
            voltagedata[i] -= avgv
            # We know that the mains voltage is 120Vrms = +-170Vpp
            voltagedata[i] = (voltagedata[i] * MAINSVPP) / vpp

        # normalize current readings to amperes
        for i in range(len(ampdata)):
            # VREF is the hardcoded 'DC bias' value, its
            # about 492 but would be nice if we could somehow
            # get this data once in a while maybe using xbeeAPI
            if vrefs[xb.address_16]:
                ampdata[i] -= vrefs[xb.address_16]
            else:
                ampdata[i] -= vrefs[0]
            # the CURRENTNORM is our normalizing constant
            # that converts the ADC reading to Amperes
            ampdata[i] /= CURRENTNORM

        #print "Voltage, in volts: ", voltagedata
        #print "Current, in amps:  ", ampdata

        # calculate instant. watts, by multiplying V*I for each sample point
        wattdata = [0] * len(voltagedata)
        for i in range(len(wattdata)):
            wattdata[i] = voltagedata[i] * ampdata[i]

        # sum up the current drawn over one 1/60hz cycle
        avgamp = 0
        # 16.6 samples per second, one cycle = ~17 samples
        # close enough for govt work :(
        for i in range(17):
            avgamp += abs(ampdata[i])
        avgamp /= 17.0

        # sum up power drawn over one 1/60hz cycle
        avgwatt = 0
        # 16.6 samples per second, one cycle = ~17 samples
        for i in range(17):
            avgwatt += abs(wattdata[i])
        avgwatt /= 17.0

        # Print out our most recent measurements
        print str(xb.address_16) + "\tCurrent draw, in amperes: " + str(avgamp)
        print "\tWatt draw, in VA: " + str(avgwatt)

        # Add the current watt usage to our graph history
        avgwattdata[avgwattdataidx] = avgwatt
        avgwattdataidx += 1
        if (avgwattdataidx >= len(avgwattdata)):
            # If we're running out of space, shift the first 10% out
            tenpercent = int(len(avgwattdata) * 0.1)
            for i in range(len(avgwattdata) - tenpercent):
                avgwattdata[i] = avgwattdata[i + tenpercent]
            for i in range(len(avgwattdata) - tenpercent, len(avgwattdata)):
                avgwattdata[i] = 0
            avgwattdataidx = len(avgwattdata) - tenpercent

        # retreive the history for this sensor
        sensorhistory = findsensorhistory(xb.address_16)
        #print sensorhistory

        # add up the delta-watthr used since last reading
        # Figure out how many watt hours were used since last reading
        elapsedseconds = time.time() - sensorhistory.lasttime
        dwatthr = (avgwatt * elapsedseconds) / (
            60.0 * 60.0)  # 60 seconds in 60 minutes = 1 hr
        sensorhistory.lasttime = time.time()
        print "\t\tWh used in last ", elapsedseconds, " seconds: ", dwatthr
        sensorhistory.addwatthr(dwatthr)

        # Determine the minute of the hour (ie 6:42 -> '42')
        currminute = (int(time.time()) / 60) % 10
        # Figure out if its been five minutes since our last save
        if (((time.time() - sensorhistory.fiveminutetimer) >= 60.0)
                and (currminute % 5 == 0)):
            # Print out debug data, Wh used in last 5 minutes
            avgwattsused = sensorhistory.avgwattover5min()
            print time.strftime(
                "%Y %m %d, %H:%M"
            ), ", ", sensorhistory.cumulativewatthr, "Wh = ", avgwattsused, " W average"

            # Also, send it to the app engine
            appengineauth.sendreport(xb.address_16, avgwattsused)

            # Reset our 5 minute timer
            sensorhistory.reset5mintimer()

        # We're going to twitter at midnight, 8am and 4pm
        # Determine the hour of the day (ie 6:42 -> '6')
        currhour = datetime.datetime.now().hour
        if (((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)):
            print "twittertime!"
            twittertimer = time.time()
            TwitterIt(twitterusername, twitterpassword,
                      appengineauth.gettweetreport())
        # Redraw our pretty picture
        fig.canvas.draw_idle()
        # Update with latest data
        wattusageline.set_ydata(avgwattdata)
        voltagewatchline.set_ydata(voltagedata)
        ampwatchline.set_ydata(ampdata)
        # Update our graphing range so that we always see all the data
        maxamp = max(ampdata)
        minamp = min(ampdata)
        maxamp = max(maxamp, -minamp)
        mainsampwatcher.set_ylim(maxamp * -1.2, maxamp * 1.2)
        wattusage.set_ylim(0, max(avgwattdata) * 1.2)
Exemplo n.º 7
0
def update_graph(idleevent):
    global avgwattdataidx, sensorhistories, twittertimer, DEBUG, currday

    # DAW - 5/18/11 - wrap the whole xbee packet inspection code in an exception handler
    try:

        # grab one packet from the xbee, or timeout
        packet = xbee.find_packet(ser)
        if not packet:
            return  # we timedout

        xb = xbee(packet)  # parse the packet
        #print xb.address_16
        if DEBUG:  # for debugging sometimes we only want one
            print xb

        # DAW - 5/18/11 - prevent exception that was caused by invalid xbee packet address
        if xb.address_16 < 0 or xb.address_16 > len(vrefcalibration):
            LogMsg("ERROR - invalid packet address: " + xb.address_16)
            return

        # we'll only store n-1 samples since the first one is usually messed up
        voltagedata = [-1] * (len(xb.analog_samples) - 1)
        ampdata = [-1] * (len(xb.analog_samples) - 1)
        # grab 1 thru n of the ADC readings, referencing the ADC constants
        # and store them in nice little arrays
        for i in range(len(voltagedata)):
            voltagedata[i] = xb.analog_samples[i + 1][VOLTSENSE]
            ampdata[i] = xb.analog_samples[i + 1][CURRENTSENSE]

        if DEBUG:
            print "ampdata: " + str(ampdata)
            print "voltdata: " + str(voltagedata)
        # get max and min voltage and normalize the curve to '0'
        # to make the graph 'AC coupled' / signed
        min_v = 1024  # XBee ADC is 10 bits, so max value is 1023
        max_v = 0
        for i in range(len(voltagedata)):
            if (min_v > voltagedata[i]):
                min_v = voltagedata[i]
            if (max_v < voltagedata[i]):
                max_v = voltagedata[i]

        # figure out the 'average' of the max and min readings
        avgv = (max_v + min_v) / 2
        # also calculate the peak to peak measurements
        vpp = max_v - min_v

        for i in range(len(voltagedata)):
            #remove 'dc bias', which we call the average read
            voltagedata[i] -= avgv
            # We know that the mains voltage is 120Vrms = +-170Vpp
            voltagedata[i] = (voltagedata[i] * MAINSVPP) / vpp

        # normalize current readings to amperes
        for i in range(len(ampdata)):
            # VREF is the hardcoded 'DC bias' value, its
            # about 492 but would be nice if we could somehow
            # get this data once in a while maybe using xbeeAPI
            if vrefcalibration[xb.address_16]:
                ampdata[i] -= vrefcalibration[xb.address_16]
            else:
                ampdata[i] -= vrefcalibration[0]
            # the CURRENTNORM is our normalizing constant
            # that converts the ADC reading to Amperes
            ampdata[i] /= CURRENTNORM

        #print "Voltage, in volts: ", voltagedata
        #print "Current, in amps:  ", ampdata

        # calculate instant. watts, by multiplying V*I for each sample point
        wattdata = [0] * len(voltagedata)
        for i in range(len(wattdata)):
            wattdata[i] = voltagedata[i] * ampdata[i]

        # sum up the current drawn over one 1/60hz cycle
        avgamp = 0

        # DAW - 2/26/11 - check for less than 17 samples - would sometimes cause index out of range exception
        if (len(ampdata) < 17):
            return

        # 16.6 samples per second, one cycle = ~17 samples
        # close enough for govt work :(

        for i in range(17):
            avgamp += abs(ampdata[i])
        avgamp /= 17.0

        # DAW - average of all 18 amp readings
        avgamp2 = 0
        for i in range(len(ampdata)):
            avgamp2 += abs(ampdata[i])
        avgamp2 /= len(ampdata)

        # DAW - average of all 18 volt readings
        avgvolt = 0
        for i in range(len(voltagedata)):
            avgvolt += abs(voltagedata[i])
        avgvolt /= len(voltagedata)

        # sum up power drawn over one 1/60hz cycle
        avgwatt = 0
        # DAW - 2/26/11 - check for less than 17 samples - would sometimes cause index out of range exception
        if len(wattdata) < 17:
            return

        # 16.6 samples per second, one cycle = ~17 samples
        for i in range(17):
            avgwatt += abs(wattdata[i])
        avgwatt /= 17.0

        # DAW - average of all 18 watt readings
        avgwatt2 = 0
        for i in range(len(wattdata)):
            avgwatt2 += abs(wattdata[i])
        avgwatt2 /= len(wattdata)
    except:
        LogMsg("Error in packet handling, ignoring")
        return

    # Print out our most recent measurements
    print str(xb.address_16) + "\tCurrent draw, in amperes: " + str(avgamp)
    print "\tWatt draw, in VA: " + str(avgwatt)
    # DAW print out extra data
    print "\t RSSI: " + str(xb.rssi) + " Volt: " + str(
        avgvolt) + " Amps: " + str(avgamp2) + " Watts: " + str(avgwatt2)

    if (avgamp > 13):
        return  # hmm, bad data

    if GRAPHIT:
        # Add the current watt usage to our graph history
        avgwattdata[avgwattdataidx] = avgwatt
        avgwattdataidx += 1
        if (avgwattdataidx >= len(avgwattdata)):
            # If we're running out of space, shift the first 10% out
            tenpercent = int(len(avgwattdata) * 0.1)
            for i in range(len(avgwattdata) - tenpercent):
                avgwattdata[i] = avgwattdata[i + tenpercent]
            for i in range(len(avgwattdata) - tenpercent, len(avgwattdata)):
                avgwattdata[i] = 0
            avgwattdataidx = len(avgwattdata) - tenpercent

    # retreive the history for this sensor
    sensorhistory = sensorhistories.find(xb.address_16)
    #print sensorhistory

    # add up the delta-watthr used since last reading
    # Figure out how many watt hours were used since last reading
    elapsedseconds = time.time() - sensorhistory.lasttime
    dwatthr = (avgwatt * elapsedseconds) / (
        60.0 * 60.0)  # 60 seconds in 60 minutes = 1 hr
    sensorhistory.lasttime = time.time()
    print "\t\tWh used in last ", elapsedseconds, " seconds: ", dwatthr
    sensorhistory.addwatthr(dwatthr)

    if DEBUG:
        print "sensorhistory.avgwattover5min is " + str(
            sensorhistory.avgwattover5min())
        print time.strftime("%Y %m %d, %H:%M") + ", " + str(
            sensorhistory.sensornum) + ", " + str(
                sensorhistory.avgwattover5min()) + "\n"

    # Determine the minute of the hour (ie 6:42 -> '42')
    currminute = (int(time.time()) / 60) % 10
    # Figure out if its been five minutes since our last save
    if (((time.time() - sensorhistory.fiveminutetimer) >= 60.0)
            and (currminute % 5 == 0)):
        # Print out debug data, Wh used in last 5 minutes
        avgwattsused = sensorhistory.avgwattover5min()
        print time.strftime("%Y %m %d, %H:%M") + ", " + str(
            sensorhistory.sensornum) + ", " + str(
                sensorhistory.avgwattover5min()) + "\n"

        # Lets log it! Seek to the end of our log file
        if logfile:
            logfile.seek(0, 2)  # 2 == SEEK_END. ie, go to the end of the file
            logfile.write(
                time.strftime("%Y %m %d, %H:%M") + ", " +
                str(sensorhistory.sensornum) + ", " +
                str(sensorhistory.avgwattover5min()) + "\n")
            logfile.flush()

        # Or, send it to the app engine
        if not LOGFILENAME:
            appengineauth.sendreport(xb.address_16, avgwattsused)

        # DAW - 1/18/11 - log avg watts used to nimbits
        # avgwattstosend = "%.2f" % avgwattsused
        if NIMBITS_ID:
            try:
                urllib.urlopen(
                    "http://gigamega-beta.appspot.com/service/currentvalue?value="
                    + str(avgwattsused) + "&point=" + NIMBITS_ID +
                    "&[email protected]&secret=e90d9c41-6529-4cf8-b248-92335c577cc7"
                )
            except IOError:
                print 'Error sending to nimbits'

        # DAW - 2/7/11 - log avg watts used to Pachube
        if PACHUBE_ID:
            try:
                pac.update([
                    eeml.Data(int(PACHUBE_ID), avgwattsused, unit=eeml.Watt())
                ])  # unit=eeml.Unit('Volt', type='basicSI', symbol='V'))])
                pac.put()
            except:
                print 'Error sending to Pachube'

        # DAW - 8/7/10 - moved here from below - otherwise, reset5mintimer can cause watts to be 0 when tweet occurs
        # We're going to twitter at midnight, 8am and 4pm

        # Determine the hour of the day (ie 6:42 -> '6')
        currhour = datetime.datetime.now().hour
        # twitter every 8 hours
        # DAW - if debugging, twitter (actually just log to file) every minute
        #if ((((time.time() - twittertimer) >= 3660.0) and (currhour % 8 == 0)) or (DEBUG and ((time.time() - twittertimer) >= 60.0))):
        # DAW - twitter every 4 hours
        if (((time.time() - twittertimer) >= 3660.0) and (currhour % 4 == 0)):
            print "twittertime!"
            twittertimer = time.time()
            if not LOGFILENAME:
                message = appengineauth.gettweetreport()
            else:
                # sum up all the sensors' data
                wattsused = 0
                whused = 0
                if DEBUG:
                    print "num sensor histories", len(
                        sensorhistories.sensorhistories)
                newday = False
                thisday = datetime.datetime.now().day
                if currday != thisday:
                    newday = True
                    if DEBUG:
                        message = "New day, clearing dayswatthr " + str(
                            currday) + " to " + str(thisday)
                        LogMsg(message)
                    currday = thisday
                for history in sensorhistories.sensorhistories:
                    if DEBUG:
                        print "in twitter loop, found history", history.sensornum, history.cumulative5mwatthr
                    wattsused += history.avgwattover5min()
                    whused += history.dayswatthr
                    # DAW - 8/7/10 - clear day's count when day changes
                    if newday:
                        history.dayswatthr = 0

                message = "Currently using " + str(
                    int(wattsused)) + " Watts, " + str(
                        int(whused)) + " Wh today so far #tweetawatt"

                # DAW - 8/7/10 - if it's midnight, clear the day's count

                # write something ourselves
            if message:
                print message
                # DAW - if debugging, write to CSV file for debug purposes rather than twittering
                if DEBUG:
                    LogMsg(message)
                else:
                    #TwitterIt(twitterusername, twitterpassword, message)
                    TwitterIt(message)

        # Reset our 5 minute timer
        sensorhistory.reset5mintimer()

    if GRAPHIT:
        # Redraw our pretty picture
        fig.canvas.draw_idle()
        # Update with latest data
        wattusageline.set_ydata(avgwattdata)
        voltagewatchline.set_ydata(voltagedata)
        ampwatchline.set_ydata(ampdata)
        # Update our graphing range so that we always see all the data
        maxamp = max(ampdata)
        minamp = min(ampdata)
        maxamp = max(maxamp, -minamp)
        mainsampwatcher.set_ylim(maxamp * -1.2, maxamp * 1.2)
        wattusage.set_ylim(0, max(avgwattdata) * 1.2)