FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: errazzor am 26 Oktober 2015, 00:36:12

Titel: DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 00:36:12
Hallo,

ich möchte innerhalb eines DOIF ein State (Zeitstempel) auslesen und wenn dieser mehr als 600 Sekunden zurück liegt, soll Aktion X ausgeführt werden.
Allerdings verzweifle ich an der Syntax:


define DOIF_TEST1 DOIF ([Anwesenheit.Dummy] eq "off" and {(time-time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0) > 600))}) (set Test.Dummy on)


Funktioniert nicht, weil laut Logfile:


2015.10.26 00:31:25 1: PERL WARNING: Argument "2015-10-26 00:31:25" isn't numeric in numeric gt (>) at (eval 67324) line 1.
2015.10.26 00:31:25 1: PERL WARNING: Use of uninitialized value in subtraction (-) at (eval 67324) line 1.
2015.10.26 00:31:25 1: PERL WARNING: Odd number of elements in anonymous hash at (eval 67324) line 1.


Ich vermute mal die Klammern stimmen einfach nicht, kann mir jemand weiterhelfen?
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: Sirel am 26 Oktober 2015, 07:19:47
Hallo Errazzor,
mit Readingstimestamp wird auch das aktuelle Datum zurückgegeben. Damit kann dann das DOIF nichts mehr anfangen (Zeile 1 im Log).
Habe damit auch schon rumexperimentiert, aber keine Lösung für das Problem gefunden.

Max
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: igami am 26 Oktober 2015, 07:45:11
Warum nutzt du nicht einfach das wait Attribut und spendierst dann noch ein DOELSE?
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 09:04:41
Also das mit dem ReadingsTimestamp funktioniert ja soweit, zumindest wenn ich ich den gleichen Befehl in der FHEM Kommandozeile ausführe.

Mit o.g. Befehl bekomme ich die Anzahl Sekunden zurück, welche seit dem Timestamp vergangen sind.
Nur die Verschachtelung in der DOIF-Schleife bekomme ich nicht hin.

Die Fehlermeldung im Log kommt nur, weil die Verschachtelung (Klammern) nicht korrekt ist und FHEM den Befehl somit nicht richtig ausführt.
Aber ich habe bisher nicht herausgefunden, wie die Klammern aussehen müssen, es ist zum wahnsinnig werden.

@igami: Verstehe leider nicht was Du meinst, kannst Du etwas genauer werden?

Sonst jemand noch eine Idee, wie das oben genannte DOIF richtig aussehen müsste?
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 09:26:04
Mal ab von Deinem Problem. Schreib uns bitte einmal was genau Dein Ziel ist.

Ich sehe in Deinem DOIF kein wirklichen Sinn.


define DOIF_TEST1 DOIF ([Anwesenheit.Dummy] eq "off" and {(time-time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0) > 600))}) (set Test.Dummy on)


Triggert Anwesenheit.Dummy auf off und der Timestamp vom Status Anwenheit ist älter wie +600 dann schalte einen anderen Dummy on???

Mach mal so


define DOIF_TEST1 DOIF ([Anwesenheit.Dummy] eq "off" ) (set Test.Dummy on) DOELSE ()
attr DOIF_TEST1 wait 600


Sollte glaube gehen
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 09:48:24
Die DOIF-Abfrage ist nur zu Testzwecken verkürzt und gibt in der o.g. Form tatsächlich keinen Sinn, hier geht es mir nur im die Funktion.

Im Echtbetrieb sind da noch mehr Bedingungen drin, sodaß es Sinn ergibt.

Das Ziel ist das setzen eines Alarm-Dummys auf on, wenn zwei Bewohner abwesend sind und ein Türkontakt geöffnet wird - allerdings nur, wenn der Status des zuletzt gegangenen Bewohners mindestens vor 10 Minuten auf "abwesend" gesetzt wurde und wenn sich kein Bewohner in den nächsten 2 Minuten wieder anmeldet.

Und für das "mindestens seit 10 Minuten abwesend" brauche ich eben den Zeitstempel des Dummys um diesen mit der aktuellen Uhrzeit zu vergleichen.

Daher reicht ein reines wait leider nicht.

Hier mal zur Verdeutlichung mein ( noch nicht funktionierendes) komplettes DOIF:


define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [Status.EG] eq "on" and (time-time_str2num(ReadingsTimestamp("Anwesenheit.Dummy1","state",0) > 600))) (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


--> Wenn Bewohner1 und Bewohner2 "absent" sind und Status.EG (Fenster/Tür offen) auf "on" und Bewohner1 sich vor mehr als 10 Minuten abgemeldet hat, setze Alarm-Dummy auf "on".
Ausführung allerdings erst nach 120 Sekunden (Warteschleife, ob sich in der Zeit ein Bewohner anmeldet)


Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 10:17:34

define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [?Status.EG] eq "on") (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 300


Getriggert werden nur die Anwesenheitsdummy und es wird als Bedingung geschaut ob Status.EG on ist. Sollte sich innerhalb der nächsten 5 Minuten keine Änderung ergeben wird geschalten.

Davon aber mal ab kannst Du Dir mal Residents und Roommate anschauen. Das ist ein virtuelles zuHause mit Bewohnern. Residents ist das Haus und Roommate sind die Bewohner. Das Haus schaltet sich entsprechend der Schaltung aller Bewohner. Dazu gibt es dann noch fertige Scripte für Abläufe die gestartet werden sollen.

Bsp.:
Bewohner1 ist abwesend und Bewohner2 ist home. Status Residents bleibt home. Bewohner2 ist dann irgendwann auch abwesend Status Residents geht auf abwesend. Bewohner1 kommt Status Residents geht auf home Bewohner2 kommt Status Residents bleibt auf home.

Nun kannst Du ganz einfach Deine Alarmanlage schalten


define doifAlarmScharf DOIF ([Residdents] eq "absent" and [?Status.EG] eq "on") (set alarm on) DOELSE ()
attr doifAlarmScharf wait 600

Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 10:35:44
Ja, dein Beispiel hatte ich ja schon funktionierend am laufen, nur fehlt mir da eben die Bedingung "Bewohner seit mindestens 10 Minuten absent" - darum ging es mir hier ja.

Ich glaube ich habe es jetzt aber beim 10000. Versuch wie folgt hinbekommen:


define DOIF_EG_Alarm_TEST DOIF ([Anwesenheit.Dummy] eq "off" and ([{time}]-[{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0))}] > 600)) (set Alarm.EG on)


Muss das ganze jetzt nur noch im Realbetrieb testen, aber es sieht gut aus :-)

Vielen Dank für den Hinweis auf Residents / Roommate, das schaue ich mir mal an!


Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: AET_FHEM am 26 Oktober 2015, 10:42:43
Wieso macht man das nicht einfach mit einem Watchdog?


define WD_EG_Alarm_TEST  Anwesenheit.Dummy:off 00:10 Anwesenheit.Dummy:on set Alarm.EG on; setstate WD_EG_Alarm_TEST defined
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 10:47:59
Gute Frage, wie würde denn die Umsetzung mit einem Watchdog für das komplette DOIF (siehe unten) aussehen?


define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [Status.EG] eq "on" and ([{time}]-[{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy1","state",0))}] > 600)) (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: AET_FHEM am 26 Oktober 2015, 11:18:27
ja da müssen wir Dummy1 und Dummy2 als struktur anlegen
=> um dummy1 und Dummy2 zu verbinden und eine Meldung draus zu machen

So etwa:
define Familie structure Familie_structure Dummy2 Dummy1
attr Familie clientstate_behavior relative
attr Familie clientstate_priority present absent
attr Familie event-on-change-reading state
attr Familie group Familie
attr Familie room Haus,HomeStatus

und 

define WD_EG_Alarm_TEST  Familie:absent 00:10 Familie:present set Alarm.EG on; setstate WD_EG_Alarm_TEST defined

--> hier sagen wir wenn die Struktur (Dummy1+Dummy2) 10 minuten nicht anwesend sind dann schalte Alarm EG on
=> damit müsste es klappen
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 11:18:42
Zitat von: errazzor am 26 Oktober 2015, 10:35:44
Ja, dein Beispiel hatte ich ja schon funktionierend am laufen, nur fehlt mir da eben die Bedingung "Bewohner seit mindestens 10 Minuten absent" - darum ging es mir hier ja.

Dein Problem ist das Du null Ahnung hast von DOIF oder es nicht verstehst. Bitte nicht persönlich nehmen aber als Kritik.
Das Ding mit den "Bewohner seit mindestens 10 Minuten absent" ist ja das wait. Das DOIF wird nur geschalten wenn es sich nicht innerhalb der nächsten (bei mir waren es 5 Minuten glaube) ändert wait 300.
Also was stand im DOIF


([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [Status.EG] eq "on"

Sollten sich diese Zustände in den nächsten 10 Minuten nicht ändern, wird

set Alarm.Status.EG on

geschalten

wait 600 also als attribut

Und ja man kann es auch mit einem watchdog machen. Aber DOIF kann es auch, wenn man versteht wie DOIF funktioniert oder wenigstens versucht sich die commandref mal an zu schauen wo DOIF eines der mit bestens dokumentierten Module ist mit endlos vielen Beispielen.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 11:22:18
Ähm könnten wir mal versuchen das ganze einfach zu halten. Es gibt bereits fertige Module die super tolle Eigenschaften haben mit denen man ein Haus/Wohnung und deren Bewohner darstellen kann. Aber nein stattdessen wird hier mit Dummy und Structure gearbeitet.
Mal so ne Frage, was willst Du dem Threadersteller sagen wenn er kommt mit Weckzeiten, Aufwachschaltungen oder Bettgehschaltungen. Wieder mit Dummy und Structure?

Bitte bitte verwendet doch die schon vorhandenen Möglichkeiten welche eine einfach nachvollziehbare Schaltung möglich machen. Die nächste Frage wäre dann wohl wie funktioniert watchdog.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 11:28:04
Zitat von: CoolTux am 26 Oktober 2015, 11:18:42
Dein Problem ist das Du null Ahnung hast von DOIF oder es nicht verstehst. Bitte nicht persönlich nehmen aber als Kritik.
Das Ding mit den "Bewohner seit mindestens 10 Minuten absent" ist ja das wait. Das DOIF wird nur geschalten wenn es sich nicht innerhalb der nächsten (bei mir waren es 5 Minuten glaube) ändert wait 300.
Also was stand im DOIF


([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [Status.EG] eq "on"

Sollten sich diese Zustände in den nächsten 10 Minuten nicht ändern, wird

set Alarm.Status.EG on

geschalten

wait 600 also als attribut


Tut mir leid, aber Du hast offenbar nicht verstanden, was meine Anforderung ist. Dann gleich in so einem Ton zu antworten naja, ich weiss nicht.
Natürlich habe ich bereits die Commandref bemüht, aber ich habe es bisher trotzdem nicht hinbekommen. Nicht jeder ist ein begnadeter Programmierer.

In deinem Beispiel wird einfach 10 Minuten gewartet ob sich etwas ändert - das habe ich wie bereits geschrieben auch schon hinbekommen.
Allerdings deckt es nicht meine Anforderung wie schon zu Anfang beschrieben ab:

* Es ändert sich innerhalb von 2 Minuten nichts (Bewohner meldet sich nicht an) UND der Bewohner ist seit x Minuten abwesend. Das in Verbindung mit dem "on" Status des Staus-EG-Dummys soll erst das Event auslösen.

Darum doch die ganze Geschichte mit dem Auslesen der zeit des Dummys.

Übrigens funktioniert mein oben gepostetes Beispiel doch noch nicht, irgendwas stimmt mit dem ausgelesenen Wert noch nicht.

Ich poste es gerne nochmal:


define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [Status.EG] eq "on" and ([{time}]-[{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy1","state",0))}] > 600)) (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


Hier ist doch zu sehen, ich habe ein "wait 120" - dieses sorgt dafür, dass das ganze DOIF erst nach 120 Sekunden ausgeführt wird (sprich der Status der Bewohner ändert sich nicht innerhalb dieser Zeit).

So..ändert sich der Bewohnerstatus innerhalb 120 Sekunden nicht, soll der Alarm auch nur dann auf "on" gesetzt werden, wenn der Bewohner schon seit mehr als 10 Minuten abwesend ist.

Das ist alles. Nur wie gesagt, bisher funktioniert der zeitvergleich noch nicht, der zeitvergleich ist offenbar nicht plausibel. "> 600" wird nicht korrekt umgesetzt, auch wenn der Rückgabewert beispielsweise 9130 ist. Ändere ich es in "< 600" löst der Alarm aus, obwohl der Rückgabewert wie gesagt 9130 ist. Irgendwas stimmt da noch nicht.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 11:50:49
Das ist mir zu hoch. Sorry aber ich verstehe Dich nicht. Tut mir leid. Ich glaube das ich alles gegeben habe um genau Deine eben noch mal beschriebende Anforderung zu erfüllen. Aber so wie es scheint habe ich Dich in der Tat nicht korrekt verstanden.


define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [?Status.EG] eq "on") (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


Dummy1 und Dummy2 lösen das DOIF aus. Bedingung ist das Dummy1 und Dummy2 off sind und Status.EG on ist. Wird alleine diese Bedingung nicht erfüllt wird nichts gemacht. Wird die Bedingung erfüllt, wird 120 Sekunden gewartet ob sich Dummy1 oder Dummy2 nicht doch wieder mit einem on melden, melden sie sich nicht mit einem on innerhalb der nächsten 120 sekunden wird der Alarm auf on gesetzt, wenn sich doch etwas tut und Dummy1 oder 2 bekommen ein on wird nichts gemacht.

Sollte das hier jetzt nicht das sein was Du wolltest, dann habe ich Deine Anforderung falsch verstanden und dann entschuldige ich mich dafür.

Hier Beispiele aus der Comandref

define di_washer DOIF ([power:watt]<2) ({system("wmail washer finished")})
attr di_washer wait 300

Eine erneute Benachrichtigung wird erst wieder ausgelöst, wenn zwischendurch der Verbrauch über 2 Watt angestiegen war.

Anwendungsbeispiel: Rolladen um 20 Minuten zeitverzögert bei Sonne runter- bzw. hochfahren (wenn der Zustand der Sonne wechselt, wird die Verzögerungszeit zurückgesetzt):

define di_shutters DOIF ([Sun] eq "on") (set shutters down) DOELSE (set shutters up)
attr di_shutters wait 1200:1200



Zitat
Bewohner ist seit x Minuten abwesend

Ist es nicht logisch das der Bewohner 120 Sekunden abwesend ist wenn der Alarm geschalten wird, wenn zwischen dem Trigger Bewohner off und dem wait von 120 Sekunden geschalten wird?

Ich versuche Dich ernsthaft zu verstehen, also Dein Anliegen.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 12:10:15
Zitat von: CoolTux am 26 Oktober 2015, 11:50:49
Das ist mir zu hoch. Sorry aber ich verstehe Dich nicht. Tut mir leid. Ich glaube das ich alles gegeben habe um genau Deine eben noch mal beschriebende Anforderung zu erfüllen. Aber so wie es scheint habe ich Dich in der Tat nicht korrekt verstanden.

Vielleicht drücke ich mich ja auch unverständlich aus oder meine Gedanken sind viel zu kompliziert, ich versuche es nochmal bestmöglich zu beschreiben.

Zitat

define DOIF_EG_Alarm_on DOIF ([Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off" and [?Status.EG] eq "on") (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


Dummy1 und Dummy2 lösen das DOIF aus. Bedingung ist das Dummy1 und Dummy2 off sind und Status.EG on ist. Wird alleine diese Bedingung nicht erfüllt wird nichts gemacht. Wird die Bedingung erfüllt, wird 120 Sekunden gewartet ob sich Dummy1 oder Dummy2 nicht doch wieder mit einem on melden, melden sie sich nicht mit einem on innerhalb der nächsten 120 sekunden wird der Alarm auf on gesetzt, wenn sich doch etwas tut und Dummy1 oder 2 bekommen ein on wird nichts gemacht.

Soweit genau richtig. Zusätzlich soll jetzt noch die Bedingung dazu: Der Zeitpunkt, an welchem Dummy1 auf "off" ging, liegt mehr als 10 Minuten zurück.

Zum Beispiel: 

* Status.EG geht auf "on", aufgrund einer Türoffnung
* Dummy1 ist "off" aber seit mindestens 10 Minuten
* Dummy2 ist "off"
* in den nächsten 120 Sekunden ändert sich der Status von Dummy1 und Dummy2 nicht

--> dann gibt es Alarm


Zitat
Ich versuche Dich ernsthaft zu verstehen, also Dein Anliegen.

Danke. Wie gesagt, offenbar drücke ich mich nicht verständlich genug aus oder versuche mein Anliegen auf einem zu komplizierten Weg zu lösen.

Hintergrund des ganzen ist folgender:

Wenn das Haus verlassen ist (Dummy1 und Dummy2 sind off bzw. absent) und es kommt jemand nach Hause, wird durch einen Türkontakt der Dummy Status.EG auf "on" gesetzt.
Ändert sich innerhalb 120 Sekunden der Status von Dummy1 oder Dummy2 nicht auf "on" bzw. "present" (kein Bewohner da, also Einbruch) wird der Alarm-Dummy auf "on" gesetzt.

Soweit so gut und das funktionierte ja auch schon mit dem wait 120.

Ich brauche jetzt aber als Workaround noch die Bedingung, dass das ganze nur passiert, wenn die Bewohner mindestens seit 10 Minuten auf "off" bzw. "absent" geschalten sind.
Hintergrund ist, dass es vorkommt dass die WLAN-Verbindung eines Smartphones wegbrechen kann und manchmal 5-6 Minuten braucht, bis das Smartphone wieder eingebucht ist.

Das gibt jedes mal einen Alarm, wenn alle Faktoren zusammen kommen, sprich:

- Bewohner ist zwar zu Hause, aber WLAN-Verbindung ist kurzzeitig unterbrochen
- Tür wird geöffnet
- Smartphone des Bewohners kommt nicht innerhalb 120 Sekunden wieder online (weil es bei einem Abbruch der bestehenden WLAN-Verbindung manchmal 5-6 Minuten braucht. Dies ist nicht der Fall, wenn man nach Hause kommt, der Fehler hängt mit Roaming zwischen zwei APs zusammen und kann derzeit nicht gelöst werden. Daher dieser Workaround!)

Natürlich könnte man jetzt sagen, setz doch einfach die 120 Sekunden hoch - das möchte ich aber nicht. Denn im Falle wenn wirklich keiner zu Hause ist, soll der Alarm spätestens nach 2 Minuten und nicht erst nach 10 Minuten ausgelöst werden.

Daher mein Gedankengang mit dem auslesen des Zeitstempels - wann ging der Bewohner "off" --> warum? Weil wenn die WLAN-Verbindung abbricht, wird nicht innerhalb von 120 Sekunden sondern erst nach 600 Sekunden Alarm ausgelöst. Und nur dann. Verlassen alle Bewohner das Haus (und sind 10 Minuten vergangen) wird der Alarm nach 120 Sekunden ausgelöst.

Puh soviel Text, sorry dafür, aber ich hoffe jetzt ist es halbwegs nachzuvollziehen was ich mir vorstelle...?
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 12:46:07
Ich denke das ganze ist zu komplex und Fehleranfällig als das Du es in ein DOIF packen kannst. Sollte es in der Tat schon so gewesen sein das Du alle 3 Bedingungen erfüllt hattest und es dennoch nicht gewünscht war (also Fehlalarm).

Ich versuche es mal mit nur Text. Versuche zu verfolgen wie sowas als Ablauf aussehen kann.

Punkt 1.
Zitat
- Bewohner ist zwar zu Hause, aber WLAN-Verbindung ist kurzzeitig unterbrochen
- Smartphone des Bewohners kommt nicht innerhalb 120 Sekunden wieder online (weil es bei einem Abbruch der bestehenden WLAN-Verbindung manchmal 5-6 Minuten braucht.

Versuche das erfassen der Bewohner beim verlassen der Wohnung zu verzögern. Es macht wenig Sinn den Bewohner sofort auf abwesend zu makieren wenn er nur mal eben in den Garten geht oder Müll runter bringen.
Wenn ich Dich richtig verstanden habe erfasst Du das an und abwesend mit Hilfe von WLAN und ich denke mal über das present Modul. Also ist ein Watchdog auf das Setzen der Dummys für abwesend ein guter Einstieg.
Daraus folgt. Zum setzen der Anwesenheit wird ein notify verwendet da es sofort schaltet. Zum setzen der Abwesenheit ein watchdog. Somit hast Du die erste Verzögerung beim verlassen für die Bewohner.

Du brauchst oder hast also schon.


Wird das presencedevice auf present geschalten startet das notify und setzt den Bewohnerdummy auf home. Wird das  presencedevice auf absent geschalten startet der watchdog er wartet nun 5 Minuten ob sich der Status vom presencedevice nicht doch wieder zurück ändert, tut er das nicht wird der Dummy Bewohner auf absent gestellt.

Natürlich kann es nun sein das innerhalb dieser 5 Minuten ein Einbruch passiert, aber dieser Zufall ist doch eher zu vernachlässigen bilde ich mir ein.

Kommen wir nun zu Deiner Tür.
Zitat
- Tür wird geöffnet

Für Dein eigentliches Vorhaben, das Alarm ausgelöst wird würde ich einzig und alleine den Türkontakt Triggern und die Dummybewohner nur als Bedingung abfragen.


define DOIF_EG_Alarm_on DOIF ( [Status.EG] eq "on" and [?Anwesenheit.Dummy1] eq "off" and [?Anwesenheit.Dummy2] eq "off") (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


120 Sekunden verbleiben nun in denen sich der Status der Bewohner ändern kann. Allerdings fällt mir gerade auf das ich mir unsicher bin ob die Änderung der Bewohner in den 120 Sekunden erfasst wird wird auf sie nicht getriggert wird. Ich denke eher nicht.

Dann lieber doch

define DOIF_EG_Alarm_on DOIF ( [Status.EG] eq "on" and [Anwesenheit.Dummy1] eq "off" and [Anwesenheit.Dummy2] eq "off") (set Alarm.Status.EG on)
attr DOIF_EG_Alarm_on wait 120


Somit wird auf allen drei getriggert, aber durch die Verzögerung beim absent der Bewohner dürfte es zu keinem Frühzeitigen Alarm kommen.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 13:26:07
Ok, jetzt wird es kompliziert ;) .. Danke erstmal, dass Du noch mitliest. Also folgendes:


Zitat von: CoolTux am 26 Oktober 2015, 12:46:07
Ich denke das ganze ist zu komplex und Fehleranfällig als das Du es in ein DOIF packen kannst. Sollte es in der Tat schon so gewesen sein das Du alle 3 Bedingungen erfüllt hattest und es dennoch nicht gewünscht war (also Fehlalarm).
,

Ja, diese 3 Bedinungen kommen recht häufig vor. Als Beispiel, ich habe mein Smartphone in der Tasche und laufe in den Keller. Es findet ein Roaming von AP1 auf Ap2 statt. Kurz darauf laufe ich wieder nach oben (wieder Roaming) und öffne die Haustür um den Müll rauszubringen.
Aufgrund eines Bugs beim Roaming kann es vorkommen, dass das Smartphone nun mehrere Minuten nicht von FHEM erkannt wird. Da die Tür offen ist, gibt es nach 120 Sekunden Alarm.

Zitat
Punkt 1.
Versuche das erfassen der Bewohner beim verlassen der Wohnung zu verzögern. Es macht wenig Sinn den Bewohner sofort auf abwesend zu makieren wenn er nur mal eben in den Garten geht oder Müll runter bringen.

Hier gibt es noch eine Besonderheit, warum ich die sofortige Abwesenheitsmarkierung benötige. Dazu ist anzumerken, dass mein WLAN bis auf den Parkplatz reicht. Sprich, ich bin erst abwesend, wenn ich mich wirklich komplett von meinem Grundstück entferne.

Ich habe einen Alarm gesetzt wenn ich das Haus verlasse und die Dachfenster noch offen sind. Diesen Alarm brauche ich tatsächlich sofort beim Verlassen des Hauses und nicht erst 10 Minuten später.
Weil wenn ich mit dem Auto wegfahre...sind 10 Minuten viel Wegstrecke um nochmal umzudrehen und die Fenster zu schliessen.

Daher wäre eine Verzögerung hier unpraktisch. Beim Dachfenster-Alarm ist auch ein Fehlalarm nicht so tragisch, weil es sich dabei nur um eine einmalige, normale Pushover-Nachricht handelt und nicht wie bei der Alarmanlage um eine High-priority Pushover, die alle 2 Minuten bimmelt.

Während ich das hier schreibe kommt mir grade noch die Idee, einen zweiten Anwesenheits-/Abwesenheitscheck nur für die Alarmanlage zu setzen...wäre etwas unschön, aber würde wohl funktionieren.

Den Rest hast Du richtig vermutet, ich nutze das presence Modul in Verbindung mit LAN-Ping.

Also zusammengefasst..ich werde versuchen, deinen Vorschlag mit dem watchdog mit Hilfe eines zweiten Presence-Checks umzusetzen..damit würde mir die sofortige Dachfenster-Alarmierung erhalten bleiben.

Um nochmal kurz zum Ursprung zurückzukommen und nur falls Du Lust hast, das doch nochmal auseinanderzunehmen:

Was mich aber trotzdem noch brennend intressieren würde ist, warum die Berechnung welche ich vornehmen wollte nicht funktioniert.

Ich habe mal ein vereinfachtes Beispiel geschrieben:


define DOIF_EG_Alarm_TEST DOIF ([Status.EG] eq "on" and ({time}-{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0))} > 16000)) (set Alarm.Dummy on)


^^ Wenn Status.EG auf "on" springt und die Anzahl Sekunden des Zeitstempels vom "Anwesenheit.Dummy" im Vergleich zur aktuellen Uhrzeit größer 16000 ist, setze Alarm.Dummy auf "on".

Es funktioniert wie gesagt so nicht. Führe ich den Befehl manuell in der FHEM-Konsole aus, bekomme ich den korrekten Wert zurück: (z.b. 15869)


{time-time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0))}


Aber innerhalb des DOIF kommen wohl nur unplausible Werte zurück, leider habe ich noch keine Möglichkeit gefunden die Werte, welche im DOIF ausgelesen werden, zur Kontrolle darzustellen.
Das DOIF im obigen Beispiel löst bei >16000 nicht aus, bei < 16000 oder auch <1 jedoch schon -> was mich vermuten lässt, dass der ausgelesene Wert einfach "0" bzw nichts ist..also das Auslesen gar nicht klappt.

Im Logfile bekomme ich dann auch Meldungen wie


2015.10.26 12:53:06 1: PERL WARNING: Odd number of elements in anonymous hash at (eval 78119) line 1.


Die Klammern und die Schreibweise habe ich schon zigfach umgestellt, aber ohne Erfolg.

Wenn das funktionieren würde...dann wäre es für mich die momentan schönste Lösung.

Jedenfalls schonmal vielen Dank für deine bisherige Hilfe, jetzt habe ich zumindest eine Lösungsmöglichkeit die funktionieren wird.


Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: Damian am 26 Oktober 2015, 14:00:39
({time}-{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0))} > 16000))

Die Bedingung in DOIF ist bereits auf der Perl-Ebene, daher sind die geschweiften Klammern hier fehl am Platz. Das was du vorhast ist aber bereits in DOIF implementiert, bei dir wäre das dann

([Anwesenheit.Dummy:state:sec] >16000)

Gruß

Damian
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: CoolTux am 26 Oktober 2015, 14:04:53
Wollte ich auch gerade so schreiben, also das er bereits in der Perlebene ist und ein paar geschweifte zu viel sind. Danke Dir Damian für den Tip das dies bereits in DOIF implementiert ist.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: Wuppi68 am 26 Oktober 2015, 14:11:31
zum LAN Ping :-)

versuche die MAC Adresse von den Telefonen auf dem Router per SNMP zu überprüfen, da kannst Du dann Deine 600 Sekunden ARP Timeout setzen.

Bei mir habe ich einen CISCO Switch für die Abfragen genommen und ich hatte noch keine FALSE Erkennungen gehabt.
Titel: Antw:DOIF Zeitberechnung Syntax
Beitrag von: errazzor am 26 Oktober 2015, 14:44:27
Zitat von: Damian am 26 Oktober 2015, 14:00:39
({time}-{time_str2num(ReadingsTimestamp("Anwesenheit.Dummy","state",0))} > 16000))

Die Bedingung in DOIF ist bereits auf der Perl-Ebene, daher sind die geschweiften Klammern hier fehl am Platz. Das was du vorhast ist aber bereits in DOIF implementiert, bei dir wäre das dann

([Anwesenheit.Dummy:state:sec] >16000)

Gruß

Damian

Das wars - es funktioniert! DANKE!

Oh Mann, ich habe das in der Commandref beim suchen zwar gesehen, habe es aber nicht in Verbindung mit meinem Vorhaben gebracht weil mir nicht klar war, dass sich der state auf den Unterschied zur aktuellen Zeit bezieht...jetzt fällt es mir wie Schuppen von den Augen.

Danke nochmals an alle !