Tweet-a-watt - hoe maak je een gekwetter Energiemeter... (16 / 19 stap)

Stap 16: Ontwerp - winkel


Introduction

OK we via onze sensoren goede gegevens ontvangt, laat het corral in nuttiger brokken en op te slaan in een database. Kunnen we een database op de computer, maar aangezien we willen zouden om deze gegevens te delen, maakt het meer zin om online gezet. Er zijn aangepaste diensten die speciaal zijn ontworpen om te doen dit soort dingen zoals Pachube maar I 'm gonna het wiel opnieuw uitvinden en ontwerpen van mijn eigen web-app die de opslag en weergave van de energiegegevens. (Meestal ik wil spelen met Google App Engine!)

Heb je 5 minuten!

We krijgen gegevens om de paar seconden van de modem XBee binnen de kill-per-watt. Kan, in theorie, we gegevens in onze database elke 2 seconden, maar dat zou snel ballon de hoeveelheid opslag die nodig zijn. Het wil ook sorteren door middel van de gegevens moeilijk. Dus in plaats daarvan kunt optellen van alle sensorgegevens voor 5 minuten, en neem vervolgens het gemiddelde.

We doen dit door te houden twee timers en één tally. Een timer zal bijhouden hoe lang haar sinds de laatste sensor signaal werd gegeven, en de andere zal volgen als de 5 minuten. De telling van alle de watturen slaat (Watt metingen * tijd sinds de laatste sensorgegevens). Dan kunnen we aan het einde door de 5 minuten gemiddelde

Dit blok van code gaat in de buurt van het begin, de timers en tally maakt en initialiseert hen

...
fiveminutetimer = lasttime = time.time() # get de huidige tijd
cumulativewatthr = 0
...

Vervolgens later op, kunnen nadat we onze gegevens we in dit blok van code:

# optellen van de delta-watthr gebruikt sinds de laatste lezing
# Erachter te komen hoeveel watt-uur werden gebruikt sinds de laatste lezing
elapsedseconds = time.time() - lasttime
dwatthr = (avgwatt * elapsedseconds) / (60,0 * 60,0) # 60 seconden in 60 minuten = 1 uur
lastTime = time.time()
afdrukken "gebruikt in de laatste \t\tWh", elapsedseconds, "seconden:", dwatthr
cumulativewatthr += dwatthr

# Het bepalen van de minuut van het uur (ie 6:42 -> '42')
currminute = (int(time.time())/60) 10%
# Erachter te komen als de vijf minuten sinds onze laatste opslaan
Als (((time.time()-fiveminutetimer) > = 60,0) en (currminute % 5 == 0)):
# Uitprinten debug gegevens, Wh gebruikt in de laatste 5 minuten
avgwattsused = cumulativewatthr * (60,0 * 60,0 / (time.time() - fiveminutetimer))
Print time.strftime ("%Y %m %d, % H: %M"),",", cumulativewatthr, "Wh =", avgwattsused, "W gemiddelde")

# Onze 5 minuten timer reset
fiveminutetimer = time.time()
cumulativewatthr = 0

Opmerking dat we delta-watthours, de kleine hoeveelheid energie berekenen gebruikt om de paar seconden. Vervolgens kunnen we de gemiddelde watt gebruikt door de watthours te delen door het aantal uren dat verstreken (ongeveer 1/12e). Instead of going door exacte 5 minuten, heb ik besloten om alleen verslag over de 5 uur (: 05: 10, enz) zodat haar makkelijker om alle gegevens tegelijk verzenden als theres meerdere sensoren die op verschillende tijdstippen opgestart.

Wattcher-5minreporter.py van de downloadpagina downloaden. Als u dit run, krijg je een gestage stroom

In de buurt van het einde kunt u het tijdstempel, de Watthrs gebruikt in de laatste paar minuten en het gemiddelde vermogen

Multisensor!

We hebben goede gegevens maar tot nu toe het werkt alleen met een sensor. Meerdere sensoren zal verknoeien het! Tijd om het toevoegen van ondersteuning voor meer dan één XBee zodat ik een paar kamers bijhouden kan. Ik doe dat door het maken van een objectklasse in python en het gebruik van het adres XBee (Onthoud dat van deel 1?) om bij te houden. Ik zal vervangen door de code die we net schreef het volgende:

Aan de bovenkant, in plaats van de timer-variabelen, ik heb een volledige klassendeclaratie, en maak een array om te slaan ze:

### sensorgegevens en matrix van geschiedenissen per sensor opslaan
klasse Fiveminutehistory:
def init (zelf, sensornum):
Self.sensornum = sensornum
Self.fiveminutetimer = time.time() # track gegevens meer dan 5 minuten
Self.lastTime = time.time()
Self.cumulativewatthr = 0

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

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

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

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

### een array van geschiedenissen
sensorhistories =]

Wanneer het object wordt geïnitialiseerd met de sensor ID-nummer, het zet ook de twee timers en cumulatieve Watthrs bijgehouden. Ik heb ook een paar hulpfuncties die zal de code schoner

Rechts onder die ik maak een beetje functie om te helpen me maken en deze objecten op te halen. Gegeven een XBee id-nummer of een nieuwe maakt of wordt de verwijzing naar het

### retriever
def findsensorhistory(sensornum):
voor geschiedenis in sensorhistories:
Als history.sensornum == sensornum:
retourneren van de geschiedenis
# geen gevonden, maak het!
geschiedenis = Fiveminutehistory(sensornum)
sensorhistories.Append(History)
retourneren van de geschiedenis

Ten slotte, in plaats van de gemiddelde Watt berekening code geschreven boven, dat wij zal vervangen door het volgende stuk, welke haalt het object en de tracks stroomverbruik met de object-timers

# retreive de geschiedenis voor deze sensor
sensorhistory = findsensorhistory(xb.address_16)
#print sensorhistory

# optellen van de delta-watthr gebruikt sinds de laatste lezing
# Erachter te komen hoeveel watt-uur werden gebruikt sinds de laatste lezing
elapsedseconds = time.time() - sensorhistory.lasttime
dwatthr = (avgwatt * elapsedseconds) / (60,0 * 60,0) # 60 seconden in 60 minuten = 1 uur
sensorhistory.lastTime = time.time()
afdrukken "gebruikt in de laatste \t\tWh", elapsedseconds, "seconden:", dwatthr
sensorhistory.addwatthr(dwatthr)

# Het bepalen van de minuut van het uur (ie 6:42 -> '42')
currminute = (int(time.time())/60) 10%
# Erachter te komen als de vijf minuten sinds onze laatste opslaan
Als (((time.time()-sensorhistory.fiveminutetimer) > = 60,0) en (currminute % 5 == 0)):
# Uitprinten debug gegevens, Wh gebruikt in de laatste 5 minuten
avgwattsused = sensorhistory.avgwattover5min()
afdrukken van time.strftime ("%Y %m %d, % H: %M"), "," sensorhistory.cumulativewatthr,"Wh =", avgwattsused, "W gemiddelde"

# Onze 5 minuten timer reset
sensorhistory.reset5mintimer()

De code in principe fungeert het zelfde behalve nu het niet op meerdere sensorgegevens stikken! Hieronder, mijn twee Kill-per-watt, één met een computer is aangesloten (100W) en een ander met een lamp (40W)

Naar de database!

De App Engine

Dus we willen een netwerkcomputer voor het opslaan van deze gegevens zodat we de gegevens kunnen delen, maar we willen niet echt moet uitvoeren van een server vanuit huis! Wat te doen? Goed zoals eerder vermeld, kunt u Pachube of gelijkaardig, maar zal ik laten zien hoe tot roll-your-own met Google App Engine (GAE). GAE is in feite een gratis mini-webserver worden gehost door Google, die fundamentele webapps zonder het gedoe van het beheer van een databaseserver wordt uitgevoerd. Elke webapp heeft opslag, sommige kaders en Google-accounts kunt gebruiken voor verificatie. Om te beginnen suggereren ik checking out the GAE website, Documentatie, enz. Ik neem aan dat je hebt weg via de tutorials en sprong recht in het ontwerpen van mijn macht gegevens opslag app genaamd Wattcher (een beetje verwarrend dat ik weet)

Ten eerste, het app.yaml -bestand waarin mijn app ziet er als volgt:

toepassing: wattcher
versie: 1
runtime: python
api_version: 1

handlers:
-url: /. *
script: wattcherapp.py

Vrij eenvoudig, maar zegt dat de app maakt gebruik van wattcherapp.py als het bronbestand

Vervolgens zullen we duiken in de python-code voor onze webapp. Ten eerste, het bevat en de index-database. Als u wilt een database maakt, definiëren wij eigenlijk het - in de python bestand-, GAE dan cijfers uit wat voor soort database om te maken voor je door het volgen van deze routebeschrijving (heel anders dan waar zou u de DB afzonderlijk MySQL)

import cgi, datetime

vanuit google.appengine.api importeren gebruikers
vanuit google.appengine.ext importeren webapp
importeren uit google.appengine.ext.webapp.util run_wsgi_app
importeren uit google.appengine.ext db

klasse Powerusage(db. Model):
Auteur = db. UserProperty() # de gebruiker
sensornum = db. IntegerProperty() # kan hebben meerdere sensoren
watt = db. FloatProperty() # elke sturen nieuwste Watt meting
datum = db. DateTimeProperty(auto_now_add=True) # timestamp

We gebruiken de standaard bevat. We hebben een interne databasetabel genaamd Powerusage, en het heeft 4 teams/spelers: een voor de gebruiker, voor het nummer van de sensor, een voor de laatste gemeld watt gebruikt en één voor een datumstempel

Elke 'pagina' of de functie van onze webapp moet zijn eigen klasse. Laten we beginnen met de functie die het mogelijk maakt voor het opslaan van gegevens in de DB. Ik noem het PowerUpdate.

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

# make de gebruiker inloggen
zoniet users.get_current_user():
Self.Redirect(users.create_login_url(Self.Request.URI))

powerusage = Powerusage()

Als users.get_current_user():
powerusage.Author = users.get_current_user()
#print self.request
als self.request.get('watt'):
powerusage.Watt = float(self.request.get('watt'))
anders:
Self.Response.out.write ('Couldnt vinden \'watt\ 'GET eigendom!')
terugkeer
als self.request.get('sensornum'):
powerusage.sensornum = int(self.request.get('sensornum'))
anders:
powerusage.sensornum = 0 # veronderstellen theres één of iets

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

Wanneer we een verzoek te doen sturen dat met een GET noemen zorg (dwz aanvragen van de webpagina), we eerst ervoor dat de gebruiker is geverifieerd en geregistreerd in, zodat we hun naam weten. Vervolgens maken we een nieuwe databasevermelding met het initialiseren van een nieuwe instantiëren van Powerusage. Dan bekijken we het GET-verzoek voor het watt-gegevens, dat zou in de indeling watt = 39,2 of soortgelijk. Dat wordt geparseerd voor ons, gelukkig en kunnen ook we de sensor-nummer dat wordt doorgegeven in de indeling sensornum = 3. Ten slotte kunnen we de gegevens in de permanente database slaan.

Volgende is een handige debugging functie, het zal gewoon uitprinten alle gegevens die zij heeft ontvangen voor uw account!

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

# make de gebruiker inloggen
zoniet users.get_current_user():
Self.Redirect(users.create_login_url(Self.Request.URI))

Self.Response.out.write ("< html >< lichaam > hier is alle gegevens die u ons hebt verzonden: < p >')

powerusages = db. GqlQuery ("SELECT * FROM Powerusage waar Auteur =: 1 ORDER BY datum", users.get_current_user())

voor powerused in powerusages:
Als powerused.sensornum:
Self.Response.out.write ("< b > < /b > %s \'s sensor #%d ' %
(powerused.author.nickname(), powerused.sensornum))
anders:
Self.Response.out.write (< b > < /b > %s' % powerused.author.nickname())

Self.Response.out.write (' gebruikt: %f Watts op %s < p > "% (powerused.watt, powerused.date))
Self.Response.out.write ("</body >< / html >")

Dit werkt gewoon Selecteer (haalt) alle posten, gesorteerd op basis van datum en drukt uit elkaar op een moment

Tot slot maken we een fundamentele 'voorpagina' dat zal tonen de laatste paar datapoints verzonden

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

Self.Response.out.write ("< html >< lichaam > Welkom bij Wattcher! < p > hier zijn de laatste 10 datapoints: < p >')

powerusages = db. GqlQuery ("SELECT * FROM Powerusage ORDER BY datum DESC limiet 10")

voor powerused in powerusages:
Als powerused.sensornum:
Self.Response.out.write ("< b > < /b > %s \'s sensor #%d ' %
(powerused.author.nickname(), powerused.sensornum))
anders:
Self.Response.out.write ("< b > < /b > %s" % powerused.author.nickname())

Self.Response.out.write (' gebruikt: %f Watts op %s < p > "% (powerused.watt, powerused.date))
Self.Response.out.write ("</body >< / html >")

Zijn zeer vergelijkbaar met de functie van de DataDump maar zijn slechts 10 punten van de gegevens en van alle gebruikers, leuk om te gebruiken wanneer je gewoon wilt 'check it out' maar niet om in te loggen

Eindelijk hebben we een beetje initializer structuur die vertelt GAE welke pagina's aan welke functies koppelen

toepassing = webapp. WSGIApplication)
[('/', MainPage)]
('/ verslag', PowerUpdate),
('/ dump', DumpData)],
debug = True)

def main():
run_wsgi_app(Application)

als naam == "belangrijkste":
Main()

Test!

OK laten we het proberen, laat eerst bezoek http://wattcher.appspot.com/report

Herinner me dat wij maakte het een vereiste - sommige - om gegevens te leveren. Laten we proberen opnieuw http://wattcher.appspot.com/report?watt=19.22&sensornum=1

Yay kregen we een OK! Laat uitchecken de gegevens opgeslagen door het bezoeken van http://wattcher.appspot.com/dump

Er is twee vermeldingen want ik heb een beetje testen vooraf maar je kunt zien zijn er 2 ingangen. Leuk!

We kunnen ook ga naar het Configuratiescherm GAE en bladeren van de gegevens 'met de hand'

Hoe dan ook, dat dit werkt, laat ga nu terug en de rapportage technologie aan onze sensor-lezer script toevoegen

Het verslag uitstappen

Alleen een beetje meer hacken op de computer script en we klaar bent. We willen het toevoegen van ondersteuning voor het verzenden van gegevens naar GAE. Helaas nu onze verificatie is gedaan via Google-accounts zijn niet gemakkelijk om te draaien op een Arduino. Aan te passen het zou u moeten sturen de gebruikersnaam in het verslag krijgen en hopen dat niemand anders gebruikt dezelfde (tenzij u ook een fundamentele wachtwoordsysteem toevoegen)

Hoe dan ook, ik totaal opgelicht aan hoe dit uit sommige aardige mensen op het Internet

Appengineauth.py downloaden van de downloadpagina, en de eerste paar regels desgewenst wijzigen. We hardcode de URL van we gonna, evenals de account/wachtwoord en de naam van de app GAE

users_email_address = "MijnAccount]
users_password = "MijnWachtwoord"
my_app_name = "wattcher"
target_authenticated_google_app_engine_uri = 'http://wattcher.appspot.com/report'

Het echte werk gebeurt op deze functie sendreport waar het verbindt en de Watt gegevens stuurt naar de GAE-site

def sendreport (sensornum, watt):
# dit waar ik eigenlijk naartoe is wilt
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 dient de inhoud van de
# target_authenticated_google_app_engine_uri pagina - als wij zal geweest zijn
# automatisch doorgestuurd naar die pagina
#
# om te bewijzen dat dit, I 'm just gonna uitprinten
Afgedrukt van serv_resp_body

Tot slot, we afronden door de volgende regels toe te voegen aan ons computer-script, die de gegevens mooi naar GAE stuurt!

# Ook, stuur het naar de app engine
appengineauth.sendreport (xb.address_16, avgwattsused)

U kunt de definitieve script- wattcher.py - definitieve downloaden van de downloadpagina!

Vergeet niet te bezoeken wattcher.appspot.com om te controleren de nieuwste lezingen

Gerelateerde Artikelen

Hoe maak je een wenskaart van klassieke auto Pop Up kaart (Kirigami 3D)

Hoe maak je een wenskaart van klassieke auto Pop Up kaart (Kirigami 3D)

Hoe maak je een wenskaart Pop Up kaart (Kirigami 3D) klassieke auto - TCGames [HD]Share op FACEBOOK: http://on.fb.me/15TrVYfTWEET: http://bit.ly/15Ts5P6 REDDIT: http://bit.ly/16qHt5L TUMBLR: http://bit.ly/10K8fhzDownload hier het gratis patroon: http
Hoe maak je een trui Lamp

Hoe maak je een trui Lamp

Hey u alle mooie burgers,Ik miste instructables en alle de awesome die jullie hebben. Dus ik ben terug na een goede onderbreking en ik ben terug met een andere opwindende instructable u:).Trui lamp...??? Ja... geen grapje. In dit instructable ga ik o
Hoe maak je een mooie Origami Rose (boeket) voor Valentijnsdag!

Hoe maak je een mooie Origami Rose (boeket) voor Valentijnsdag!

In deze tutorial, ik zal u tonen hoe maak je een origami mooi Rose. Geniet van: D!Share op FACEBOOK: http://on.fb.me/15TrVYfTWEET: http://bit.ly/15Ts5P6REDDIT: http://bit.ly/16qHt5LTUMBLR: http://bit.ly/10K8fhzTips: zorg voor uw plooien aan het begin
Hoe maak je een Origami-gevechtsvliegtuig (papieren vliegtuigje)!

Hoe maak je een Origami-gevechtsvliegtuig (papieren vliegtuigje)!

In deze tutorial, ik zal u tonen hoe maak je een origami gevechtsvliegtuig (papieren vliegtuigje). Geniet van: D!Model: Gevechtsvliegtuig (papieren vliegtuigje)Door: traditioneleShare op FACEBOOK: http://on.fb.me/15TrVYfTWEET: http://bit.ly/15Ts5P6RE
Hoe maak je een Origami papier Jet Plane!

Hoe maak je een Origami papier Jet Plane!

In deze tutorial, ik zal u tonen hoe maak je een origami JET papieren vliegtuigje. Geniet van: D!Model: JET papieren vliegtuigjeDoor: traditioneleShare op FACEBOOK: http://on.fb.me/15TrVYfTWEET: http://bit.ly/15Ts5P6REDDIT: http://bit.ly/16qHt5LTUMBL
Hoe maak je een Origami papier Squid vliegtuig!

Hoe maak je een Origami papier Squid vliegtuig!

In deze tutorial, ik zal u tonen hoe maak je een origami Squid papieren vliegtuigje. Geniet van: D!Model: Squid papieren vliegtuigjeDoor: traditioneleShare op FACEBOOK: http://on.fb.me/15TrVYfTWEET: http://bit.ly/15Ts5P6REDDIT: http://bit.ly/16qHt5LT
Hoe maak je een LED Fairy-Light String met behulp van de MR16

Hoe maak je een LED Fairy-Light String met behulp van de MR16

dit instructable is een super eenvoudige, gemakkelijke en leuke manier om een string van de LED Fairy-licht met behulp van MR16 LED downlighters.Het is ook mijn eerste instructable!, eindelijk na jaren van verschillende DIY en knutselen leuk. ^_^Dus,
Hoe maak je een DIY Tiki fakkel van de sneeuw Ski's

Hoe maak je een DIY Tiki fakkel van de sneeuw Ski's

Een paar ski's van oude van Habitat voor herstel van de mensheid nu een vet gele tiki fakkel, klaar voor onze volgende achtertuin feest is.Mark en ik waren door onze vrienden bij Krylon uitgedaagd om een fakkel tiki van iets out-of-the-gewone.Stap 1:
Hoe maak je een citroen-accu

Hoe maak je een citroen-accu

In dit instructable leert u hoe maak je een citroen-batterij. De citroenen maken ongeveer 4 en een halve volt, genoeg te lopen van iets dat maakt gebruik van lage spanning. De citroenen produceren deze spanning door het proces van elektrolyse is de c
Hoe maak je een Lamp Nuka Cola Quantum

Hoe maak je een Lamp Nuka Cola Quantum

Ik maakte deze lamp als een cadeau voor een zeer goede vriend. Ik maak rekwisieten als een hobbie en besloot: "Ik wil mijn vriend iets!" Ik dacht en dacht over wat te maken van hem, toen drong het tot me dat hij hield van Fallout. Deze prop werd
Hoe maak je een spuit Pen

Hoe maak je een spuit Pen

https://www.YouTube.com/watch?v=qutcj6xwLjo&feature=Youtu.beStap 1: Om te doen een spuit Pen moet je!In deze Instructables ga ik om u te tonen hoe maak je een pen met de spuit!Een handgemaakte pen met de spuit die we moeten maken:-Insuline spuit,-Bal
Hoe maak je een periscoop! / Tutorial / DIY

Hoe maak je een periscoop! / Tutorial / DIY

https://www.YouTube.com/watch?v=Pb24i2mru7c&feature=Youtu.beStap 1: Om te doen een periscoop moet je! In hedendaagse instructables 'm I gonna Toon u het idee van hoe maak je een periscoop.Stap 2: Periscoop is een van de eenvoudigste optische toestell
Hoe maak je een boot van de stoom met een kaars

Hoe maak je een boot van de stoom met een kaars

https://www.YouTube.com/watch?v=sWJqCubW1ic&feature=Youtu.beStap 1: Om te doen een boot van de stoom met een kaars u nodig!In deze instructables ik zal je laten zien een geweldig idee van hoe maak je een boot van de stoom met de kaars.Stap 2: Kindere
Hoe maak je een kleine uil!

Hoe maak je een kleine uil!

Dit instructable leert u hoe maak je een kleine uil! Het was bedoeld als een toegang tot de First-Time Auteur wedstrijd in instructables, maar ik hoop dat velen van u grote vreugde van het vinden! Zodra u klaar bent met uw uil, wat gaat u doen? Zal u