Das würde beides Volkszähler für dich machen...
Wie würde in dem Fall die vzlogger.conf und das Programm auf dem 8266?
Das würde beides Volkszähler für dich machen...
Wie würde in dem Fall die vzlogger.conf und das Programm auf dem 8266?
Danke. Ja, sehr cool.
Zu deinen Fragen:
1. Die beiden Konstanten können auch zu Beginn deklariert werden. Da sie nicht verändert werden ist das die stimmiger!
2. Ich finde es einfach schlüssiger direkt jeden Impuls zu erfassen und mit Hilfe der vergangenen Zeit dann die Leistung in dieser Zeit zu berechnen. Geht aber natürlich auch indem man die Pulse zählt und dann weiter berechnet. Dann muss man sich aber irgendwie auch die Gesamtanzahl der Pulse irgendwo merken...
Moin, ich habs hinbekommen.
Läuft seit gestern stabil. Allerdings war der "GET" Request der richtige und nicht der "POST" Request.
Die Pulse werden hier Interrupt gesteuert abgefangen. Für JEDEN Puls wird Millisekunden genau die Leistung berechnet und an die Middleware gesendet.
Im Frontend ist der Kanal als "El. Energie (Leistungswerte)" mit einer Auflösung von "1" definiert.
Der S0 Eingang hat Hardwaremäßig einen 4,7k Ohm Widerstand.
Zu beachten ist, dass in diesem Fall bei maximaler Leistung (Balkonkraftwerk mit 600W, S0 Zähler mit 1600 Impulse / kWh) alle 3700ms ein Puls gesendet wird.
Hier mein Programm:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
const char* ssid = "WIFI_SSID";
const char* password = "WIFI_password";
String hostname = "HOSTNAME";
String serverName = "VZ-SERVER_IP" // z.B. http://192.168.1.2:80";
volatile byte interrupt_status = 0; //status des Interrupts
volatile unsigned long millis_alt = 0;
volatile unsigned long millis_neu = 0;
byte firstPulse = 1;
ICACHE_RAM_ATTR void interrupt_code() {
millis_neu = millis(); //Zeit holen
interrupt_status = 1; //Statusbyte setzen
}
void setup() {
ESP.wdtDisable(); //software watchdog deaktivieren, hardware watchdog rebootet alle 8s.
// Serial.begin(9600);
// while (!Serial) {
// delay(500);
// }
WiFi.mode(WIFI_STA); //als Client
WiFi.hostname(hostname.c_str());
WiFi.begin(ssid, password); //wifi start
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
pinMode(D5, INPUT); //D5 als Eingang ohne PullUp
attachInterrupt(digitalPinToInterrupt(D5), interrupt_code, FALLING); //Interrupt bei fallender Flanke
}
void loop() {
const float a = 2.25; //3600/1600
const int b = 1000; //1000 Watt
float delta_sec = 0.0; //variable für Zeit zwischen zwei Pulsen in Sekunden
float c = 0.0;
float pv_leistung = 0.0; //Leistung als Float
String PV_Leistung; //Leistung als String
unsigned long delta = 0; //variable für Zeit zwischen zwei Pulsen in Millisekunden
ESP.wdtFeed(); //hardware watchdog reset
if (interrupt_status) {
//delta berechnen, dazu Interrupt kurzzeitig deaktivieren
noInterrupts(); //Interrupt deaktivieren
delta = millis_neu - millis_alt; //delta berechnen
millis_alt = millis_neu; //millis aktualisieren
interrupt_status = 0; //Statusbyte rücksetzen
interrupts(); //Interrupt aktivieren
//Leistung berechnen und in String schreiben
delta_sec = delta / 1000;
c = delta_sec / a;
pv_leistung = b / c;
PV_Leistung = String(pv_leistung, 1);
// Serial.print("delta: ");
// Serial.println(delta);
// Serial.print("PV_Leistung: ");
// Serial.println(PV_Leistung);
if (firstPulse) {
firstPulse = 0;
// Serial.println("erster Puls nicht gesendet!");
}
else {
//Wenn WLAN ok --> Leistung senden
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
String serverPath = serverName + "/middleware.php/data/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json?operation=add&value=" + PV_Leistung;
// Serial.println("weiterer Puls wird gesendet...");
// Serial.print("serverPath: ");
// Serial.println(serverPath);
http.begin(client, serverPath.c_str());
int httpResponseCode = http.GET();
// Serial.print("httpResponseCode: ");
// Serial.println(httpResponseCode);
http.end(); //Close connection
}
}
}
}
Alles anzeigen
Vielen Dank für die Tipps. Ich werde morgen weiter ausprobieren.
Ich denke, ich habe unabhängig davon noch einen Fehler gefunden:
Der Wemos D1 mini hat einen Software watchdog, der nach ca. 3 sec. rebootet und einen Hardware watchdog, der nach dem Abschalten vom Software watchdog nach ca. 8 sec. rebootet. Diesen kann man nicht abschalten. Wenn ich jetzt per Interrupt auf die Pulse warte und es nicht gerade Hochsommer ist, lässt ein Puls bei einer Anlage mit 600W max. Leistung ("Balkonkraftwerk") und einem Zähler mit 1600 Impulsen pro kWh natürlich auf sich warten. Ich habe auch beobachtet, dass die onboard Led regelmäßig aufblinkt. Ich denke das war der reboot und das Programm kam gar nicht so weit einen HTTP Request zu senden...
Das hat leider so nicht funktioniert. Im Frontend kommen keine Daten an. An welcher Stelle kann ich denn nachschauen wo was ankommt? Die vzlogger.log loggt ja nur die in der vzlogger.conf eingetragenen Dinge mit, oder?
Guten Abend,
kann mir jemand bei der korrekten Syntax für ein HTTP Push Request vom Wemos D1 mini ESP 8266 zum Volkszähler helfen?
Ich programmiere mit der Arduino IDE und den dazugehörigen libraries. wie funktioniert speziell der Aufbau des HTTP Push Request mit den zur Verfügung stehenden Libs?
if (WiFi.status() == WL_CONNECTED) {
WiFiClient client;
HTTPClient http;
http.begin(client, serverName);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String httpRequestData = String("UUID.json?operation=add&value=" + PV_Leistung);
int httpResponseCode = http.POST(httpRequestData);
http.end();
}
Alles anzeigen
als "serverName" hab ich
const char* serverName = "http://192.168.2.150:80/middleware.php/data";
Ich habe momentan keine Möglich das direkt zu testen. Daher meine Frage ob das so funktioniert?! Oder wie muss der "serverName" und der httpRequestData String aussehen?
Da darf nur "Impulse" stehen.
Warum? Laut wiki darf beim protocol s0 der Wert "Impulse" oder "Impulse_neg" sein. Der eigentliche Impuls ist ja auch negativ wenn der Sensor am "Viertelmond" vorbei läuft sieht der Raspberry Pi am Eingang für 0,02m³ 0V.
Und du hast ausgerchnet einen der GPIO gewählt die auf den Erweiterungen als Ausgang genutzt wurden und im Image (rc.local) schon entsprechend vorkonfiguriert ist...
Ich habe die entsprechenden Textzeilen auskommentiert und so ergänzt:
echo 24 > /sys/class/gpio/export #exportiere Pin
echo "in" > /sys/class/gpio/gpio24/direction #als Eingang
echo "falling" > /sys/class/gpio/gpio24/edge #fallende Flanke
echo "1" > /sys/class/gpio/gpio24/active_low # 0V wird als Impuls erkannt
Das funktioniert auch. Wenn ich mir nach dem Systemstart die Dateien anschaue stehen da auch die Werte drin.
Aggregation würde ich erstmal noch raus nehmen, das passt auf deinen Anwendungsfall vermutlich weniger.
Das hab ich extra drin gelassen damit man direkt unterscheiden kann ob wirklich kein Verbauch da war oder ob der Raspberry stromlos war / der vzlogger nicht funktioniert hat etc. Laut wiki kann man dann mit aggtime den Abstand zwischen zwei gesendeten Datenpunkten festlegen. Oder stört diese Einstellung dann auch wenn Impulse kommen?
Es kommt mit der letzten Version von Raspian leider gelegentlich vor das rc.local, und damit der Export der GPIOs, noch nicht vollständig abgearbeitet ist wenn vzlogger startet.
Ich habe das jetzt so umgangen, dass der vzlogger daemon erst 30s nach systemstart losläuft.
In /etc/systemd/system die Datei vzlogger.service als sudo mit nano bearbeitet und folgende Zeile bei [Service] eingefügt: ExecStartPre=/bin/sleep 30Das hat gut funktioniert.
Das eigentlich Problem besteht aber weiterhin. Ich bekomme keine Daten im Frontend. Woran kann es noch liegen bzw. wie kann ich noch auf Fehlersuche gehen? Mit dem Multimeter gemessen bekomme ich jedenfalls die Signale am entsprechenden Pin...
Guten Morgen,
leider funktioniert das Auslesen des Sensors nicht.
Der Kanal im Frontend ist als Gas (S0-Impulse) mit einer Auflösung von 100 eingerichtet.
Meine vzlogger.conf sieht so aus:
{
"retry": 0,
"verbosity": 1,
"log": "/var/log/vzlogger/vzlogger.log",
"push": [],
"local": {
"enabled": false,
"port": 8080,
"index": false,
"timeout": 0,
"buffer": 0
},
"meters": [
{
"enabled": true,
"allowskip": false,
"interval": -1,
"aggtime": 60,
"aggfixedinterval": false,
"channels": [
{
"api": "volkszaehler",
"uuid": "xxx",
"identifier": "Impulse_neg",
"middleware": "http://localhost/middleware.php",
"aggmode": "sum",
"duplicates": 0
}
],
"protocol": "s0",
"device": "",
"gpio": 24,
"mmap": "",
"gpio_dir": -1,
"configureGPIO": true,
"resolution": 100,
"send_zero": true,
"debounce_delay": 0,
"nonblocking_delay": 100000
}
]
}
Alles anzeigen
Ich habe alternativ auch schon versucht "configureGPIO" auf false zu setzen und dann den Eingang am Raspberry manuell zu setzen. Ich habe dafür in der /boot/config.txt den Einrag gpio=24=ip,pn hinzugefügt. Also den GPIO24 als Eingang und ohne Pull-Up / Pull-Down Widerstand konfiguriert.
Des weiteren habe ich in der /etc/rc.local folgendes eingetragen:
echo 24 > /sys/class/gpio/export #exportiere Pin
echo "in" > /sys/class/gpio/gpio24/direction #als Eingang
echo "falling" > /sys/class/gpio/gpio24/edge #fallende Flanke
echo "1" > /sys/class/gpio/gpio24/active_low # 0V wird als Impuls erkannt
Leider hat dies auch nichts genutzt. Nach dem ganzen Testen ist leider gestern Abend noch ein Fehler dazu gekommen: Nach einem Neustart des Raspberry startet der vzlogger nicht mehr automatisch. "sudo service vzlogger status" meldet einen Fehler. Ohne Änderungen vorzunehmen startet vzlogger nach Eingabe von "sudo service vzlogger start" ohne Fehler und läuft. Woran liegt das?
Viele Grüße
grassh0pper
Hallo, ich habe o.g. Gaszähler mittels Induktivem Näherungssensor an den Raspberry Pi angeschlossen. Der Sensor bekommt seine 12V Betriebsspannung von einem Step-Up Modul. Den Ausgang teile ich über einen Spannungsteiler wieder runter auf 3,3V. Der Sensor geht auf 0V wenn der metallische "Viertelmond" des Gaszählers bei x,x4m^3 ankommt und geht wieder auf 3,3V wenn der Gaszähler über x,x6m^3 läuft.
0V für 0,02m^3 und
3,3V für 0,08m^3 .
Ich habe dazu 3 Fragen:
1. Wie konfiguriere ich die vzlogger.conf für s0 für diesen Fall?
2. Was passiert, wenn der Gaszähler z.b. auf x,x5m^3 stehen bleibt?
3. Wie lange darf der negative Puls bei s0 sein damit dieser korrekt erkannt wird. Im Sommer wenn Gas nur für Warmwasser genutzt wird kann dieser Zustand beispielsweise stundenlang bestehen bleiben...
Viele Grüße
Moin, leider ist das ganze noch etwas buggy. Die Einstellungen in der "maxPrecision" werden ignoriert, es wird für alle Einheiten die Einstellung aus der precision übernommen...