Kurz bevor ich in meine Wohnung eingezogen bin, hatte ich die Möglichkeit dem Elektriker beim Anschließen des Sicherunsgkastens über die Schulter zu schauen. Und was mir damals gleich aufgefallen ist: Der verbaute Stromzähler, ein Eltako dsz12e, hat einen S0-Ausgang. Als ich 2013 meine Bachelorarbeit mit dem sperrigen Thema „Analyse der Wirtschaftlichkeit von PV-Anlagen in Verbindung mit Speichern für Privathaushalte ohne EEG-Vergütung“ geschrieben habe, war eines der Probleme überhaupt an Daten zu kommen, zu welchen Zeitpunkten in Privathaushalten elektrische Energie verbraucht wird. Letztendlich habe ich ein Verbrauchsprofil aufgrund einer VDI-Richtline erzeugt – aber auch das beinhaltete „nur“ werte für 15 minuten – eine noch genauere Auflösung wäre aber wünschenswert gewesen. Der S0-Ausgang an meinem Stromzähler hat deshalb sofort mein Interesse geweckt.
Allerdings waren andere Bastelprojekte erstmal wichtiger – und anfangs hat mich auch abgeschreckt, dass der S0-Ausgang laut Spezifikation eine angelegten Spannung von 5V benötigt, der Raspberry liefert aber nur 3,3V. Aber irgendwann als ich mal wieder zu dem Thema gegoogelt habe, bin ich über einen Blogartikel von Johannes Weber gestoßen, der mit dem Raspberry Pi seinen S0-Stromzähler (den gleichen, der auch bei mir verbaut ist) ausließt – und mein Interresse war wieder geweckt.
Letzte Woche hab ich es dann geschaft. Der S0-Ausgang des Stromzählers wurde wie von Johannes beschrieben mit dem Pi verbunden (ebenfalls mit Gelb/Weiß, damit ich nicht durcheinander komme) – und ich konnte mit seinem Testprogramm erste Messswerte aufzeichnen.
Allerding unterscheidet sich ab hier unsere Zielsetzung: Johannes will die Daten mit seinem Monitoring-Server aufzeichnen – ich hätte gerne zuerstmal einfache CSV-Daten. Wie ich diese konkret später mal verwenden werde ist noch nicht klar – aber mit CSV-Dateien bleib ich flexibel. Deshalb habe ich Johannes Stromzählerprogramm für meine Zwecke angepasst – es erzeugt jetzt für jeden Tag eine CSV-Datei mit werten für jede Minute:
/*
* isr.c:
* Wait for Interrupt test program - ISR method
*
* How to test:
* Use the SoC's pull-up and pull down resistors that are avalable
* on input pins. So compile & run this program (via sudo), then
* in another terminal:
* gpio mode 0 up
* gpio mode 0 down
* at which point it should trigger an interrupt. Toggle the pin
* up/down to generate more interrupts to test.
*
* Copyright (c) 2013 Gordon Henderson.
***********************************************************************
* This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/
*
* wiringPi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* wiringPi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
***********************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <time.h> //for filename & time in CSV-file
// What GPIO input are we using?
// This is a wiringPi pin number
#define BUTTON_PIN 9
// globalCounter:
// Global variable to count interrupts
// Should be declared volatile to make sure the compiler doesn't cache it.
static volatile int globalCounter = 0 ;
/*
* myInterrupt:
*********************************************************************************
*/
void myInterrupt (void)
{
++globalCounter ;
}
/*
*********************************************************************************
* main
*********************************************************************************
* adaptet by Jonathan Schneider (http://langhaarschneider.net) to save input-Values of every minute to CSV-files for every day.
* inspired by Johannes Weber (http://blog.webernetz.net/2014/10/13/stromzahler-mit-s0-schnittstelle-vom-raspberry-pi-auswerten/)
*/
int main (void)
{
FILE* ptr_datei; //pointer to file descriptor
time_t t; //timestamp of the current time
struct tm* ptr_ts; //pointer to tm-struct (defined in time.h)
int lastmin = 0; //int value for the last minute that was written to the CSV-file
char filename[31]; //Filename including dir:/home/pi/strom/YYYY-MM-DD.csv + \0 means 30 characters needed
if (wiringPiSetup () < 0)
{
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}
if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0)
{
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ;
return 1 ;
}
for (;;) //endless loop...
{
do {
delay (100); //sleep 100 ms
t = time(NULL); //get current time
ptr_ts = localtime(&t); //create tm-structure
} while (lastmin == ptr_ts->tm_min); //loop while the current minute = the last minute, which values are already saved in the logfile
//create filename. Year has 4 Characters, Month and say may have only one. So it has to be formatted that month and day always will have two characters - maybe with leading zwro.
//To year 1900 has to be added because it only includes the years from 1900.
//Month has to be increased by one because it starts with january = 0
//BE CAREFUL IF YOU CHANGE THE FILENAME! You might have to increase filename[]!
sprintf(filename, "/home/pi/strom/%i-%02i-%02i.csv", ptr_ts->tm_year+1900, ptr_ts->tm_mon+1, ptr_ts->tm_mday);
printf("%s", filename);
ptr_datei = fopen(filename, "a"); //Open file FILENAME. Create it if it doesnt exist. Append things that will be written at the end
//Print following information into one line: HH:MM;COUNTERVALUE
//HH & MM have to be formated, that they always will have two characters
fprintf (ptr_datei, "%02i:%02i;%d\n", ptr_ts->tm_hour, ptr_ts->tm_min, globalCounter);
globalCounter = 0; //after writing the counter-value to the file, reset the counter-value to 0 for the next minute
fclose (ptr_datei); //close the CSV-file
lastmin = ptr_ts->tm_min; //set lastmin to the minute for which the CSV-file was written.
} //And start again
return 0 ; //will hopefully never be reached...
}
Inzwischen wurde auch das Problem der Spannungsversorgung des Pi in Nähe des Sicherungskasten gelöst – und der Pi liefert mir hübsche Messwerte:
pi@raspicounter ~/strom $ cat 2015-04-16.csv 21:10;19 21:11;19 21:12;18 21:13;19 21:14;18 21:15;18 21:16;18 21:17;19 21:18;19 21:19;19 21:20;19
Die angezeigten Werte müssen noch in kWh oder Wh umgerechnet werden – da mein Zähler mir pro kWh 800 Impulse liefert. Ich habe also in den letzten Minuten einen Verbrauch von rund 23,57 Wh pro Minute gehabt.
Das nächste Projekt könnte dann mein Wärmemengenzähler für die Heizung werden. Der Sensus pollucom e lässt sich laut Bedienungsanleitung auch irgendwie auslesen…
Ich freue mich über deine Anmerkungen/Fragen/Kommentare!

Schreibe einen Kommentar