Hallo zusammen,
ich bin dabei meine Gartenbewässerung zu planen. Um vorab alles schon zu testen habe ich mir einen Dummy angelegt und ein at, dass die Regenmenge erfasst und entsprechend alle 3Tage bewässert.
Die readings werden in den Dummy geschrieben und geloggt.
Nun habe ich das Problem, dass die readings nicht in der Reihenfolge angelegt werde, wie sie im at entstehen.
Das wäre aber nützlich um die korrekte Funktion meines at's zu kontrollieren.
Gibt es eine Möglichkeit, dies zu korrigieren?
das at:
*04:00 {fhem("sleep 0.1 quiet; \
setreading Regen Regenmenge_IST " . (ReadingsVal("KS300","rain",0) - ReadingsVal("Regen","Regenzaehler",0)))};\
{if (ReadingsVal("Regen","Regenmenge_IST",0) >= 10) \
{fhem("setreading Regen Tag 0;sleep 0.1 quiet;\ setreading Regen Regenzaehler " . (ReadingsVal("KS300","rain",0)));} \
else {fhem "setreading Regen Tag ".(ReadingsVal("Regen","Tag",0)+1)};};\
{if (ReadingsVal("Regen","Tag",0) >= 3)\
{fhem "set Regen on-for-timer 10;setreading Regen Tag 0;sleep 0.1 quiet;\
setreading Regen Regenzaehler " . (ReadingsVal("KS300","rain",0))};}
das Log:
2019-08-24_04:00:00 Regen Tag: 3
2019-08-24_04:00:00 Regen on
2019-08-24_04:00:00 Regen Tag: 0
2019-08-24_04:00:00 Regen Regenmenge_IST: 0
2019-08-24_04:00:00 Regen Regenzaehler: 1628.4
2019-08-24_04:00:10 Regen off
Regenmenge_IST z.B. müsste am Anfang stehen.
Und bitte nicht schreien, wenn es steht werde ich mich an Perl versuchen und es in die myUtils auslagern. ;)
Danke und Gruß Bernd
Du loggst die Events. Das dauert halt und geht durch diverse Stationen.
Wenn Du eine Zeitnahe Ausgabe willst baue Logausgaben ein in Dein at.
Log(1,'Loggingtext')
;
Ja, die Idee hatte ich auch, nur mit Log wird in die globale Log-Datei geloggt.
Ich hätte gerne mehrere Tage zusammenhängend in einer separaten Datei, so wie es, bis auf die Reihenfolge momentan passiert.
Oder kann ich bei Log die entsprechende Datei mit angeben?
Du kannst nur global das Logfile angeben.
Du kannst aber ohne weiteres in Dein at ein Befehl schreiben das er auf die Platte in eine Datei irgendwas reinschreibt. Das wiederum ist aber Perl. ;)
my $fileName = '/opt/fhem/log/MeinRegen.log';
if(open(FH, ">>$fileName")) {
print(FH 'Das ist mein Test' . "\nl");
close(FH);
return undef;
}
else {
return "Can't open $fileName: $!";
}
Schau mal ob das so passt.
Danke für den Code.
Zum Verständnis: Am Anfang des at die Datei festlegen und bei jedem Reading das If.
Oder kann ich das If über den kompletten at Code legen?
Z.B. If Open Datei... setreading...print...setreading...print..Close Datei...
Muß die Datei vorher manuell angelegt werden?
Alternativ in einer sub auslagern, dann kann ich aber gleich beginnen alles in eine sub zu schreiben ;)
if(open(FH, ">>$fileName")) {
Das ganz am Anfang einfügen Also gleich nach dem ersten {
Und das
}
else {
return "Can't open $fileName: $!";
}
Kommt ganz ans Ende vor dem letzten }
So hatte ich es gemeint, danke.
Werde es testen und bescheid geben wenn es funktioniert...
Hallo CulTux,
nach viel Syntax-Fehlern, bis mir klar wurde, dass ich schon in Perl bin und nicht zw. Perl und Fhem wechsle, funktioniert es jetzt (hatte viel zu viele Klammern) ::).
Danke nochmal.
bei deinem Code
print(FH 'Das ist mein Test' . "\nl");
ist das l zuviel
print(FH 'Das ist mein Test' . "\n");
Für die die es interessiert:
*04:00 {
my $fileName = '/opt/fhem/log/1-Bewaesserung.log';
if(open(FH, ">>$fileName")) {
fhem("sleep 0.1 quiet;
setreading Regen Regenmenge_IST " . (ReadingsVal("KS300","rain",0) - ReadingsVal("Regen","Regenzaehler",0)));
print(FH localtime . ' ' . 'Regenmenge_IST' . "\n");
if (ReadingsVal("Regen","Regenmenge_IST",0) >= 10) {
fhem("setreading Regen Tag 0");
print(FH localtime . ' ' . 'Tag0' . "\n");
fhem("sleep 0.1 quiet;setreading Regen Regenzaehler " . (ReadingsVal("KS300","rain",0)));
print(FH localtime . ' ' . 'Regenzaehler' . "\n");
}
else {
fhem "setreading Regen Tag ".(ReadingsVal("Regen","Tag",0)+1);
print(FH localtime . ' ' . 'Tag+1' . "\n")
};
if (ReadingsVal("Regen","Tag",0) >= 3) {
fhem ("set Regen on-for-timer 10");
print(FH localtime . ' ' . 'an' . "\n");
fhem ("setreading Regen Tag 0");
print(FH localtime . ' ' . 'Tag0' . "\n");
fhem "sleep 0.1 quiet;setreading Regen Regenzaehler " . (ReadingsVal("KS300","rain",0));
print(FH localtime . ' ' . 'Regenzaehler' . "\n");
}
close(FH);
return undef;
}
else {
return "Can't open $fileName: $!";
}
}
Die Log-Datei musste ich manuell anlegen.
Als nächstes:
alles in myUtils
einbinden von Bodenfeuchte, Beregnungsmenge und Durchflussmenge etc. ;D
So, da im obigen Code noch Fehler, bzw. Verbesserungsbedarf war hier mein aktueller Stand (immer noch in der Testphase mit einem Dummy "Regen"):
Den Code habe ich mittlerweile in 99_myUtils ausgelagert und alle Werte über Variablen deklariert, damit ich auch die berechneten Daten ins log bekomme.
Das at sieht nun so aus:
defmod at_Beregnung at *04:00 {Bewaesserung()}
und in myUtils steht:
sub Bewaesserung() {
my $fileName = '/opt/fhem/log/1-Bewaesserung.log';
my $Regenzaehler = (ReadingsNum("KS300","rain",0,1));
my $RegenzaehlerAlt = (ReadingsNum("Regen","Regenzaehler",0,1));
my $Regenmenge = $Regenzaehler-$RegenzaehlerAlt;
my $Regenmenge = sprintf("%.1f", $Regenmenge);
my $Tag = (ReadingsNum("Regen","Tag",0));
my $Beregnungsmenge = 0;
if(open(FH, ">>$fileName")) {
fhem "setreading Regen Regenmenge_IST $Regenmenge ";
print(FH localtime . ' Regenmenge_IST: ' . $Regenmenge . "\n");
if ($Regenmenge >= 10) {
fhem "setreading Regen Tag 0";
print(FH localtime . ' Tag: 0' . "\n");
fhem "setreading Regen Regenzaehler $Regenzaehler ";
print(FH localtime . ' Regenzaehler: ' . $Regenzaehler . "\n");
}
else {
$Tag = $Tag+1;
fhem "setreading Regen Tag $Tag ";
print(FH localtime . ' Tag: ' . $Tag . "\n");
if ($Tag >= 3) {
if ($Regenmenge < 10) {
$Beregnungsmenge = 10-$Regenmenge+2;
}
else {
$Beregnungsmenge = 0};
if ($Beregnungsmenge > 10) {
$Beregnungsmenge = 10;
}
print(FH localtime . ' Beregnungsmenge: ' . $Beregnungsmenge . "\n");
fhem "set Regen on-for-timer 10";
print(FH localtime . ' Beregnung: an' . "\n");
fhem "setreading Regen Tag 0";
print(FH localtime . ' Tag: 0' . "\n");
fhem "setreading Regen Regenzaehler $Regenzaehler ";
print(FH localtime . ' Regenzaehler: ' . $Regenzaehler . "\n");
}
}
close(FH);
return undef;
}
else {
return "Can't open $fileName: $!";
}
}
Als Tipp:
Mein Filelog ist noch existent aber deaktiviert.
defmod log_Bewaesserung FileLog ./log/%y-Bewaesserung.log Regen
attr log_Bewaesserung disable 1
Da mein Logfile, das ich mittels Perlcode beschreibe, den "gleichen" Name hat erscheint es in Fhem unter meinem definierten Filelog und kann so leicht eingesehen werden (siehe Bild).
Nur mal so am Rande ein anderer Weg um die Regenmenge zu ermitteln. Zumindest kann man davon evtl. auch ableiten.
Ich habe das bei mir so gelöst, dass ich alle Regenmeldungen meiner Wetterstation die einen Wert > 100 haben zähle und mir einen Grenze z.B. 12 festgelegt habe, ab dem es genug geregnet hat und ich nicht bewässern muss. Eine Meldung kommt alle 5 Minuten, somit ergeben 12 positiv Meldungen = 1h nass.
Dazu habe ich ein userReadings erstellt
attr Regensensor userReadings raincount {RainCount()}
Und dazu eine function geschrieben, die in der Datenbank die Vorkommen zählt.
# RainCount (Regen-Zähler)
sub RainCount() {
use strict;
use DBI;
my $dbh = DBI->connect(
"dbi:SQLite:dbname=/var/log/fhem/fhem.db",
"",
"",
{ RaiseError => 1 },
) or die $DBI::errstr;
my $sth = $dbh->prepare("select count(VALUE) from history where DEVICE like 'Regensensor' AND cast(VALUE as INTEGER) > 100 AND TIMESTAMP >= datetime('now','-1 day') order by TIMESTAMP");
$sth->execute();
my $row = $sth->fetchrow_array();
return $row;
}
Danke, dein Code sieht profimäßig aus.
Bei mir ist es der erste selbst geschriebene.
Was bedeutet dein Zahlenwert von der Wetterstation?
Ich habe eine KS300, die summiert durchgehend den Regenzähler in l/m3 auf.