Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

19 Schritt:Schritt 1: Stellen Sie es! Schritt 2: Prep Schritt 3: Stellen Sie den Receiver Schritt 4: Konfigurieren Schritt 5: Löten Sie den Transmitter - Teileliste Schritt 6: Schematische Transmitter Schritt 7: Setzen Sie und erstellen Sie die Sender - 1 Schritt 8: Setzen Sie und erstellen Sie die Sender - 2 Schritt 9: Setzen Sie und erstellen Sie die Sender - 3 Schritt 10: Montieren Sie und erstellen Sie die Sender - 4 Schritt 11: Montieren Sie und erstellen Sie die Sender - 5 Schritt 12: Software Schritt 13: Öffnen Schritt 14: Design - Überblick Schritt 15: Design - hören Schritt 16: Design - Shop Schritt 17: Design - Diagramm Schritt 18: Ressourcen Schritt 19: Download

Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

Dieses Projekt dokumentiert meine Abenteuer in lernen, wie man für die drahtlose Energieüberwachung verdrahten mein Zuhause. Ich lebe in einer Mietwohnung, damit ich nicht Hacking-Zugang zu einem Meter oder Unterbrecher-Platte haben. Da bin ich immer noch sehr interessiert an Mess meinen Stromverbrauch auf einer langfristigen Basis, baute ich drahtlose Steckdose Reportern. Bauen Sie Ihre eigenen Leistungsmonitor ist nicht zu hart und Geld sparen können, aber ich bin kein Fan von kleben meine Finger in 120-V-Strom. Stattdessen werde ich die bestehenden Kill-a-Watt-Netzmonitor, der funktioniert super und ist in meinem örtlichen Baumarkt erhältlich eingesetzt.

Mein Plan ist, sind alle Zimmer mit einem 6-Steckerleiste, die Kräfte alle Geräte in diesem Raum verbunden (jeweils kill-a-Watt kann bis zu 15A zu messen oder zu 1800W, die viel ist!). So kann ich Raum-by-Raumnutzung zu verfolgen, zum Beispiel "Küche", "Schlafzimmer", "Werkbank" und "Büro".

Jedes Wireless Steckdose / Empfänger kann für ~ 55 € mit ein paar leicht zugängliche elektronische Teile und Licht Löten eingebaut werden, ist nicht Mikrocontroller-Programmierung oder Hochspannungstechnik erforderlich!

Sie können mein Setup inklusive Diagramme und Berichte zu sehen http://twitter.com/tweetawatt

Wenn Sie möchten, um ein für sich selbst bauen

1. Kaufen Sie ein Set : erhalten Sie alle Teile, die Sie benötigen, ist ein Starter-Kit an der adafruit webshop
2. Fabrikat: drehen Sie jeden Kill-a-Watt in eine drahtlose Netz Füllstandmessumformer
3. Software: Download und führen Sie es auf Ihrem Computer, um Daten zu erhalten, und speichern Sie es in eine Datei und / oder veröffentlichen

Wenn Sie wissen, wie es gemacht wurde möchten, finden Sie unter:

1. Hören Sie: Schreiben Sie einfache Software für den Computer (oder Arduino, etc), um Signal hören und berechnen Sie die aktuelle Stromverbrauch
2. Store: Erstellen Sie eine Datenbank-Backend, das den Stromverbrauch für die langfristige Analyse zu speichern wird http://wattcher.appspot.com
3. View: Graph und zu verstehen, Trends in der Energieverbrauch

Schauen Sie sich die neuesten Messwerte bei http://wattcher.appspot.com

Schritt 1: Stellen Sie es!

  1. Bevor du anfängst...

    Sie sollten nur das Projekt, wenn Sie versuchen, komfortabel und kompetente Arbeit mit Hochspannung Strom, Elektronik und Computer sind. Sobald das Projekt abgeschlossen ist es eingeschlossen ist und es gibt keine hohen Spannungen ausgesetzt. Allerdings müssen Sie nur an dem Projekt arbeiten, wenn sein nicht eingesteckt und nie versuchen, zu testen, zu messen, zu öffnen oder zu sondieren die Leiterplatten, während sie an eine Steckdose angeschlossen sind Wenn etwas nicht funktioniert:. Zu stoppen, nehmen Sie ihn aus die Wand Macht, dann öffnen Sie es und zu untersuchen. Ja, es noch ein paar Minuten dauert, aber es ist viel sicherer!

    Ihre Sicherheit ist in Ihrem Verantwortungsbereich, einschließlich der ordnungsgemäßen Verwendung von Geräten und Schutzausrüstung, und festzustellen, ob Sie über ausreichende Fähigkeiten und Erfahrungen haben. Elektrowerkzeuge, Elektrizität und andere für diese Projekte eingesetzten Mittel sind gefährlich, wenn nicht einwandfrei und mit angemessenen Schutzmaßnahmen, einschließlich der Fangvorrichtung verwendet. Einige anschauliche Fotos nicht Vorsichtsmaßnahmen oder Geräte darstellen, um zu zeigen, das Projekt Schritte deutlicher. Dieses Projekt ist nicht zur Verwendung durch Kinder bestimmt.

    Die Nutzung der Anleitung und Anregungen ist auf eigene Gefahr. Adafruit Industries LLC, übernimmt keine Haftung für eventuelle Schäden, Verletzungen oder Kosten. Sie sind dafür verantwortlich, sicherzustellen, dass Ihre Aktivitäten mit den geltenden Gesetzen entsprechen.

    OK, wenn Sie zustimmen können wir weitermachen!

    Machen Sie einen Tweet-a-Watt-

    Um den Tweet-a-Watt-Setup zu machen, müssen wir durch ein paar Schritte gehen

    1. Bereiten Sie indem Sie sicherstellen, wir haben alles, was wir brauchen, und wissen, die erforderlich sind, um das Projekt zu erstellen Fähigkeiten
    2. Erstellen Sie das Setup-Empfänger durch Löten einen der Adapter-Kits
    3. Konfigurieren Sie die XBee Funkmodems
    4. Erstellen Sie die Sender-Setup, indem Sie einen Kill-a-Watt über das XBee übertragen
    5. Starten Sie die Software, die Daten abruft und speichern Sie es in eine Datei, laden Sie sie auf einer Datenbank und / oder twitter

Schritt 2: Prep

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tutorials

    Erfahren Sie, wie mit Tonnen von Tutorials zu löten!
    Vergessen Sie nicht, um zu lernen, wie Sie Ihre Multimeter zu verwenden!

    Tools

    Es gibt einige wenige Werkzeuge, die für die Montage erforderlich sind. Keines dieser Tools sind im Lieferumfang enthalten. Wenn Sie diese nicht haben, wäre jetzt ein guter Zeitpunkt, um zu leihen oder kaufen sie. Sie sind sehr sehr praktisch, wenn Montage / Befestigung / Modifizieren elektronischer Geräte! I Links zu ihnen zu kaufen, aber natürlich sollten Sie sie erhalten, wo immer am bequemsten / preiswert. Viele dieser Teile sind in einem Ort wie Radio Shack oder andere (höhere Qualität) DIY Elektronik-Fachgeschäften erhältlich.

    Ich empfehle eine "basic" Elektronik Werkzeugsatz für dieses Kits, die ich hier beschreibe.

    Lötkolben. One mit Temperaturregelung und einem Stand am besten ist. Ein konischer oder kleine "Schraubendreher" Spitze ist gut, fast alle Eisen werden mit einer von ihnen.

    Ein niedriger Qualität (ähem, € 10 Modell aus Radioshack) können Eisen mehr Probleme als seinen Wert führen!

    Verwenden Sie keine "Coldheat" Lötkolben, sind sie nicht geeignet für empfindliche Elektronik der Arbeit und kann das Kit beschädigt werden ( siehe hier )

    Solder. Rosin Kern, 60/40. Gute Lot ist eine gute Sache. Bad Lot führt zu Brückenbildung und kalte Lötstellen, die schwer zu finden sein kann. Kaufen Sie nicht eine winzige Menge, werden Sie laufen aus, wenn Sie es am wenigsten erwarten. Ein halbes Pfund Spule ist ein Minimum.

    Multimeter / Oszilloskop. Ein Meter ist hilfreich, um Spannungen und Kontinuität zu überprüfen.

    Flush / Seitenschneider. Wesentlich für Schneid Leitungen in der Nähe der Leiterplatte.

    Entlötwerkzeug. Wenn Sie sind anfällig für falsch Lötteile.

    "Handy-Hands 'mit Lupe. Nicht unbedingt erforderlich, aber die Dinge gehen viel schneller.

    Überprüfen Sie heraus meine empfohlenen Werkzeuge und wo zu kaufen.

    Gutes Licht. Wichtiger als man denkt.

Schritt 3: Stellen Sie den Receiver

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 9 Artikel anzeigen
    Überblick

    Wir werden mit der Empfänger-Hardware zu starten, das ist die Sache, die in den Computer angeschlossen und die Daten von der drahtlosen Netzstecker empfängt. Die Empfänger-Hardware bedeutet "doppelte Aufgabe", es auch verwendet, um die XBee der Modems 'Firmware (die leider ist notwendig, weil sie kommen ab Werk mit wirklich alten Firmware) und konfigurieren Sie die Modems aktualisieren.

    Was Sie brauchen

    Der Empfänger ist im Wesentlichen ein XBee, mit USB-Anschluss, um einem Computer auf, um es der XBee sprechen.

    Nennen FTDI Kabel
    Beschreibung Ein USB-Seriell-Konverter. Plugs in ordentlich in die Adafruit XBee-Adapter, damit ein Computer mit dem XBee sprechen.
    Datenblatt TTL-232R 3,3 V oder 5,0 V
    Distributor Mouser
    Anzahl 1

    Nennen Adafruit XBee Adapter-Kit
    Beschreibung Ich werde mit meinem eigenen Entwurf für das XBee breakout / Trägerplatte, aber Sie fast jede Art so lange verwenden können, wie Sie alle fehlenden Teile wie the3.3V Versorgung und LEDs zu replizieren
    Sie werden 2 Adapter Kits haben, aber Sie sollten nur dann montieren einem für diesen Teil! Der andere muss verschiedene Anweisungen so einfach zu warten!
    Datenblatt Webseite
    Händler Adafruit
    Anzahl 1

    Nennen XBee-Modul
    Beschreibung Wir werden mit dem XBee "Serie 1" Punkt-zu-Mehrpunkt-802.15.4-Module mit einer Chip-Antenne Teil # XB24-ACI-001. Sie sind kostengünstig und lassen sich gut. Dieses Projekt wahrscheinlich nicht mit einer anderen Version des XBee arbeiten, und schon gar nicht eine der 'High Power' Pro Orte!
    Datenblatt
    Händler Adafruit
    Anzahl 1

    Löten Sie den Adapter zusammen!

    Dieser Schritt ist ziemlich einfach, gehen Sie einfach auf, um die XBee-Adapter die Homepage und löten sie zusammen nach den Anweisungen!

    Denken Sie daran: Sie erhalten 2 Adaptersätze haben, aber Sie sollten nur löten einer von ihnen an dieser Stelle! Der andere muss verschiedene Anweisungen so einfach zu warten!

    Verbinden mit dem XBee

    Nun ist es Zeit, um zu den XBees verbinden

    Finden Sie Ihr FTDI Kabel - entweder 3,3V oder 5V. Diese Kabel haben einen USB-Seriell-Konverter-Chip in sie geformt und werden von jedem Betriebssystem unterstützt. So konfigurieren oder aktualisieren oder den Anschluss ist wirklich trivial. Stecken Sie einfach das Kabel in das Ende des Moduls, so dass die schwarzen Adern mit GND. Es gibt eine weiße Umrandung zeigt, wo das Kabel verbindet.

    Sie müssen herausfinden, welche serielle Schnittstelle (COM) Sie verwenden. Stecken Sie das FTDI-Kabel, USB-Adapter, Arduino etc. unter Windows, überprüfen Sie den Geräte-Manager, suchen Sie nach "USB Serial Port"

    Digi / Maxstream schrieb ein kleines Programm, um zu konfigurieren XBees, sein auch der einzige Weg, die ich kenne, um sie auf die neueste Firmware zu aktualisieren. Leider ist es nur unter Windows. Download von X-CTU von Digi und installieren es auf Ihrem Computer

    Nach der Installation und dem Start des Programms wählen Sie den COM-Port (COM4 hier) und Baudrate (9600 ist Standard). Keine Flusskontrolle, 8N1. Sicherstellen, dass der Anschluss-Box sieht aus wie das Bild (mit Ausnahme des COM-Port, die verschieden sein können)

    Um zu überprüfen, klicken Sie auf Test / Abfrage-

    Hoffentlich wird der Test erfolgreich zu sein. Wenn Sie Probleme haben: überprüfen, ob die XBee mit Strom versorgt wird, leuchtet die grüne LED auf der Adapterplatine sollte blinken, der richtige COM-Port und Baudrate ausgewählt ist, usw.

    Jetzt ziehen Sie den Adapter aus dem FTDI Kabel, sorgfältig zu ersetzen das erste XBee mit dem anderen und stellen Sie sicher, dass man im Gespräch auch in Ordnung. Sobald Sie wissen beide XBees werden mit dem Adapter arbeitet, um seine Zeit zu aktualisieren und konfigurieren Sie sie, den nächsten Schritt!

Schritt 4: Konfigurieren

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 14 Artikel anzeigen
    Überblick

    OK, so weit Sie eine der XBee-Adapter-Boards montiert und angeschlossen an Ihren Computer mit dem FTDI Kabel. (Der andere Adapter ist für die spätere so gar nichts mit ihm zu tun noch!) Die XBees reagieren auf die X-CTU-Software und blinken just fine. Als nächstes werden wir die Aktualisierung der Firmware

    Aktualisieren der Firmware

    Es gibt eine gute Chance, Ihren XBees sind nicht mit der neuesten Firmware und es gibt eine Menge von Funktionen hinzugefügt, von denen einige die wir brauchen, um dieses Projekt zum Laufen zu bringen. Also nächstes ist ein Upgrade!

    Öffnen Sie die Registerkarte Modem Konfiguration. Dies ist, wo das Modem konfiguriert und aktualisiert,

    Klicken Sie auf Herunterladen neuer Versionen ... und wählen Sie, um die neuesten Firmware aus dem Internet herunterladen

    Sobald Sie die neueste Firmware heruntergeladen haben, seine Zeit zu aktualisieren!

    Klicken Sie auf Modem-Parameter -> "Lesen", um in der aktuellen Version und Einstellungen lesen

    Jetzt werden Sie sicher wissen, welche Funktion Set, Version und Einstellungen im Modem gespeichert sind,

    Wählen Sie aus dem Dropdown Version die neueste Version verfügbar

    Überprüfen Sie die Firmware-Update-Option Always

    Und klicken Sie anschließend zu initialisieren und programmieren die neue Firmware in!

    Das ist es, jetzt die neueste Firmware für Ihr Modem Sie haben. Sie sollten nun deaktivieren Sie das Kontrollkästchen Immer Firmware aktualisieren. Bei Problemen, wie zum Beispiel eine Zeitüberschreitung oder nicht in der Lage zu kommunizieren haben, stellen Sie sicher, dass der RTS Pin up richtig verdrahtet wie dieser Stift ist notwendig für das Upgrade. FTDI Kabel sind bereits für diesen Satz so sollten Sie nicht ein Problem haben

    Spülen & Repeat

    Aktualisieren Sie die Firmware auf beiden XBees so sind sie beide auf dem neuesten Stand

    An diesem Punkt könnte es klug, um die beiden XBees in einer Weise, dass Sie ihnen sagen, abgesehen lässt markieren. Sie können einen Sharpie, einen Aufkleber oder ähnliches verwenden, um anzugeben, welche eine ist der Empfänger und der der Sender

    Konfigurieren Sie den Sender XBee

    Beide XBee die Notwendigkeit, mit der neuesten Firmware, sondern nur den Sender (die gehen, um in einem Tötungs-a-Watt gesetzt werden) konfiguriert werden muss aufgerüstet werden. Das configure-Prozess teilt dem XBee was Stifte wir die Sensordaten aus der gelesen werden soll. Es erzählt auch die XBee, wie oft an uns zu senden Daten, und wie viel.

    Stecken Sie den Sender XBee in den USB-Anschluss (den Hörer XBee entfernt) und starten Sie X-CTU oder ein Terminalprogramm. Schließen Sie bei 9600 Baud, 8N1 parity.Then konfigurieren jedes wie folgt:

    1. Stellen Sie die MY-Adresse (die Kennung für das XBee) bis 1 (erhöht dies für jeden Sender, so dass Sie sie auseinander zu halten, werden wir annehmen, dass Sie nur eine bis jetzt)
    2. Stellen Sie den Energiesparmodus SM bis 4 (Cyclic Schlaf)
    3. Stellen Sie die Schlafzeit ST bis 3 (3 Millisekunden nach wakeup um wieder einzuschlafen)
    4. Stellen Sie die Schlafperiode SP bis C8 (0xC8 hexadezimal = 200 x 10 ms = 2 Sekunden zwischen trägt)
    5. Stellen Sie ADC 4 D4 bis 2 (analog / digital Sensor Enable-Pin AD4)
    6. Stellen Sie ADC 0 D0 bis 2 (Analog / Digital-Sensor Enable-Pin AD0)
    7. Stellen Proben zu TX IT bis 13 (0x13 = 19 A / D-Proben pro Paket)
    8. Stellen Sie die IR Sample Rate bis 1 (1 ms zwischen A / D-Proben)

    wenn Sie denken, es wird mehr XBee in der Gegend, die bei der Installation in Konflikt geraten könnte man sich auch,

    1. Stellen Sie den PAN-ID, um eine 4-stellige Hex-Zahl (seine 3332 standardmäßig aktiviert)

    Sie können dies mit X-CTU oder mit einem Terminalprogramm wie zB Hyperterm, minicom, ZTerm usw. mit der Befehlsfolge zu tun
    Atmy = 1, SM = 4, ST = 3, SP = C8, D4 = 2 D0 = 2, IT = 13, IR = 1
    Sie müssen, indem sie das Modem Aufmerksamkeit warten Sie 10 Sekunden startet, dann Eingabe +++ schnell, dann eine Pause für weitere 5 Sekunden. Dann verwenden Sie AT um sicherzustellen, dass seine Zahlung AT tention auf Ihre Befehle

    Im Grunde, was das bedeutet, ist, dass wir alle auf einem einzigen XBees PAN-Netzwerk haben, wird jede XBee eine eindeutige Kennung haben, werden sie in den Schlafmodus die meiste Zeit zu bleiben, dann aufwachen alle 2 Sekunden bis 19 Proben zu nehmen ADC 0 und 4, 1 ms auseinander liegen. Wenn Sie Schwierigkeiten haben, stellen Sie sicher, dass Sie die Firmware-Upgrade!

    Stellen Sie sicher, um die Konfiguration auf der XBee permanenten Speicher SCHREIBEN, sobald Sie es getan haben. Wenn Sie mit X-CTU auf die Schaltfläche "Schreiben" in der oberen linken. Wenn Sie mit einem Terminal, verwenden Sie den Befehl ATWR!

    Beachten Sie, dass, sobald das XBee wird gesagt, um in den Ruhemodus, müssen Sie es zurücksetzen, um zu reden, denn sonst wird es nicht zu reagieren und X-CTU wird sich beschweren. Sie können einfach ziehen Sie den Adapter aus dem FTDI Kabel zurückzusetzen oder berühren Sie einen Draht zwischen den RST und GND-Pins an der Unterkante des Adapters.

    Nun, da die Sender sind alle Setup mit einzigartigen MY Anzahl IDs, stellen Sie sicher, dass, während sie von der Stromversorgung über USB grüne LED blinkt einmal alle 2 Sekunden (was anzeigt, Wakeup und Daten senden)

    Konfigurieren Sie die Empfänger XBee

    Stecken Sie den Empfänger XBee in den USB-Anschluss (den Hörer XBee entfernt) und starten Sie X-CTU . Wenn Sie den PAN-ID im vorherigen Schritt festgelegt, müssen Sie hier das gleiche machen

      Stellen Sie den PAN-ID, um die gleiche Hex-Zahl wie oben Wenn Sie den PAN oben nicht ändern können, dann gibt es nichts für Sie zu tun, einfach diesen Schritt überspringen

      Nächster!

      Nun, da die XBees konfiguriert und bereit, seine Zeit, um zum nächsten Schritt zu gehen, wo wir den Kill-a-Watt-Hardware

Schritt 5: Löten Sie den Transmitter - Teileliste

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 11 Artikel anzeigen
    Bevor du anfängst...

    Sie sollten nur das Projekt, wenn Sie versuchen, komfortabel und kompetente Arbeit mit Hochspannung Strom, Elektronik und Computer sind. Sobald das Projekt abgeschlossen ist es eingeschlossen ist und es gibt keine hohen Spannungen ausgesetzt. Allerdings müssen Sie nur an dem Projekt arbeiten, wenn sein nicht eingesteckt und nie versuchen, zu testen, zu messen, zu öffnen oder zu sondieren die Leiterplatten, während sie an eine Steckdose angeschlossen sind Wenn etwas nicht funktioniert:. Zu stoppen, nehmen Sie ihn aus die Wand Macht, dann öffnen Sie es und zu untersuchen. Ja, es noch ein paar Minuten dauert, aber es ist viel sicherer!

    Ihre Sicherheit ist in Ihrem Verantwortungsbereich, einschließlich der ordnungsgemäßen Verwendung von Geräten und Schutzausrüstung, und festzustellen, ob Sie über ausreichende Fähigkeiten und Erfahrungen haben. Elektrowerkzeuge, Elektrizität und andere für diese Projekte eingesetzten Mittel sind gefährlich, wenn nicht einwandfrei und mit angemessenen Schutzmaßnahmen, einschließlich der Fangvorrichtung verwendet. Einige anschauliche Fotos nicht Vorsichtsmaßnahmen oder Geräte darstellen, um zu zeigen, das Projekt Schritte deutlicher. Dieses Projekt ist nicht zur Verwendung durch Kinder bestimmt.

    Die Nutzung der Anleitung und Anregungen ist auf eigene Gefahr. Adafruit Industries LLC, übernimmt keine Haftung für eventuelle Schäden, Verletzungen oder Kosten. Sie sind dafür verantwortlich, sicherzustellen, dass Ihre Aktivitäten mit den geltenden Gesetzen entsprechen.

    OK, wenn Sie zustimmen können wir weitermachen!

    Transmitter Stückliste

    Für jeden Ausgang die Sie überwachen wollen, müssen Sie:

    Name: Kill-a-Watt
    Beschreibung: "von der Stange" Modell P4400 Leistungsmonitor
    Datenblatt: P3 Kill-a-Watt-
    Vertrieb: Viele! Überprüfen Sie auch Hardware / Elektronik-Läden
    Anzahl Lizenzen: 1

    Name: Adafruit XBee Adapter
    Beschreibung: Ich werde mit meinem eigenen Entwurf für das XBee breakout / Trägerplatte, aber Sie fast jede Art so lange verwenden können, wie Sie alle fehlenden Teile wie the3.3V Versorgung und LEDs zu replizieren
    Datenblatt: Webpage
    Distributor: Adafruit
    Anzahl Lizenzen: 1

    Name: XBee-Modul
    Beschreibung: Wir werden mit dem XBee "Serie 1" Punkt-zu-Mehrpunkt-802.15.4-Module mit einer Chip-Antenne Teil # XB24-ACI-001. Sie sind kostengünstig und lassen sich gut. Dieses Projekt wahrscheinlich nicht mit einer anderen Version des XBee arbeiten, und schon gar nicht eine der 'High Power' Pro Orte!
    Distributor: Adafruit
    Anzahl Lizenzen: 1

    Name: D3
    Beschreibung: 1N4001-Diode. Alle Leistungsdiode sollte okay sein. Heck, sollte einmal ein 1N4148 oder 1N914 OK sein. Aber 1N4001 vorgeschlagen und ist in dem Kit.
    Datenblatt: Generische 1N4001
    Distributor: Digikey Mouser
    Anzahl Lizenzen: 1

    Name: D2
    Beschreibung: Große diffuse LED, für einfache Betrachtung. Das Kit kommt mit grün.
    Anzahl Lizenzen: 1

    Name: C3
    Beschreibung: 220uF 4V oder höher (Foto zeigt 100uF)
    Datenblatt: Generische
    Distributor: Digikey Mouser
    Anzahl Lizenzen: 1

    Name: C4
    Beschreibung: 10,000uF Kondensator (wow!) / 6.3V (Foto zeigt eine blosse 2200uF) Versuchen Sie, 16 mm Durchmesser zu erhalten, 25mm lang
    Datenblatt: Generische
    Distributor: Digikey [Mouser]
    Anzahl Lizenzen: 1

    Name: R4 R6
    Beschreibung: 10K 1 / 4W 1% Widerstand (braun schwarz schwarz rot gold) oder 10K 1 / 4W 5% Widerstand (braun schwarz orange gold). 1% ist bevorzugt, aber 5% ist OK
    Datenblatt: Allgemein
    Distributor: Mouser Digikey
    Menge: 2

    Name: R3 R5
    Beschreibung: 4.7K 1 / 4W 1% Widerstand (gelb violett braun gold) oder 4.7K 1 / 4W 5% Widerstand (gelb violett rot gold). 1% ist bevorzugt, aber 5% ist OK.
    Datenblatt: Allgemein
    Distributor: Mouser Digikey
    Menge: 2

    Name: Flachbandkabel
    Beschreibung: Flachbandkabel oder andere flexible Draht, mindestens 6 Leiter, etwa 6 "long
    Datenblatt: Generische Ribbon
    Distributor: Digikey
    Menge: 6 "

    Name: Schrumpf
    Beschreibung: Schrumpf! Ein paar Zoll von 1/8 "und 1/16" jeder
    Datenblatt: Allgemein

    Es wird laufen Sie ca. € 50- € 60 für jeden Ausgang

Schritt 6: Schematische Transmitter

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...
    Das XBee Funk tut all die harte Arbeit, hört es auf zwei analoge Eingänge (AD0 und AD4) für Spannungs- und Stromdaten. Dann überträgt sie diese Informationen drahtlos an den Host-Computer Empfänger XBee. Es gibt ein paar, müssen wir um Ingenieur, damit es funktioniert:

    1. Wir wollen die XBee off interne Stromversorgung des Kill-A-Watt laufen. Doch seine aktuelle beschränkt und wird nicht bieten 50 mA in einem Ausbruch, wenn die XBee trägt. Wir lösen dies durch Hinzufügen einer einfachen "Akku" in Form eines wirklich großen Kondensator C4.

    2. The Kill-a-Watt arbeitet mit 5V aber XBees kann nur bei 3,3 V laufen, so haben wir einen Spannungsregler IC1 und zwei Kondensatoren zwei Stabilisierung des 3,3 V, C1 und C2.

    3. Das XBee wird alle paar Sekunden zu übertragen, auch während der Kondensator aufgeladen wird. Das bedeutet, dass es zu halten Ablassen des Kondensators, das Zurücksetzen und erneut versuchen, im Grunde ausgeflippt, während die Stromversorgung noch im Aufbau. Wir verhindern, indem du eine andere ziemlich große Kondensator C3 auf der Reset-Leitung. Dies verlangsamt die XBee, Verzögerung der Inbetriebnahme von wenigen Sekunden und hält die XBee vom Anfahren bis wir haben solide Leistung.

    4. Die XBee analoge Sensoren laufen bei 3,3 V, aber das Kill-a-Watt-Sensoren bei 5V laufen. Wir verwenden einfache Spannungsteiler R3 / R4 und R5 / R6, das analoge Signal auf ein vernünftiges Maß zu reduzieren

Schritt 7: Setzen Sie und erstellen Sie die Sender - 1

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 7 Artikel anzeigen
    Öffnen Sie Ihre Kit und erhalten Sie die Teile für den Sender. Denken Sie daran, dass wir benutzen die meisten, aber nicht alle von einem XBee-Adapter-Kit. Die zwei kleinen LEDs, die 74HC125N Chip, ein 10K und 1K Widerstand werden nicht verwendet und Sie sollten sie beiseite zu legen für ein zukünftiges Projekt, so dass Sie nicht versehentlich hier verwenden Sie sie.

    Überprüfen Sie, ob Sie alles, was Sie haben. Das einzige, was hier nicht dargestellt ist die XBee Radio und Kill-a-Watt.

    Legen Sie das PCB der Adapter-Kit und bereiten Sie sich durch Erhitzen Lötkolben und Vorbereitung Ihrer Handwerkzeuge löten

    Wir werden durch Löten in der 3,3 V-Regler, der identisch mit dem Standard-XBee Adapter Kit Sie in den Receiver Anweisungen gemacht ist zu starten. Vergessen Sie nicht, um die Polarität des C2 überprüfen und dass IC1 ist in der richtigen Weise. Dann löten und Clip die drei Komponenten.

    Jetzt werden wir von den Standard XBee Adapter Anweisungen veer und fügen Sie eine viel größere LED auf der ASC Linie, so dass wir leicht sehen, es blinkt, wenn seine in der Kill-a-Watt. Achten Sie darauf, für die LED-Polarität zu sehen, weil ein nach hinten LED wird die Fehlersuche sehr schwierig. Die längere Vorlauf geht im Lot + markierte Loch.

    Geben Sie die LED etwa einen halben Zoll von Raum über das Ende der Leiterplatte, wie gezeigt. Auch Lot in der passenden 1K Widerstand R2

    Solder in den beiden 2mm 10pin Buchsenleisten in der Adapter-Kit. Seien Sie vorsichtig mit dem Lot, so dass Sie nicht versehentlich die Buchsenleiste füllen. Verwenden Sie eine geringe Menge, um sicherzustellen, gibt es eine Verbindung, sondern seine nicht überfüllt

Schritt 8: Setzen Sie und erstellen Sie die Sender - 2

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 12 Artikel anzeigen
    Nun ist es Zeit, um die Drähte, die wir für die nächsten Haltestellen vorzubereiten. Verwenden Sie Ihre Seitenschneider aus dem Ende des Regenbogens Flachbandkabel im Kit Kerbe von den braun, rot, orange und gelb Drähte.

    Dann reißen Sie die vier Adern vom Rest des Kabels.

    Machen Sie dasselbe für den schwarzen und weißen Drähten und der einzigen grünen Draht. Dann schneiden Sie den grünen Draht so seine nur ca. 1,5 "lang. Sie sollten nun 3 Streifen aus Draht, einem 6" mit 4 Leitern, einem 6 "mit 2 Leitern und einem 1,5" mit 1 Leiter

    Verwenden Sie wirestrippers, um die Enden der grünen Draht von den Enden Streifen, 1/4 "

    Dann tin der grüne Draht durch Erwärmen der Enden des Drahtes und die Anwendung ein wenig Lötzinn zu binden zusammen die Litze.

    Verwenden Sie das grüne Kabel, um eine Brücke zwischen dem VREF-Pin, 7. von oben auf der rechten und auf der linken oberen der VCC Pin erstellen.

    Überprüfen Sie, um sicherzustellen, dass Sie diese richtig zu machen! Dann löten Sie sie fest. Dadurch wird der Bezugspunkt des Analogwandler auf 3,3 V eingestellt

    Zurück zum 4-teilige Flachbandkabel. Teilen Sie die Enden mit dem Seitenschneider, dann Streifen und Zinn Alle 8 endet.

    Setzen Sie ein 4.7K Widerstand in einem Schraubstock oder Halter, dann Clip ein Ende ab und Zinn es wie die Drähte.

    Schneiden Sie ein 1/2 "Stück 1/16" Schrumpf und schieben Sie auf die gelbe Leitung, um sicherzustellen, gibt es Freiraum zwischen dem Schrumpfschlauch und dem Ende des Drahtes. Löten Sie dann das gelbe Kabel an die 4.7k Widerstand.

    Machen Sie dasselbe für das orange Kabel und das andere 4.7K Widerstand. Verwenden Sie eine Wärmequelle (ein Heißluftgebläse oder Fön ist perfekt), um den Schrumpfschlauch über die gelöteten Draht / Widerstand schrumpfen joint.Then den Widerstand 90 Grad biegen und Clip das andere Ende der 4.7K Widerstände

Schritt 9: Setzen Sie und erstellen Sie die Sender - 3

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 8 Artikel anzeigen
    Nun werden wir den Spannungsteiler zu bauen. Nehmen Sie die beiden 10K Widerstände und schließen Sie sie wie gezeigt. Man geht von AD0 und eine von AD4. Sowohl dann eine Verbindung zu Boden. Günstig ist der Chip sind wir nicht mit Masse hatte Stifte, damit wir "Wiederverwendung" jene Stifte.

    Jetzt kommt der schwierige Teil. Wir wollen das andere Ende des 4.7K Widerstand mit dem Stift verbinden AD0 aber die 10K-Widerstand ist schon da. Verwenden Sie Ihre Lötkolben, ein Klecks Lot auf der Spitze des 10K-Widerstand schmelzen und dann huckepack die 4.7K Widerstand durch Löten an der Spitze des 10K-Widerstand.

    Löten Sie das orange Kabel an den AD0 Stift, das Gelb an den AD4

    Die anderen zwei Drähte für die Stromversorgung. Der rote Draht sollte auf der Unterseite der Adapterplatine der + 5V Pin angelötet werden. Das braune Kabel mit dem GND-Pin.

    Wir sind fast mit dem Adapter Löten erfolgen. Schließlich ist die 220uF Rückstellkondensators. Wir werden diese an den RST-Pin, 5. von oben auf der linken Seite zu verbinden. Sicherstellen, dass die langen Leitung ist mit dem RST-Pin verbunden und die kürzeren Vorlauf geht zum 4. Stift wo der Chip gehen würde. Überprüfen Sie das Foto auf der linken Seite, um sicherzustellen, Sie haben es in Recht habe.

    Der Kondensator wird nicht unterhalb des XBee-Modul passen, so geben ihm eine Leitungslänge, so dass der zylindrische Groß ist neben dem 3,3 V-Regler.

    Zum Vergleich, die folgenden Bilder zeigen, was die Rück aussehen sollte.

    ... Und was es sein sollte, wie mit dem XBee Modem installiert aussehen. Achten Sie darauf, die Stifte auf dem XBee Linie mit der Kopfzeile.

Schritt 10: Montieren Sie und erstellen Sie die Sender - 4

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 10 Artikel anzeigen
    Jetzt ersetzen Sie die Platine mit der großen Kapazität.

    Clip die langen Leitungen nach unten. Sie müssen das nutzen "-" Streifen zu verfolgen, welche Stift ist negativ und der positiv ist zu halten.

    Tin sowohl führt mit Lot.

    Löten Sie das andere Ende des roten Band Draht (das geht an + 5V auf der XBee-Adapter) an die positive Stift des Kondensators.

    Löten Sie dann das braune Kabel (wird mit GND auf der XBee-Adapter) mit dem negativen Stift.

    Clip der Kathode führen hinunter des 1N4001 Diode, das ist das Ende mit dem weißen Streifen. auf sie. Löten die Diode, so daß der Weißstreifenseite mit dem Pluspol des großen Kondensator.

    Nehmen Sie die Schwarzweiss-Band von früher. Split, Streifen und Zinn die vier Enden. Schneiden Sie ein 1 "Stück 1/8" Schrumpfschlauch und schieben Sie sie auf das weiße Kabel. Öffnen Sie mit einem 1/2 "Stück 1/16" Schrumpfschlauch auf den schwarzen Draht.

    Clip das andere Ende der Diode (die Seite ohne weißen Streifen) und löten den weißen Draht zu ihm. Löten Sie das schwarze Kabel an den negativen Stift des großen Kondensator.

    Jetzt schrumpfen die Schrumpfschlauch, so dass die Kondensatorleitungen und Diode sind abgedeckt.

    Also gut, hier ist was Sie sollten, einen Adapter mit zwei Sensorzeilen (orange und gelb) hängen vor und zwei Stromleitungen (rot und braun), die auf dem großen Kondensator verbunden sind. Dann gibt es zwei Schwarz-Weiß-Leitungen mit dem Kondensator verbunden, der weiße durch eine Diode.

Schritt 11: Montieren Sie und erstellen Sie die Sender - 5

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 16 Artikel anzeigen
    Jetzt wird es Zeit, das Kill-a-Watt zu öffnen! Es gibt nur 3 Schrauben, mit denen sie zusammenhalten, und sie sind auf der Rückseite zu finden.
    Jetzt wird es Zeit, das Kill-a-Watt zu öffnen! Es gibt nur 3 Schrauben, mit denen sie zusammenhalten, und sie sind auf der Rückseite zu finden.
    Verwenden Sie einen 3/8 Bohrer ein Loch in der Nähe der rechten Ecke der Gehäuserückseite zu machen. Dies ist, was die LED aus bleiben. (Ignorieren Sie das weiße Band und # 4, das ist ein Recycling-Kill-a-Watt :)
    Jetzt finden Sie die LM2902N Chip. Dies ist ein Quad-Operationsverstärker, der die Stromleitung Nutzung erfasst. Wir fahren nach huckepack gehen rechts oben auf ihm, und leihen den Boden, Energie 5V und 2 Sensorausgänge!
    Mit Lötkolben, Schmelz ein bisschen löten an Pin 1, 4, 11 und 14 des Chips. Stellen Sie sicher, dass Sie den Chip richtig ausgerichtet haben, zeigt die Kerbe, wo die Stifte 1 und 14
    Löten Sie den weißen Draht (5 V an die XBee) auf Pin 4. Solder das schwarze Kabel (Masse), um direkt über Pin 11.
    Löten Sie nun das gelbe Kabel an Pin 1 und das orange Kabel an Pin 14.
    Verwenden Sie zwei kleine Stücke von klebrigen Schaum und kleben Sie sie auf die Rückseite des Gehäuses.
    Dann legen Sie die XBee-Adapter und Kondensator auf dem Band, so dass der LED-Sticks aus dem Loch früher gebohrt
    Verstauen Sie die überschüssige Bandkabel aus dem Weg, so dass sie nicht in der Nähe der 120-V-Verbindungen, die machen könnte ihnen gehen puh.
    Schließen Sie es und stecken Sie es in.
    Sie werden feststellen, es ist ein bisschen pingelig für einige Sekunden wie die großen Kondensator auflädt. Die Anzeige kann nicht kommen für 15-30 Sekunden, und sie kann in die und aus den ersten verblassen. Die Zahlen können auch falsch für ein bisschen, wie es hochgefahren sein. Innerhalb von 30 Sekunden, sollten Sie das Display zu stabilisieren und die Anzeige-LED blinkt alle 2 Sekunden!
    Gehen Sie auf Ihrem Computer, stecken Sie den Empfänger XBee in den USB-Adapter und sicherzustellen, dass es die neueste Firmware hochgeladen hat und es auf der gleichen PAN-ID, wie der Sender. Sie sehen die RSSI LED (rote LED) leuchten. Das bedeutet, dass Sie eine gute Verbindung haben!
    Öffnen Sie die Klemme in X-CTU (oder ein anderes Terminal-Programm) und schließen mit 9600 Baud 8N1 Parität und du wirst eine Menge Unsinn zu sehen. Was wichtig ist, dass ein neues Stück Unsinn wird einmal alle 2 Sekunden gedruckt, was ein Datenpaket empfangen wurde.
    Die Hardware durchgeführt wird. Gute Arbeit!

Schritt 12: Software

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 15 Artikel anzeigen
    Einführung

    Nun, da die Hardware abgeschlossen ist, kommen wir zu der spannende Teil: Betrieb der Software, die die Daten von unserer Empfänger XBee abruft und speichert sie in unserem Computer oder lädt sie zu einer Datenbank oder aktualisiert unseren Twitter-Feed oder .... was auch immer Sie " d mögen!

    Hier ist, wie es funktioniert, ist das XBee innerhalb des Kill-a-Watt bis zu zwei analoge Signale angeschlossen. Eines ist das Spannungssignal, das der Wechselspannung Lese anzeigt. In der Regel ist dies eine Sinuswelle, die 120 V AC ist. Eine heikle Sache zu erinnern ist, dass 120 V ist der "RMS" Spannung, und die "wahre Spannung" ist + -170VDC. ( Sie können bei Wikipedia mehr über RMS-Spannung gelesen Grunde seiner einen Weg zu zeigen, wie viel "durchschnittlichen" Spannung da ist.) Die zweite Lesung ist die AC-Stromlese. Dies ist, wie viel Strom wird durch die Tötungs-a-Watt gezogen. Wenn Sie die aktuelle vermehren durch die Spannung, werden Sie die Leistung (in Watt) verwendet zu erhalten!

    Die XBee der Analog / Digital-Wandler eingerichtet ist, um eine "Momentaufnahme" eines Sinus-Zyklus zu einer Zeit. Jedes Doppeldatei (Spannung und Strom) ist 1ms auseinander genommen und es dauert 17 von ihnen. Das entspricht einem 17ms lange Reihe von Proben. Ein Zyklus der Stromverbrauch ist 1 / 60Hz lange die 16.6ms ist. Also es funktioniert ziemlich gut!

    Schauen wir uns einige Beispiele für Spannungs- und Stromverläufe wie die XBee sieht.

    Zum Beispiel diese erste Kurve ist von einem Laptop angeschlossen ist. Sie werden sehen, dass seine ein Schaltteil, und zieht nur Macht auf dem Höhepunkt der Spannungskurve.

    Läßt jetzt versuchen Sie, in einer 40W Glühbirne. Sie werden bemerken, dass im Gegensatz zu dem Schaltteil, der Strom folgt der Spannung nahezu perfekt. Das ist, weil eine Glühbirne ist nur ein Widerstand!

    Schließlich können versuchen, kleben Sie das Messgerät auf einem dimmbaren Schalter. Du wirst sehen, dass die Spannung 'gehackt' up, nicht mehr sinusförmig. Und obwohl die aktuelle folgt der Spannung, die immer noch pass ziemlich gut.

    The XBee sends the raw data to the computer which, in a python script, figures out what the (calibrated) voltage and amperage is at each sample and multiplies each point together to get the Watts used in that cycle. Since there's almost no device that changes the power-usages from cycle-to-cycle, the snapshot is a good indicator of the overall power usage that second. Then once every 2 seconds, a single snapshot is sent to the receiver XBee

    Install python & friends

    The software that talks to the XBee is written in python . I used python because its quick to develop in, has multi-OS support and is pretty popular with software and hardware hackers. The XBees talk over the serial port so literally any programming language can/could be used here. If you're a software geek and want to use perl, C, C#, tcl/tk, processing, java, etc. go for it! You'll have to read the serial data and parse out the packet but its not particularly hard.

    However, most people just want to get on with it and so for you we'll go through the process of installing python and the libraries we need.

    1. Download and install python 2.5 from http://www.python.org/download/ I suggest 2.5 because that seems to be stable and well supported at this time. If you use another version there may be issues
    2. Download and install pyserial from the package repository (this will let us talk to the XBee thru the serial port)
    3. If you're running windows download and install win32file for python 2.5 (this will add file support)
    4. Download and install the simplejson python library (this is how the twitter api likes to be spoken to)

    Now you can finally download the Wattcher script we will demonstrate here! We're going to download it into the C:\wattcher directory, for other OS's you can of course change this directory

    Basic configure

    We'll have to do a little bit of setup to start, open up the wattcher.py script with a text editor and find the line

    SERIALPORT = "COM4" # the com/serial port the XBee is connected to

    change COM4 into whatever the serial port you will be connecting to the XBee with is called. Under windows its some COMx port, under linux and mac its something like /dev/cu.usbserial-xxxx check the /dev/ directory and/or dmesg

    Save the script with the new serial port name

    Test it out

    Once you have installed python and extracted the scripts to your working directory, start up a terminal (under linux this is just rxvt or xterm , under mac its Terminal , under windows, its a cmd window)

    I'm going to assume you're running windows from now on, it shouldn't be tough to adapt the instructions to linux/mac once the terminal window is open.

    Run the command cd C:\wattcher to get to the place where you uncompressed the files. By running the dir command you can see that you have the files in the directory

    Make sure your transmitter (Kill-a-Watt + Xbee) is plugged in, and blinking once every 2 seconds. Remember it takes a while for the transmitter to charge up power and start transmitting. The LCD display should be clear, not fuzzy. Make sure that there's nothing plugged into the Kill-a-Watt, too. The RSSI (red) LED on the receiver connected to the computer should be lit indicating data is being received. Don't continue until that is all good to go.

    Now run python by running the command C:\python25\python.exe wattcher.py

    You should get a steady print out of data. The first number is the XBee address from which it received data, following is the estimated current draw, wattage used and the Watt-hours consumed since the last data came in. Hooray! We have wireless data!

    Calibrating

    Now that we have good data being received, its time to tweak it. For example, its very likely that even without an appliance or light plugged into the Kill-a-Watt, the script thinks that there is power being used. We need to calibrate the sensor so that we know where 'zero' is. In the Kill-a-Watt there is an autocalibration system but unfortunately the XBee is not smart enough to do it on its own. So, we do it in the python script. Quit the script by typing in Control-C and run it again this time as C:\python25\python.exe wattcher.py -d note the -d which tells the script to print out debugging information

    Now you can see the script printing out a whole mess of data. The first chunk with lots of -1's in it is the raw packet. While its interesting we want to look at the line that starts with ampdata :

    ampdata: [498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 497, 498, 498, 498]

    Now you'll notice that the numbers are pretty much all the same. That's because there's nothing plugged into the tweetawatt and so each 1/60 Hz cycle has a flat line at 'zero'. The A/D in the XBee is 10 bits, and will return values between 0 and 1023. So, in theory, if the system is perfect the value at 'zero' should be 512. However, there are a bunch of little things that make the system imperfect and so zero is only close to 512. In this case the 'zero' calibration point is really 498. When its off there is a 'DC offset' to the Amp readings, as this graph shows:

    See how the Amp line (green) is steady but its not at zero, its at 0.4 amps? There is a 'DC offset' of 0.4 amps

    OK, open up the wattcher.py script in a text editor.

    vrefcalibration = [492, # Calibration for sensor #0]
    492, # Calibration for sensor #1
    489, # Calibration for sensor #2
    492, # Calibration for sensor #3
    501, # Calibration for sensor #4
    493] # etc... approx ((2.4v * (10Ko/14.7Ko)) / 3

    See the line that says # Calibration for sensor #1 ? Change that to 498

    vrefcalibration = [492, # Calibration for sensor #0]
    498, # Calibration for sensor #1
    489, # Calibration for sensor #2
    492, # Calibration for sensor #3
    501, # Calibration for sensor #4
    493] # etc... approx ((2.4v * (10Ko/14.7Ko)) / 3

    Save the file and start up the script again, this time without the -d

    Now you'll see that the Watt draw is 2W or less, instead of 40W (which was way off!) The reason its not 0W is that, first off, there's a little noise that we're reading in the A/D lines, secondly there's power draw by the Kill-a-Watt itself and finally, the XBee doesn't have a lot of samples to work with. However <2W is pretty good considering that the full sensing range is 0-1500W

    Note the graph with the calibrated sensor:

    See how the Amps line is now at 0 steady, there is no DC offset

    Logging data

    Its nice to have this data but it would be even nicer if we could store it for use. Well, thats automatically done for you! You can set the name of the log file in the wattcher.py script. By default it's powerdatalog.csv . The script collects data and every 5 minutes writes a single line in the format Year Month Day, Time, Sensor#, Watts for each sensor.As you can see, this is an example of a 40W incandescent lightbulb plugged in for a few hours. Because of the low sample rate, you'll see some minor variations in the Watts recorded. This data can be easily imported directly into any spreadsheet program

    Tweeting

    Finally we get to the tweeting part of the tweet-a-watt. First open up the wattcher.py script and set

    # Twitter username & password
    twitterusername = "username"
    twitterpassword = "password"

    to your username and password on twitter. You can make an account on twitter.com if you don't have one.

    Then run the script as usual. Every 8 hours (midnight, 8am and 4pm) the script will sent a twitter using the Twitter API

    Then check it out at your account:

Step 13: Expand

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...
    Überblick

    Once you've got your base system up and running here are some ideas for how to extend, improve or expand it!

    Add more outlets

    So you can track more rooms, of course

    Graphing

    If you'd like to play some more with the script, there's some extras built in. For example, you can graph the data as it comes in from the XBee, both Watts used and the actual 'power line' waveform. Simply set GRAPHIT = True you'll need to install a mess of python libraries though, including wxpython , numpy and pylab

    Remove the computer

    It took a few hours, but I hacked my Asus wifi router to also log data for me. There'll be more documentation soon but here's some hints:

    Do basically everything in [Do basically everything in MightyOhm's tutorial. You can use the FTDI cable to reprogram the router, just move the pins around. Then add a 16mb USB key (I was given one as schwag so look in your drawers) and install python and the openssl library as well as the other libraries needed like pyserial. The code should pretty much just run! (I'll put up more detailed notes later)]

    The router still works as my wifi gateway to the cablemodem, and only uses 5W MightyOhm's tutorial]. You can use the FTDI cable to reprogram the router, just move the pins around. Then add a 16mb USB key (I was given one as schwag so look in your drawers) and install python and the openssl library as well as the other libraries needed like pyserial. The code should pretty much just run! (I'll put up more detailed notes later)

    The router still works as my wifi gateway to the cablemodem, and only uses 5W

Step 14: Design - overview

  1. Design overview

    For those interested in how to build a sensor node system with a Google Appengine backend, here is the process by which I created it. Of course, you should have the hardware part done first!

    1. Listen - designing the parser for the computer that grabs XBee packets, and extracts the useful data
    2. Store - how to use GAE to store the data in 'the cloud'
    3. Graph - using Google Visualizations to make pretty graphs

Step 15: Design - listen

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Data listening & parsing

    In this section we will work on the receiver software, that will talk to a receiver XBee and figure out what the sensor data means. I'll be writing the code in python which is a fairly-easy to use scripting language. It runs on all OS's and has tons of tutorials online. Also, Google AppEngine uses it so its a good time to learn!

    This whole section assumes that you only have 1 transmitter and 1 receiver, mostly to make graphing easier to cope with. In the next section we'll tie in more sensors when we get to the datalogging part!

    Raw analog input

    We'll start by just getting raw data from the XBee and checking it out. The packet format for XBees is published but instead of rooting around in it, I'll just use the handy XBee library written for python. With it, I can focus on the data instead of counting bytes and calculating checksums.

    To use the library, first use the pyserial module to open up a serial port (ie COM4 under windows, /dev/ttyUSB0 under mac/linux/etc) You can look at the XBee project page for information on how to figure out which COM port you're looking for. We connect at the standard default baudrate for XBees, which is 9600 and look for packets

    from xbee import xbee
    import serial

    SERIALPORT = "COM4" # the com/serial port the XBee is connected to
    BAUDRATE = 9600 # the baud rate we talk to the xbee

    # open up the FTDI serial port to get data transmitted to xbee
    ser = serial.Serial(SERIALPORT, BAUDRATE)
    ser.open()

    while True:
    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if packet:
    xb = xbee(packet)

    print xb

    Running this code, you'll get the following output:

    <xbee {app_id: 0x83, address_16: 1, rssi: 85, address_broadcast: False, pan_broadcast: False, total_samples: 19, digital: [[-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1 , -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1 , -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1 , -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1 , -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1 , -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1 , -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1 , -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1 , -1], [-1, -1, -1, -1, -1, -1, -1, -1, -1]], analog: [[190, -1, -1, -1, 489, -1], [109, -1, -1, -1, 484, -1], [150, -1, -1, -1, 492, -1], [262, -1, -1, -1, 492 , -1], [423, -1, -1, -1, 492, -1], [589, -1, -1, -1, 492, -1], [740, -1, -1, -1, 492, -1], [843, -1, -1, -1, 492, -1], [870, -1, -1, -1, 496, -1], [805, -1, -1, -1, 491, -1], [680, -1, -1, -1, 492, -1], [518, -1, -1, -1, 492, -1], [349, -1, -1, -1, 491, -1], [199, -1, -1, -1, 491, -1], [116, -1, -1, -1, 468, -1], [108, -1, -1, -1, 492, -1], [198, -1, -1, -1, 492, -1], [335, -1, -1, -1, 492, -1], [523, -1, -1, -1, 492, -1]]}>

    which we will reformat to make a little more legible

    <xbee {
    app_id: 0x83,
    address_16: 1,
    rssi: 85,
    address_broadcast: False,
    pan_broadcast: False,
    total_samples: 19,
    digital: [[-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1],
    [-1, -1, -1, -1, -1, -1, -1, -1, -1]],
    analog: [[190, -1, -1, -1, 489, -1],
    [109, -1, -1, -1, 484, -1],
    [150, -1, -1, -1, 492, -1],
    [262, -1, -1, -1, 492, -1],
    [423, -1, -1, -1, 492, -1],
    [589, -1, -1, -1, 492, -1],
    [740, -1, -1, -1, 492, -1],
    [843, -1, -1, -1, 492, -1],
    [870, -1, -1, -1, 496, -1],
    [805, -1, -1, -1, 491, -1],
    [680, -1, -1, -1, 492, -1],
    [518, -1, -1, -1, 492, -1],
    [349, -1, -1, -1, 491, -1],
    [199, -1, -1, -1, 491, -1],
    [116, -1, -1, -1, 468, -1],
    [108, -1, -1, -1, 492, -1],
    [198, -1, -1, -1, 492, -1],
    [335, -1, -1, -1, 492, -1],
    [523, -1, -1, -1, 492, -1]]

    }>

    OK now its clear whats going on here. First off, we get some data like the transmitter ID (address_16) and signal strength (RSSI). The packet also tells us how many sample are available (19). Now, the digital samples are all -1 because we didn't request any to be sent. The library still fills them in tho so thats why the non-data is there. The second chunk is 19 sets of analog data, ranging from 0 to 1023. As you can see, the first sample (#0) and fifth sample (#4) contain real data, the rest are -1. That corresponds to the hardware section where we setup AD0 and AD4 to be our voltage and current sensors.

    We'll tweak our code so that we can extract this data only and ignore the rest of the packet.

    This code creates two arrays, voltagedata and ampdata where we will stick the data. We throw out the first sample because usually ADCs are a bit wonky on the first sample and then are good to go after that. It may not be necessary tho

    #!/usr/bin/env python
    import serial
    from xbee import xbee

    SERIALPORT = "COM4" # the com/serial port the XBee is connected to
    BAUDRATE = 9600 # the baud rate we talk to the xbee
    CURRENTSENSE = 4 # which XBee ADC has current draw data
    VOLTSENSE = 0 # which XBee ADC has mains voltage data

    # open up the FTDI serial port to get data transmitted to xbee
    ser = serial.Serial(SERIALPORT, BAUDRATE)
    ser.open()

    while True:
    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if packet:
    xb = xbee(packet)

    #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 voltagedata
    print ampdata

    Now our data is easier to see:


    Voltage: [672, 801, 864, 860, 755, 607, 419, 242, 143, 108, 143, 253, 433, 623, 760, 848, 871, 811]
    Current: [492, 492, 510, 491, 492, 491, 491, 491, 492, 480, 492, 492, 492, 492, 492, 492, 497, 492]


    Note that the voltage swings from about 100 to 900, sinusoidally.

    Normalizing the data

    Next up we will 'normalize' the data. The voltage should go from -170 to +170 which is the actual voltage on the line, instead of 100 to 900 which is just what the ADC reads. To do that we will get the average value of the largest and smallest reading and subtract it from all the samples. After that, we'll normalize the Current measurements as well, to get the numbers to equal the current draw in Amperes.

    #!/usr/bin/env python
    import serial
    from xbee import xbee

    SERIALPORT = "COM4" # the com/serial port the XBee is connected to
    BAUDRATE = 9600 # the baud rate we talk to the xbee
    CURRENTSENSE = 4 # which XBee ADC has current draw data
    VOLTSENSE = 0 # which XBee ADC has mains voltage data

    # open up the FTDI serial port to get data transmitted to xbee
    ser = serial.Serial(SERIALPORT, BAUDRATE)
    ser.open()

    while True:
    # grab one packet from the xbee, or timeout
    packet = xbee.find_packet(ser)
    if packet:
    xb = xbee(packet)

    #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]

    # 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
    ampdata[i] -= VREF
    # 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

    We'll run this now to get this data, which looks pretty good, there's the sinusoidal voltage we are expecting and the current is mostly at 0 and then peaks up and down once in a while. Note that the current is sometimes negative but that's OK because we multiply it by the voltage and if both are negative it still comes out as a positive power draw


    Voltage, in volts: [-125, -164, -170, -128, -64, 11, 93, 148, 170, 161, 114, 46, -39, -115, -157, -170, -150, -99]

    Current, in amps: [0.064516129032258063, -1.096774193548387, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.096774193548387,]
    0.0, 0.0, 0.0, -0.064516129032258063, 0.0, 0.0, -0.70967741935483875, 0.0, 0.0]


    Basic data graphing

    Finally, I'm going to add a whole bunch more code that will use the numpy graphing modules to make a nice graph of our data. Note that you'll need to install wxpython as well as numpy , and matplotlib !

    At this point, the code is getting waaay to big to paste here so grab "wattcher.py Mains graph" from the download page!

    Run it and you should see a graph window pop up with a nice sinusoidal voltage graph and various amperage data. For example this first graph is of a laptop plugged in. You'll see that its a switching supply, and only pulls power during the peak of the voltage curve.

    Now lets try plugging in a 40W incandescent light bulb. You'll notice that unlike the switching supply, the current follows the voltage almost perfectly. Thats because a lightbulb is just a resistor!

    Finally, lets try sticking the meter on a dimmable switch. You'll see that the voltage is 'chopped' up, no longer sinusoidal. And although the current follows the voltage, its still matching pretty well.

    Graphing wattage!

    OK neat, its all fun to watch waveforms but what we -really want- is the Watts used. Remember, P = VI otherwise known as Watts = Voltage * Current. We can calculate total Watts used by multiplying the voltages and currents at each sample point, then summing them up over a cycle & averaging to get the power used per cycle. Once we have Watts, its easy to just multiply that by 'time' to get Watt-hours!

    Download and run the wattcher.py - watt grapher script from the download page

    Now you can watch the last hour's worth of watt history (3600 seconds divided by 2 seconds per sample = 1800 samples) In the image above you can see as I dim a 40-watt lightbulb. The data is very 'scattered' looking because we have not done any low-pass filtering. If we had a better analog sampling rate, this may not be as big a deal but with only 17 samples to work with, precision is a little difficult

    Done!

    OK great! We have managed to read data, parse out the analog sensor payload and process it in a way that gives us meaningful graphs. Of course, this is great for instantaneous knowledge but it -would- be nice if we could have longer term storage, and also keep track of multiple sensors. In the next step we will do that by taking advantage of some free 'cloud computing' services!

Step 16: Design - store

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Alle 7 Artikel anzeigen
    Einführung

    OK we are getting good data from our sensors, lets corral it into more useful chunks and store it in a database. We could make a database on the computer, but since we'd like to share this data, it makes more sense to put it online. There are custom services that are specifically designed to do this sort of thing like Pachube but I'm going to reinvent the wheel and design my own web-app that stores and displays energy data. (Mostly I want to play around with Google App Engine!)

    You have 5 minutes!

    We get data every few seconds from the XBee modem inside the kill-a-watt. We could, in theory, put data into our database every 2 seconds but that would quickly balloon the amount of storage necessary. It would also make sorting through the data difficult. So instead lets add up all the sensor data for 5 minutes and then take the average.

    We'll do this by keeping two timers and one tally. One timer will track how long its been since the last sensor signal was sent, and the other will track if its been 5 minutes. The tally will store up all the Watt-hours (Watt measurements * time since last sensor data). Then at the end we can average by the 5 minutes

    This chunk of code goes near the beginning, it creates the timers and tally and initializes them

    ...
    fiveminutetimer = lasttime = time.time() # get the current time
    cumulativewatthr = 0
    ...

    Then later on, after we get our data we can put in this chunk of code:

    # add up the delta-watthr used since last reading
    # Figure out how many watt hours were used since last reading
    elapsedseconds = time.time() - lasttime
    dwatthr = (avgwatt * elapsedseconds) / (60.0 * 60.0) # 60 seconds in 60 minutes = 1 hr
    lasttime = time.time()
    print "\t\tWh used in last ",elapsedseconds," seconds: ",dwatthr
    cumulativewatthr += 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() - fiveminutetimer) >= 60.0) and (currminute % 5 == 0)):
    # Print out debug data, Wh used in last 5 minutes
    avgwattsused = cumulativewatthr * (60.0*60.0 / (time.time() - fiveminutetimer))
    print time.strftime("%Y %m %d, %H:%M"),", ",cumulativewatthr,"Wh = ",avgwattsused," W average")

    # Reset our 5 minute timer
    fiveminutetimer = time.time()
    cumulativewatthr = 0

    Note that we calculate delta-watthours, the small amount of power used every few seconds. Then we can get the average watts used by dividing the watthours by the number of hours that have passed (about 1/12th). Instead of going by exact 5 minutes, I decided to only report on the 5's of the hour (:05, :10, etc) so that its easier to send all the data at once if theres multiple sensors that started up at different times.

    Download wattcher-5minreporter.py from the Download page. If you run this, you'll get a steady stream

    Near the end you can see the timestamp, the Watthrs used in the last few minutes and the average Wattage

    Multisensor!

    We have good data but so far it only works with one sensor. Multiple sensors will mess it up! Time to add support for more than one XBee so that I can track a few rooms. I'll do that by creating an object class in python, and using the XBee address (remember that from part 1?) to track. I'll replace the code we just wrote with the following:

    At the top, instead of the timer variables, I'll have a full class declaration, and create an array to store them:

    ####### store sensor data and array of histories per sensor
    class Fiveminutehistory:
    def init (self, sensornum):
    self.sensornum = sensornum
    self.fiveminutetimer = time.time() # track data over 5 minutes
    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):
    return self.cumulativewatthr * (60.0*60.0 / (time.time() - self.fiveminutetimer))

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

    ######### an array of histories
    sensorhistories = []

    When the object is initialized with the sensor ID number, it also sets up the two timers and cumulative Watthrs tracked. I also created a few helper functions that will make the code cleaner

    Right below that I'll create a little function to help me create and retrieve these objects. Given an XBee ID number it either makes a new one or gets the reference to it

    ####### retriever
    def findsensorhistory(sensornum):
    for history in sensorhistories:
    if history.sensornum == sensornum:
    return history
    # none found, create it!
    history = Fiveminutehistory(sensornum)
    sensorhistories.append(history)
    return history

    Finally, instead of the average Watt calculation code written up above, we'll replace it with the following chunk, which retreives the object and tracks power usage with the object timers

    # 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"

    # Reset our 5 minute timer
    sensorhistory.reset5mintimer()

    The code basically acts the same except now it wont choke on multiple sensor data! Below, my two Kill-a-Watts, one with a computer attached (100W) and another with a lamp (40W)

    Onto the database!

    The App Engine

    So we want to have an networked computer to store this data so we can share the data, but we really don't want to have to run a server from home! Was zu tun ist? Well as mentioned before, you can use Pachube or similar, but I will show how to roll-your-own with Google App Engine (GAE) . GAE is basically a free mini-webserver hosted by Google, that will run basic webapps without the hassle of administrating a database server. Each webapp has storage, some frameworks and can use Google accounts for authentication. To get started I suggest checking out the GAE website, documentation, etc. I'll assume you've gone through the tutorials and jump right into designing my power data storage app called Wattcher (a little confusing I know)

    First, the app.yaml file which defines my app looks like this:

    application: wattcher
    version: 1
    runtime: python
    api_version: 1

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

    Pretty simple, just says that the app uses wattcherapp.py as the source file

    Next, we'll dive into the python code for our webapp. First, the includes and database index. To create a database, we actually define it -in the python file-, GAE then figures out what kind of database to create for you by following those directions (very different than MySQL where you'd create the DB separately)

    import cgi, datetime

    from google.appengine.api import users
    from google.appengine.ext import webapp
    from google.appengine.ext.webapp.util import run_wsgi_app
    from google.appengine.ext import db

    class Powerusage(db.Model):
    author = db.UserProperty() # the user
    sensornum = db.IntegerProperty() # can have multiple sensors
    watt = db.FloatProperty() # each sending us latest Watt measurement
    date = db.DateTimeProperty(auto_now_add=True) # timestamp

    We use the default includes. We have a single database table called Powerusage , and it has 4 entries: one for the user, one for the sensor number, one for the last reported Watts used and one for a datestamp

    Each 'page' or function of our webapp needs its own class. Lets start with the function that allows us to store data in the DB. I'll call it PowerUpdate.

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

    # make the user log in
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))

    powerusage = Powerusage()

    if users.get_current_user():
    powerusage.author = users.get_current_user()
    #print self.request
    if self.request.get('watt'):
    powerusage.watt = float(self.request.get('watt'))
    sonst:
    self.response.out.write('Couldnt find \'watt\' GET property!')
    return
    if self.request.get('sensornum'):
    powerusage.sensornum = int(self.request.get('sensornum'))
    sonst:
    powerusage.sensornum = 0 # assume theres just one or something

    powerusage.put()
    self.response.out.write('OK!')

    When we send a request to do that with a GET call (ie requesting the webpage), we'll first make sure the user is authenticated and logged in so we know their name. Then we'll create a new database entry by initializing a new instantiation of Powerusage. Then we'll look the GET request for the watt data, which would be in the format watt=39.2 or similar. That's parsed for us, thankfully and we can also get the sensor number which is passed in the format sensornum=3. Finally we can store the data into the permanent database

    Next is a useful debugging function, it will simply print out all the data it has received for your account!

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

    # make the user log in
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))

    self.response.out.write('<html><body>Here is all the data you have sent us:<p>')

    powerusages = db.GqlQuery("SELECT * FROM Powerusage WHERE author = :1 ORDER BY date", users.get_current_user())

    for powerused in powerusages:
    if powerused.sensornum:
    self.response.out.write('<b>%s</b>\'s sensor #%d' %
    (powerused.author.nickname(), powerused.sensornum))
    sonst:
    self.response.out.write(<b>%s</b>' % powerused.author.nickname())

    self.response.out.write(' used: %f Watts at %s<p>' % (powerused.watt, powerused.date))
    self.response.out.write("</body></html>")

    This function simply SELECT's (retrieves) all the entries, sorts them by date and prints out each one at a time

    Finally we'll make a basic 'front page' that will show the last couple of datapoints sent

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

    self.response.out.write('<html><body>Welcome to Wattcher!<p>Here are the last 10 datapoints:<p>')

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

    for powerused in powerusages:
    if powerused.sensornum:
    self.response.out.write('<b>%s</b>\'s sensor #%d' %
    (powerused.author.nickname(), powerused.sensornum))
    sonst:
    self.response.out.write('<b>%s</b>' % powerused.author.nickname())

    self.response.out.write(' used: %f Watts at %s<p>' % (powerused.watt, powerused.date))
    self.response.out.write("</body></html>")

    Its very similar to the DataDump function but its only 10 points of data and from all users, nice to use when you just want to 'check it out' but don't want to log in

    Finally, we have a little initializer structure that tells GAE what pages link to what functions

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

    def main():
    run_wsgi_app(application)

    if name == " main ":
    main()

    Test!

    OK lets try it out, first lets visit http://wattcher.appspot.com/report

    Remember we made it a requirement to supply -some- data. Lets try again http://wattcher.appspot.com/report?watt=19.22&sensornum=1

    Yay we got an OK! Lets check out the data stored by visiting http://wattcher.appspot.com/dump

    There's two entries because I did a little testing beforehand but you can see that there are 2 entries. Nett!

    We can also visit the GAE control panel and browse the data 'by hand'

    Anyways, now that that's working, lets go back and add the reporting technology to our sensor-reader script

    Getting the report out

    Only a little more hacking on the computer script and we're done. We want to add support for sending data to GAE. Unfortunately right now our authentication is done through Google accounts so its not easy to run on an Arduino. To adapt it you'd have to send the username in the Report GET and hope nobody else uses the same one (unless you also add a basic password system)

    Anyhow, I totally ripped off how to do this from some nice people on the Internet

    Download appengineauth.py from the download page , and change the first few lines if necessary. We hardcode the URL we're going to and the account/password as well as the GAE app name

    users_email_address = " [email protected] "
    users_password = "mypassword"
    my_app_name = "wattcher"
    target_authenticated_google_app_engine_uri = 'http://wattcher.appspot.com/report'

    The real work happens at this function sendreport where it connects and sends the Watt data to the GAE site

    def sendreport(sensornum, watt):
    # this is where I actually want to go to
    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 should contain the contents of the
    # target_authenticated_google_app_engine_uri page - as we will have been
    # redirected to that page automatically
    #
    # to prove this, I'm just gonna print it out
    print serv_resp_body

    Finally, we wrap up by adding the following lines to our computer script, which will send the data nicely over to GAE!

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

    You can download the final script wattcher.py - final from the download page !

    Don't forget to visit wattcher.appspot.com to check out the lastest readings

Step 17: Design - graph

  1. Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Tweet-a-Watt - Wie man einen zwitschern Leistungsmesser zu machen ...

    Making pretty pictures

    Data is great, but visualizations are better. In this step we'll manipulate our stored history so that we can make really nice graphs!

    First we'll start by making our sensors named, so that its easier for us to keep track of which is what. Then we'll look at our graph options and data formats. Finally we'll reformat our data to make it ready for graphing

    Configuring the sensor names

    Its no fun to have data marked as "sensor #1" so I added a 'config' page where the app engine code looks at what sensor numbers have sent data to the database and then allows you to name them. Of course, you need to have the sensor on and sending data -first- before this will work

    The configure screen looks something like the image below.

    This code uses GET when it should really use POST. I'm kinda old and dont like debugging with POST so...yeah.

    class Configure(webapp.RequestHandler):
    def get(self):
    # make the user log in if no user name is supplied
    if self.request.get('user'):
    account = users.User(self.request.get('user'))
    sonst:
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))
    account = users.get_current_user()

    self.response.out.write('<html><body>Set up your sensornode names here:<p>')

    # find all the sensors up to #10
    sensorset = []
    for i in range(10):
    c = db.GqlQuery("SELECT * FROM Powerusage WHERE author = :1 and sensornum = :2", users.get_current_user(), i)
    if c.get():
    sensorset.append(i)

    self.response.out.write('<form action="/config" method="get">')
    for sensor in sensorset:
    name = ""
    currnamequery = db.GqlQuery("SELECT * FROM Sensorname WHERE author = :1 AND sensornum = :2", users.get_current_user(), sensor)
    currname = currnamequery.get()

    # first see if we're setting it!
    if self.request.get('sensornum'+str(sensor)):
    name = self.request.get('sensornum'+str(sensor))
    if not currname:
    currname = Sensorname() # create a new entry
    currname.sensornum = sensor
    currname.author = users.get_current_user()
    currname.sensorname = name
    currname.put()
    sonst:
    # we're not setting it so fetch current entry
    if currname:
    name = currname.sensorname

    self.response.out.write('Sensor #'+str(sensor)+': <input type="text" name="sensornum'+str(sensor)+'" value="'+name+'"></text><p>')

    self.response.out.write("""<div><input type="submit" value="Change names"></div>
    </form>
    </ Body>
    </html>""")

    Now we can have more useful data in the history dump

    Now we can see that Phil is mostly to blame for our power bill!

    Google Visualizer

    So we have data and we'd like to see our power usage history. Graphing data is a lot of work, and I'm lazy. So I look online and find that Google -also- has a visualization API! This means I don't have to write a bunch of graphical code, and can just plug into their system. Sweet!

    OK checking out the gallery of available visualizations , I'm fond of this one, the Annotated Time Line

    Note how you can easily see the graphs, scroll around, zoom in and out and each plot is labeled. Perfect for plotting power data!

    Data formatting

    Theres a few restrictions to how we get the data to the visualization api and our best option is JSon data. As far as I can tell, JSON is what happened when everyone said "wow, XML is really bulky and wasteful". Anyhow, theres like 4 layers of framework and interpretive data structions and in the end there was a pretty easy to use library written by the Google Visualizations team that let me 'just do it' with a single call by putting the data into a python 'dictionary' in a certain format.

    Lets go through the code in sections, since the function is quite long

    class JSONout(webapp.RequestHandler):
    def get(self):

    # make the user log in if no user name is supplied
    if self.request.get('user'):
    account = users.User(self.request.get('user'))
    sonst:
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))
    account = users.get_current_user()

    # assume we want 24 hours of data
    historytimebegin = 24
    if self.request.get('bhours'):
    historytimebegin = int(self.request.get('bhours'))

    # assume we want data starting from 0 hours ago
    historytimeend = 0
    if self.request.get('ehours'):
    historytimeend = int(self.request.get('ehours'))

    # data format for JSON happiness
    datastore = []
    columnnames = ["date"]
    columnset = set(columnnames)
    description ={"date": ("datetime", "Date")}

    # the names of each sensor, if configured
    sensornames = [None] * 10

    First up we get the user we're going to be looking up the data for. Then we have two variables for defining the amount of data to grab. One is "ehours" (end hours) and the other is "bhours". So if you wanted the last 5 hours, bhours would be 5 and ehours would be 0. If you wanted 5 hours from one day ago, bhours would be 29 and ehours would be 24. datastore is where we will corall all the data. columnnames and description are the 'names' of each column. We always have a date column, then another column for each sensor stream. We also have a seperate array to cache the special sensor names.

    onto the next section! Here is where we actually grab data from the database. Now app engine has this annoying restriction, you can only get 1000 points of data at once so what I do is go through it 12 hours at a time. The final datastore has all the points but its easier on the database, I guess. One thing that's confusing perhaps is each column has a name and a description. The name is short, say "watts3" for sensor #3, but the description might be "Limor's workbench". I don't even remember writing this code so maybe you can figure it out on your own?

    # we cant grab more than 1000 datapoints, thanks to free-app-engine restriction
    # thats about 3 sensors's worth in one day
    # so we will restrict to only grabbing 12 hours of data at a time, about 7 sensors worth

    while (historytimebegin > historytimeend):
    if (historytimebegin - historytimeend) > 12:
    timebegin = datetime.timedelta(hours = -historytimebegin)
    timeend = datetime.timedelta(hours = -(historytimebegin-12))
    historytimebegin -= 12
    sonst:
    timebegin = datetime.timedelta(hours = -historytimebegin)
    historytimebegin = 0
    timeend = datetime.timedelta(hours = -historytimeend)

    # grab all the sensor data for that time chunk
    powerusages = db.GqlQuery("SELECT * FROM Powerusage WHERE date > :1 AND date < :2 AND author = :3 ORDER BY date", datetime.datetime.now()+timebegin, datetime.datetime.now()+timeend, account)

    # sort them into the proper format and add sensor names from that DB if not done yet
    for powerused in powerusages:
    coln = "watts" + str(powerused.sensornum)
    entry = {"date": powerused.date.replace(tzinfo=utc).astimezone(est), coln: powerused.watt}
    if not (coln in columnset):
    columnnames.append(coln)
    columnset = set(columnnames)
    # find the sensor name, if we can
    if (len(sensornames) < powerused.sensornum) or (not sensornames[powerused.sensornum]):
    currnamequery = db.GqlQuery("SELECT * FROM Sensorname WHERE author = :1 AND sensornum = :2", account, powerused.sensornum)
    name = currnamequery.get()

    if not name:
    sensornames[powerused.sensornum] = "sensor #"+str(powerused.sensornum)
    sonst:
    sensornames[powerused.sensornum] = name.sensorname

    description[coln] = ("number", sensornames[powerused.sensornum])
    #self.response.out.write(sensornames)

    # add one entry at a time
    datastore.append(entry)

    Finally at the end of all the looping, we call the magic function that turns the dictionary into JSON, wrap it in the proper Google Visualization package, then spit it out!

    # OK all the data is ready to go, print it out in JSON format!
    data_table = gviz_api.DataTable(description)
    data_table.LoadData(datastore)
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write(data_table.ToJSonResponse(columns_order=(columnnames),
    order_by="date"))

    If you were to visit http://wattcher.appspot.com/visquery.json?user= [email protected] &bhours=1 it would output something like this:

    google.visualization.Query.setResponse({'version':'0.5', 'reqId':'0', 'status':'OK', 'table': {cols: [{id:'date',label:'Date',type:'datetime'},{id:'watts1',label:'Limor',type:'number'},{id:'watts5',label:'Workbench',type:'number'},{id:'watts2',label:'Adafruit',type:'number'},{id:'watts4',label:'Phil2',type:'number'}],rows: [{c:[{v:new Date(2009,1,25,21,20,2)},{v:64.8332291619},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,20,3)},,{v:230.122099757},,{v:null}]},{c:[{v:new Date(2009,1,25,21,20,3)},,,{v:65.4923925044},{v:null}]},{c:[{v:new Date(2009,1,25,21,20,4)},,,,{v:48.6947643311}]},{c:[{v:new Date(2009,1,25,21,25,3)},,{v:228.409810208},,{v:null}]},{c:[{v:new Date(2009,1,25,21,25,3)},{v:67.3574917331},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,25,3)},,,{v:66.0046383897},{v:null}]},{c:[{v:new Date(2009,1,25,21,25,4)},,,,{v:47.3892235642}]},{c:[{v:new Date(2009,1,25,21,30,2)},{v:84.9379517795},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,30,3)},,,,{v:99.7553490071}]},{c:[{v:new Date(2009,1,25,21,30,5)},,{v:229.73642288},,{v:null}]},{c:[{v:new Date(2009,1,25,21,30,6)},,,{v:66.6556291818},{v:null}]},{c:[{v:new Date(2009,1,25,21,35,2)},,,{v:67.3146052998},{v:null}]},{c:[{v:new Date(2009,1,25,21,35,3)},{v:96.2322216676},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,35,3)},,{v:226.678267688},,{v:null}]},{c:[{v:new Date(2009,1,25,21,35,4)},,,,{v:158.428422765}]},{c:[{v:new Date(2009,1,25,21,40,3)},,{v:232.644574879},,{v:null}]},{c:[{v:new Date(2009,1,25,21,40,4)},,,,{v:153.666193493}]},{c:[{v:new Date(2009,1,25,21,40,6)},,,{v:66.7874343225},{v:null}]},{c:[{v:new Date(2009,1,25,21,40,12)},{v:95.0019590395},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,40,21)},{v:95.0144043571},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,40,23)},,,{v:66.8060307611},{v:null}]},{c:[{v:new Date(2009,1,25,21,45,2)},,,{v:66.9814723201},{v:null}]},{c:[{v:new Date(2009,1,25,21,45,3)},,{v:226.036818816},,{v:null}]},{c:[{v:new Date(2009,1,25,21,45,3)},{v:99.2775581827},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,45,4)},,,,{v:154.261889366}]},{c:[{v:new Date(2009,1,25,21,50,4)},{v:102.104642018},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,50,4)},,,,{v:155.441084531}]},{c:[{v:new Date(2009,1,25,21,50,5)},,,{v:67.0087146687},{v:null}]},{c:[{v:new Date(2009,1,25,21,50,5)},,{v:230.678636915},,{v:null}]},{c:[{v:new Date(2009,1,25,21,55,3)},{v:103.493297176},,,{v:null}]},{c:[{v:new Date(2009,1,25,21,55,3)},,,,{v:151.309223916}]},{c:[{v:new Date(2009,1,25,21,55,4)},,,{v:66.9174858741},{v:null}]},{c:[{v:new Date(2009,1,25,21,55,4)},,{v:227.765325835},,{v:null}]},{c:[{v:new Date(2009,1,25,22,0,3)},,,{v:67.0004310254},{v:null}]},{c:[{v:new Date(2009,1,25,22,0,3)},,,,{v:150.389989112}]},{c:[{v:new Date(2009,1,25,22,0,3)},,{v:230.892049553},,{v:null}]},{c:[{v:new Date(2009,1,25,22,0,4)},{v:92.2432771363},,,{v:null}]},{c:[{v:new Date(2009,1,25,22,15,3)},{v:97.5910440774},,,{v:null}]},{c:[{v:new Date(2009,1,25,22,15,3)},,,,{v:143.722595861}]},{c:[{v:new Date(2009,1,25,22,15,4)},,,{v:64.4898008851},{v:null}]},{c:[{v:new Date(2009,1,25,22,15,4)},,{v:222.357617868},,{v:null}]}]}});

    Anyways, you can kinda see the data, also note its actually a function call, this stuff is really kinky!

    Now go to the Google Visualizations Playground and enter in that URL into the sandbox

    And you can see the visualization itself pop out! (this is just a screen shot so go do it yerself if you want to mess around)

    OK go mess around, adding and changing bhours and ehours

    Wrapping up the visualization

    OK we're nearly done. Now we just need to basically grab the code from the sandbox and make it a subpage in our app engine...like so:

    class Visualize(webapp.RequestHandler):
    def get(self):

    # make the user log in if no user name is supplied
    if self.request.get('user'):
    account = users.User(self.request.get('user'))
    sonst:
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))
    account = users.get_current_user()

    historytimebegin = 24 # assume 24 hours
    if self.request.get('bhours'):
    historytimebegin = int(self.request.get('bhours'))

    historytimeend = 0 # assume 0 hours ago
    if self.request.get('ehours'):
    historytimeend = int(self.request.get('ehours'))

    # get the first part, headers, out
    self.response.out.write(
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <Head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Google Visualization API Sample</title>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <Script type = "text / javascript">
    google.load("visualization", "1", {packages: ["annotatedtimeline"]});

    function drawVisualizations() {
    )

    # create our visualization
    self.response.out.write( new google.visualization.Query("http://wattcher.appspot.com/visquery.json?user= +
    account.email()+ &bhours= +str(historytimebegin)+ ").send(
    function(response) {
    new google.visualization.AnnotatedTimeLine(
    document.getElementById("visualization")).
    draw(response.getDataTable(), {"displayAnnotations": true});
    });
    )

    self.response.out.write( }

    google.setOnLoadCallback(drawVisualizations);
    </ Script>
    </ Head>
    <body style="font-family: Arial;border: 0 none;">
    <div id="visualization" style="width: 800px; height: 250px;"></div>
    </ Body>
    </html> )

    The first part is pretty straight forward, get the user name or login. Then we will assume the user wants 1 last day of data, so set bhours and ehours . Then we literally just print out the code we copied from Google's Visualization sandbox, done!

    Viz Viz Viz

    The only thing I couldn't figure out is how to get 3 visualizations going on at once (last hour, day and week) with the above code. It just kinda broke. So for the triple view I had to use iframes :(

    class VisualizeAll(webapp.RequestHandler):
    def get(self):

    # make the user log in if no user name is supplied
    if self.request.get('user'):
    account = users.User(self.request.get('user'))
    sonst:
    if not users.get_current_user():
    self.redirect(users.create_login_url(self.request.uri))
    account = users.get_current_user()

    self.response.out.write(
    <h2>Power usage over the last hour:</h2>
    <iframe src ="graph?user= [email protected] &bhours=1" frameborder="0" width="100%" height="300px">
    <p>Your browser does not support iframes.</p>
    </iframe>

    <h2>Power usage over the last day:</h2>
    <iframe src ="graph?user= [email protected] &bhours=24" frameborder="0" width="100%" height="300px">
    <p>Your browser does not support iframes.</p>
    </iframe>

    <h2>Power usage over the last week:</h2>
    <iframe src ="graph?user= [email protected] &bhours=168" frameborder="0" width="300%" height="500px">
    <p>Your browser does not support iframes.</p>
    </iframe>

    )

    Anyhow, it works just fine.

    Timecodes!

    The final thing that wont be reviewed here is how I got the date and times to be EST instead of UTC. As far as I can tell, its kind of broken and mysterious. Check the code if you want to figure it out.

Step 19: Download

  1. Software