Tage-Counter mit Dummy (Pflanzen Gießen Erinnerung)

Begonnen von Nogga, 12 Februar 2018, 12:52:37

Vorheriges Thema - Nächstes Thema

Nogga

Hallo zusammen,

meine Pflanzen möchte ich (noch) nicht mit Sensoren ausstatten. Als notorischer Gieß-Vergesser möchte ich aber trotzdem das Gießen in FHEM nachhalten.

Meine Idee:

1. Jede Pflanze bekommt ein Dummy
2. Der Dummy hat das letzte Gießdatum ("LetztesGiessen")
3. Zusätzlich auch ein Gießintervall in Tagen ("GiessIntervall")

Jetzt möchte ich:
FHEM regelmäßig checkt, ob das Intervall erreicht ist, wenn ja ein (state) Reading von "OK" auf "Gießen" stellt.
Per webcmd möchte ich dann wiederum das Gießen "abschließen", d.h. das Datums-Reading wieder auf jetzt stellen bei Auslösen.

Ich glaube, das ist ziemlich simpel. Aber irgendwie stehe ich auf dem Schlauch. Insbesondere das Datum, bzw. die Fälligkeit  zu kalkulieren...

Der Vollständigkeit halber, was ich dann noch vorhabe:
Über alle Pflanzen-Dummies ziehe ich eine Readingsgroup. In meinem Tablet UI zähle ich zunächst die überfälligen Pflanzen und zeige dies mit einem Icon + Counter an (vgl. Fenster-Offen-Counter). Über ein Popup zeige ich dann alle fälligen Pflanzen an, die ich dann per Touch "als gegossen" zurücksetzen kann).

rabehd

Ich habe ähnliche Fragen per Forensuche und Google lösen können. U.a. mir Hilfe des Blogs von Otto (glaube ich).

Zuerst würde ich Das stückweise verwirklichen.

ZitatFHEM regelmäßig checkt, ob das Intervall erreicht ist, wenn ja ein (state) Reading von "OK" auf "Gießen" stellt.
Wie wäre es mit einem at?

ZitatPer webcmd möchte ich dann wiederum das Gießen "abschließen", d.h. das Datums-Reading wieder auf jetzt stellen bei Auslösen.
http://heinz-otto.blogspot.de/2017/01/ein-remote-taster-in-fhem-mit.html
Auch funktionierende Lösungen kann man hinterfragen.

Nogga

Ich glaube auch, dass ich das alleine hinbekomme. Das at ist mir klar.
Das einzige, was evtl. zur Selbsthilfe fehlt ist das spezifische Intervall berechnen.

Sowas in der Art (Pseudocode):

if ((JetztTimestamp - IntervallAusReading) > LetztesGiessenAusReading) set Dummy.state = 'Giessen'

Wie mache ich das in Perl?
Idealerweise als wiederverwendbares Stück Code, das ich in jedes Dummy einpflanzen kann, bzw. 1x generisch per at aufrufen kann und alle Dummies abklopft...

rabehd

Im Dummy wird Dir der Code nichts nutzen. Du musst die Berechnung doch auslösen.

Ich würde eine Funktion für 99_myUtils.pm bauen, welche ein Datum und ein Intervall übergeben bekommt und damit das Zieldatum errechnet.
(Gibt es bestimmt schon zum Koiieren)

Im at gehtst Du die einzelnen Dummys ab. Rufst mit deren Werten die Funktion auf. Wertest das Ergebnis aus und setzt ggf. den Wert für den Dummy.

Lässt sich natürlich noch optimieren.
Auch funktionierende Lösungen kann man hinterfragen.

CoolTux

Gab es da nicht mal so ein Modul für Erinnerungen? Mir fällt da leider gerade nicht ein wie das heißt.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Nogga

Meine letzten Perl-Ausflüge sind ungefähr 15 Jahre her... ziemlich eingerostet.

In der Theorie sollte alles klappen, nur das Auslesen der Timestamps über ReadingsVal funktioniert nicht. Kann da jemand helfen?
Und zuletzt: wie bekomme ich das at und notify generisch hin, dass ich im Zweifel alle "Pflanze_.*" oder noch besser alle Dummies mit dem Attribut Pflanze = 1 selektiere.

Folgende Logik:
- Ein Dummy repräsentiert eine Pflanze.
- Das letzte Giessen steckt in letztesGiessenTimestamp
- giessenIntervall ist in Sekunden
- das notify aktualisiert das letzte Giessen (kann man das auch direkt im Dummy einbauen?!)
- das at (nur zum Test alle 10 Sekunden) checkt ob das (Letzte Giessen + Interval) schon in der Vergangenheit liegt, wenn ja, dann muss gegossen werden und der Status des Dummies wird gesetzt


Folgendes habe ich zusammen:

defmod Pflanze_1 dummy
attr Pflanze_1 userattr letztesGiessenTimestamp giessenIntervall Pflanze
attr Pflanze_1 Pflanze 1
attr Pflanze_1 giessenIntervall 120
attr Pflanze_1 letztesGiessenTimestamp 1518469613
attr Pflanze_1 room Tablet-UI
attr Pflanze_1 setList state:ok,giessen
attr Pflanze_1 webCmd update


defmod notify_Pflanze_1 notify Pflanze_1 {\
if ("$EVENT" eq "update")\
{\
fhem('attr Pflanze_1 letztesGiessenTimestamp '.time());;\
}\
}\

attr notify_Pflanze_1 room Tablet-UI


defmod At_Pflanzen_Check at +*00:00:10 {\
Debug(ReadingsVal('Pflanze_1', 'letztesGiessenTimestamp', 0));;\
Debug(ReadingsVal('Pflanze_1', 'giessenIntervall', 0));;\
Debug(time());;\
if (ReadingsVal('Pflanze_1', 'letztesGiessenTimestamp', 0) + ReadingsVal('Pflanze_1', 'giessenIntervall', 0) > time())\
{\
# alles ok - Zeit noch nicht abgelaufen\
fhem("set Pflanze_1 ok");;\
Debug('Pflanze 1 ist ok');;\
}\
else\
{\
# nicht ok - Zeit ist abgelaufen!\
fhem("set Pflanze_1 giessen");;\
Debug('Pflanze 1 ist nicht ok - giessen!');;\
}\
}

Amenophis86

Zitat von: CoolTux am 12 Februar 2018, 18:58:19
Gab es da nicht mal so ein Modul für Erinnerungen? Mir fällt da leider gerade nicht ein wie das heißt.

Denke du meinst https://fhem.de/commandref_DE.html#monitoring
Aktuell dabei unser neues Haus mit KNX am einrichten. Im nächsten Schritt dann KNX mit FHEM verbinden. Allein zwei Dinge sind dabei selten: Zeit und Geld...

CoolTux

Zitat von: Amenophis86 am 12 Februar 2018, 22:31:29
Denke du meinst https://fhem.de/commandref_DE.html#monitoring

Jepp. Würde dann wohl unter regelmäßige Wartungsarbeiten (z.B. Tischwasserfilter wechseln oder Räume putzen) fallen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Zitat von: Nogga am 12 Februar 2018, 22:23:15
Meine letzten Perl-Ausflüge sind ungefähr 15 Jahre her... ziemlich eingerostet.

In der Theorie sollte alles klappen, nur das Auslesen der Timestamps über ReadingsVal funktioniert nicht. Kann da jemand helfen?
Und zuletzt: wie bekomme ich das at und notify generisch hin, dass ich im Zweifel alle "Pflanze_.*" oder noch besser alle Dummies mit dem Attribut Pflanze = 1 selektiere.

Folgende Logik:
- Ein Dummy repräsentiert eine Pflanze.
- Das letzte Giessen steckt in letztesGiessenTimestamp
- giessenIntervall ist in Sekunden
- das notify aktualisiert das letzte Giessen (kann man das auch direkt im Dummy einbauen?!)
- das at (nur zum Test alle 10 Sekunden) checkt ob das (Letzte Giessen + Interval) schon in der Vergangenheit liegt, wenn ja, dann muss gegossen werden und der Status des Dummies wird gesetzt


Folgendes habe ich zusammen:

defmod Pflanze_1 dummy
attr Pflanze_1 userattr letztesGiessenTimestamp giessenIntervall Pflanze
attr Pflanze_1 Pflanze 1
attr Pflanze_1 giessenIntervall 120
attr Pflanze_1 letztesGiessenTimestamp 1518469613
attr Pflanze_1 room Tablet-UI
attr Pflanze_1 setList state:ok,giessen
attr Pflanze_1 webCmd update


defmod notify_Pflanze_1 notify Pflanze_1 {\
if ("$EVENT" eq "update")\
{\
fhem('attr Pflanze_1 letztesGiessenTimestamp '.time());;\
}\
}\

attr notify_Pflanze_1 room Tablet-UI


defmod At_Pflanzen_Check at +*00:00:10 {\
Debug(ReadingsVal('Pflanze_1', 'letztesGiessenTimestamp', 0));;\
Debug(ReadingsVal('Pflanze_1', 'giessenIntervall', 0));;\
Debug(time());;\
if (ReadingsVal('Pflanze_1', 'letztesGiessenTimestamp', 0) + ReadingsVal('Pflanze_1', 'giessenIntervall', 0) > time())\
{\
# alles ok - Zeit noch nicht abgelaufen\
fhem("set Pflanze_1 ok");;\
Debug('Pflanze 1 ist ok');;\
}\
else\
{\
# nicht ok - Zeit ist abgelaufen!\
fhem("set Pflanze_1 giessen");;\
Debug('Pflanze 1 ist nicht ok - giessen!');;\
}\
}


Da Du Deinen Code aus der Config Datei hast kann ich da nicht helfen. Keine Lust irgendein Backslash zu über sehen. So was ist unnötig. Alles kann man in der Detailansicht mit DEF editieren, sogar mit Syntaxprüfung. Ansonsten ein list vom Device/Notify passt gut damit wir alles sehen können.
Timestamp mact man mit ReadingsTimestamp. Da ich das auch nicht altäglich mache musste ich auch danach suchen, und was soll ich sagen mit der suche findet man das sogar.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Nogga

Ich habe meinen Code nicht aus der Config genommen, da ich die ConfigDB nutze. Offensichtlich hat er die Escapes beim Kopieren eingefügt. Ich habe alle Definitionen aus den DEF bzw RawDefinition Feldern. Aber ichbwerde mir ReadingsTimestamp nochmal genauer ansehen. Danke.

Nogga

Ich habe gerade gesehen, dass ich wohl alles aus den RawDefinitions genommen habe statt aus den DEF Feldern, deswegen die Escapes... aber ich werde es heute Abend auch gerne nochmal sauber als copy aus den DEF Feldern Posten...

Nogga

So, ich glaube ich habe es jetzt geschafft. Das at checkt wann zuletzt gegossen wird und wenn das Intervall überschritten wird, dann wird die Pflanze auf giessen (=pour) gesetzt.

Jetzt fehlt nur noch ein Detail: das notify reagiert momentan auf ein bestimmtes Dummy (Pflanze_1), wie bekomme ich das generisch hin, dass auf alle Dummies mit dem Attribut model=Pflanze reagiert wird?

(Dummy aus dem Raw Definition, notify und at aus dem DEF-Editor kopiert...)


defmod Pflanze_1 dummy
attr Pflanze_1 userattr pourInterval model
attr Pflanze_1 model Pflanze
attr Pflanze_1 pourInterval 20
attr Pflanze_1 room Tablet-UI
attr Pflanze_1 setList state:ok,giessen
attr Pflanze_1 webCmd update


At_Pflanzen_Check:
+*00:00:10 {
if (time_str2num(ReadingsTimestamp('Pflanze_1', 'lastPouringTimestamp', 0)) + AttrVal('Pflanze_1', 'pourInterval', 0) > time())
{
# alles ok - Zeit noch nicht abgelaufen
fhem("set Pflanze_1 ok");
Debug('Pflanze 1 ist ok');
}
else
{
# nicht ok - Zeit ist abgelaufen!
fhem("set Pflanze_1 giessen");
Debug('Pflanze 1 ist nicht ok - giessen!');
}
}


Notify:
Pflanze_1 {
if ("$EVENT" eq "update")
{
fhem('setreading $NAME lastPouringTimestamp '.localtime());
fhem('set $NAME ok');
}
}

CoolTux

Dein Notify sieht seltsam aus und sollte so eigentlich nicht gehen. Ausser es fehlt hier in der Anzeige was.

Notify arbeitet mit RegEx. Mach also aus Dein Pflanze_1 ein Pflanze.* als Trigger und überall wo Du im Code Pflanze_1 hast machst Du $NAME
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Nogga

Naja eine Regex muss nicht immer wildcards haben /Pflanze_1/ funktioniert genau so. Halt exakt auf den Namen.
Die Variante mit .* auf den Namen kenne ich. Ich wollte aber nicht auf Namen filtern, sondern auf Attribute.. ich habe das schon gesehen, finde es aber nicht mehr.

CoolTux

Du kannst ein Notify RegEx nur auf NAME triggern lassen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net