Presence auf Raum Ebene per Algorithmus "Wasp in a Box"

Begonnen von patlabor, 08 März 2019, 10:34:09

Vorheriges Thema - Nächstes Thema

patlabor

Hallo zusammen,

ich habe es mittlerweile geschafft ein Zimmer (die Toilette) mit Bewegungsmelder, Türkontakten und Milight Beleuchtung auszustatten.
Meine Idee war eine Präsenz Erkennung nach der "Wasp in a Box" Idee umzusetzen.

Gerade auf der Toilette ist es ja ziemlich oft anzutreffen das ein Bewegungsmelder für das Licht vorhanden ist, der fest auf z.B. 5 Minuten eingestellt ist.
Ist dann mal eine "längere Sitzung" notwendig, sitzt man plötzlich im dunkeln und man fängt an im Raum rumzuwinken bis wieder das Licht angeht.
Stellt man das Timeout auf eine längere Zeit, bleibt das Licht bei jeder "kleinen Sache" die einen in die Toilette treibt z.B. 15 min an.

Eigentlich ist die Idee von Haus Automatisierung ja genau das zu vermeiden.

Habe hierzu schon vor geraumer Zeit ein scheinbar geniale Idee im Netz entdeckt:

The Wasp In A Box Algorithm
Assume there is no wasp in the box.
Have you heard the wasp buzzing in the box?
YES = There is a wasp in the box until you are told otherwise.
Have you opened the box since you last heard buzzing?
YES = There is no wasp in the box.
NO = There is still a wasp in the box if you heard one earlier.
Got to step 2.
https://smartisant.com/research/presence/index.php

Leider scheitere ich hierbei aber gerade bei der praktischen Umsetzung.

Da sich meine Perl Kenntnisse doch sehr im Rahmen halten, versuche ich das ganze z. Zt. per DOIF zu lösen.

Momentan habe ich das so am laufen:

define di_presence_toilette DOIF ([ms_toilette] eq "true" and [tk_toilette] eq "true") (set presence_toilette on) DOELSEIF ([tk_toilette] eq "false") (set presence_toilette off)
attr di_presence_toilette wait 0:20


Das licht schalte ich dann so:
define di_li_toilette DOIF ([presence_toilette] eq "on" or [tk_toilette] eq "false") (set to_licht on) DOELSE (set to_licht off)
attr di_li_toilette wait 0:5


Den Bewegungsmelder habe ich so positioniert, das er die Tür nicht wahrnimmt und nur auslöst wenn tatsächlich jemand im Raum ist. Dann meldet er für eine Sekunde presence:true.

Bei dieser Konstruktion habe ich aber leider teilweise Probleme mit den Timings.
Manchmal kommt es vor, das jemand in den Raum reinhuscht etwas nimmt und sofort wieder verschwindet, dann bleibt Presence auf on bis das nächste mal jemand die Tür öffnet.
Dann kommt es auch immer mal wieder vor das jemand in den Raum "rennt" sofort platz nimmt und beim hinsetzen die Tür zuzieht. Dies hat leider zur Folge das man ein paar Sekunden später im dunkeln sitzt und man wieder anfangen muß das "Licht anzuwinken"
Ich habe versuchsweise einmal die Zeit die der Bewegungsmelder Presence:true von einer Sekunde zu verlängern, das hat aber lediglich zur Folge das die Zeit zwischen letzte Bewegung erkannt und Tür ist zu, zu kurz ist und das Licht in der Toilette einfach an bleibt nachdem der Raum leer ist.

Leider bin ich hier mit meinen gegen null gehenden Programmierkenntnissen auch schon am ende und komme seit gut einer Woche nicht weiter.
Ich will auch nicht das mir hier jemand eine fertige Lösung präsentiert, aber vielleicht gibt es ja jemand der diesen Algorithmus als Modul erstellen kann und das Thema hier als Denkanstoß nutzt. 






the ratman

also ganz dumm und mit auch keinen programmierkenntnissen und der annahme, dass sich selten mehr als 1 person im klo befindet, würd ich das mit nem doif lösen

so nach dem motto:
1) wenn innerhalb einer vergangenn zeit (wenige sekunden) die klotür geöffnet wurde und sich der bewegungsmelder gemeldet hat - licht an
2) wenn sich die tür nochmals öffnet - licht aus
3) eventuell noch: wenn klotüre länger als x zeit offen, dann licht aus und durchsage "es stinkt aus dem klo" *g*

ich trau mich aber (wie immer) wetten, dass es hier x leute gibt, denen wesentlich sinnvollere ideen kommen.
→do↑p!dnʇs↓shit←

willib

Ein Algorithmus hat es schwer bei solchen Dingen. Wie bildest du den fliegenden Wechsel zweier Personen ab?

Ich empfehle dir einen Riegelschließkontakt zu verwenden. Wenn die Tür abgeschlossen ist noch jemand im Raum.
FHEM in Debian 10 LXC unter Proxmox auf NUC, Homematic, Hue, Intertechno, Jeelink, RFXTRX, Harmony Hub, VU+ Uno 4K, Sonos, AMAD

peterk_de

#3
Ohne zu wissen, dass dieser Algorithmus einen treffenden Namen hat, habe ich das in allen Räumen schon länger so umgesetzt. Und zwar mit DOIFs, die jeweils einen "Raumdummy" mit dem Namen raum.anwesenheit füttern, mit dem ich dann wiederum verschiedenes schalte (z.B. Licht, aber auch den Bildschirm vom Wandtablet, einen nervenden Luftentfeuchter, der nur laufen sollen wenn man nicht im Raum ist etc.)

Also eigentlich genau deine Lösung, aber schon über ca. 1 Jahr "abgehangen", etwas aufgebohrt und gut erweiterbar.

Mal ein Beispiel für einen"einfachen" Raum - also einen mit einer Tür:

(0) (set kueche.anwesenheit Ja) (set kueche.anwesenheit Unbekannt) (set kueche.anwesenheit Unwahrscheinlich) (set kueche.anwesenheit Nein)

DOELSEIF  ( ( [kueche.wandtaster.praesenz:"motion.*on"]
              or [kueche.fenster:"^(offen|geschlossen)$"]
              or [kueche.fenster2:"^(offen|geschlossen)$"]             
            ) and ([?kueche.tuer] eq "geschlossen")
              and ([kueche.tuer:state:sec] > 2)
              and ([wohnung.modus] ne "Abwesenheit")
          )
          (set kueche.anwesenheit Ja)

DOELSEIF ([kueche.wandtaster.praesenz:"motion.*on"]
          or [kueche.tuer:"offen"]
          or [kueche.tuer:"geschlossen"]
          or [kueche.fenster:"^(offen|geschlossen)$"]
          or [kueche.fenster2:"^(offen|geschlossen)$"] 
          )
         (set $SELF cmd_1)


attr di_kueche.anwesenheit do resetwait
attr di_kueche.anwesenheit wait 0,60,300,900:0:0



Das ist vielleicht ein bisschen erklärungsbedürftig:

- cmd_1 wird ausgeführt, wenn irgendwas in dem Raum passiert, während die Tür zu ist (Bewegungsmelder, Fenster wird geöffnet, ...) und - wegen Funkdelay - auch schon mindestens 2 sec auf "zu" steht. Dann wird der Anwesenheitsdummy auf "Ja" gesetzt und bleibt so auch beliebig lange stehen, auch wenn man sich z.B. eine Stunde nicht bewegt.

- cmd_2 wird ausgeführt, wenn im Raum etwas passiert während die Tür offen ist, oder auch wenn die Tür selbst geöffnet oder geschlossen wird. Dann wird cmd_0 aufgerufen und es beginnt eine "klassische" Zeitschaltung, die immer sofort erstmal auf "Anwesenheit Ja" springt und dann "allmählich" über unbekannt und unwahrscheinlich auf "Nein" wechselt. Hierfür wird als Hilfsbefehl ...

- ... cmd_0 (die erste Zeike) benutzt. Das hat als Bedingung "0", wird also nie über Sensoren oder Ereignisse etc. wahr. Das heißt, man kann es nur über set mydoif cmd_0 ausführen. Das brauche ich, um abgestuft den Abwesenheitsdummy zu setzen (Anwesenheit Ja -> Warten -> Anwesenheit  Unbekannt -> Warten -> Anwesenheit Nein) und über das Attribut do resetwaitimmer wieder zurück zu "Ja" zu springen, wenn bei offener Tür etwas passiert.

- Feintuning 1 - Timing: Über das Attribut wait können die Wartezeiten eingestellt werden, falls die Tür dauerhaft offen steht oder gerade geöffnet/geschlossen wurde.. Hier ist etwas Feintuning nötig: Der zweite Wert (hier 60) ist kritisch. Innerhalb dieser Zeit muss nach dem Öffnen UND nach dem Schließen der Tür von innen jeweils irgendeine Aktivität im Raum detektiert werden, damit die Anwesenheit unterbrechungsfrei bei "Ja" steht. Sinnvoll ist auch, mit dieser Zeile hier zu spielen: ([kueche.tuer:state:sec] > 2) - Ein großes Problem war nämlich, wenn man beim Rausgehen den BWM auslöst und dessen "Bewegung erkannt" erst nach dem Türschließen bei FHEM ankommt. Dann steht der Raum dauerhaft auf "Anwesend" obwohl niemand drin ist.

- Feintuning 2 - Nicht nur bei Anwesenheit "Ja" und "Nein" etwas auslösen: Ich erzeuge hier ja nicht nur binär ein Anwesenheitsreading, sondern auch Stufen dazwischen. Und zwar daeshalb: Je nach Raum geht das Licht z.B. mal schon bei "Unwahrscheinliche Anwesenheit" aus, manchmal aber erst bei "Nein - definitiv keine Anwesenheit". Die Wandtablets aber z.B. immer schon nach einer Minute, also bei "Anwesenheit unbekannt", weil man sich eh bewegen muss und den BWM auslöst, um zu ihnen zu gelangen.

- Feintuning 3 - Mehr Sensoren + anderer Input: Schön an der Lösung ist auch, dass man sehr einfach neue Ereignisse als "Aktivitätsbeweis" für den Raum hinzufügen kann (z.B. weiterer BWM, Lichtschalter gedrückt, Kühlschranktür wurde geöffnet, Duschkabinentür wurde geschlossen ...). Dadurch klappt das sehr genau und hier mittlerweile mit 100% WAF ;) Bei dir würde sich dafür ein Kontakt an der Klobrille anbieten. Manchmal - gerade in schnellen Situationen - helfen echt nur mehr Sensoren.

Bei uns war das auch im Bad ein Problem, da hat deshalb die Duschtür einen Kontakt bekommen: Wenn jemand während jemand anderes geduscht hat kurz ins Bad kam, ging sonst irgendwann das Licht aus, weil man unter der Dusche den BWM nicht triggert. Jetzt heißt "Duschkabine ist geschlossen" -> bleibe bei cmd_1, also Anwesenheit = dauerhaft "Ja". Ein separater BWM für die Dusche hätte natürlich genauso funktioniert.

Das kann man zudem dann auch Tageszeitabhängig machen oder - so wie ich - auch vom Geofencing-Status der Bewohner abhängen lassen: In unserer Abwesenheit schaltet z.B. die Katze das Licht max. 1 Minute ein, wenn sie mit dem BWM kuschelt ;-) In meinem Beispiel erledigt das die Bedingung and ([wohnung.modus] ne "Abwesenheit"), die ein "Dauer-Anwesend" in einem Raum nur zulässt, wenn die Wohnung (automatisch per Geofencing oder auch manuell per Taster) in den Anwesenheitsmodus versetzt wurde.

So, das war ein einfacher Raum. Bei Interesse folgt auch gern noch ein etwas komplexerer (= Durchgangsraum ohne Türen an jedem möglichen Zugang), bei dem es mit einer handvoll BWMS auch prima klappt ;-)
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...

patlabor

Hallo,

das ist ziemlich genau das was ich versucht habe zu erreichen.
Ich habe mal versucht das ganze bei mir umzusetzen, aber irgendwie komme ich wieder nicht weiter.

Bei mir sieht es jetzt so aus:

DEF
(0) (set presence_toilette on) (set presence_toilette unknown) (set presence_toilette off)
DOELSEIF ([ms_toilette] eq "true" and [?tk_toilette] eq "true" and [tk_toilette:state:sec] > 5) (set presence_toilette on)
DOELSEIF ([ms_toilette] eq "true" or [tk_toilette] eq "false" or [tk_toilette] eq "true") (set $SELF cmd_1)


Das device:state:sec war mir völlig unbekannt, ich vermute aber das das eine Zeitspanne definiert, wie lange die letzte Statusänderung her ist.
Aber genau hier liegt mein Problem. Wenn ich beim Verlassen das Raumes die Tür schließe, springt das doif sofort nochmal auf CMD_2.
Der Bewegungsmelder zeigt noch "Bewegung" an und die Tür ist geschlossen, soweit verstehe ich das, daher habe ich das so verstanden, das die Tür schon (in meinem Fall) 5 Sek geschlossen sein muß damit die Bedingung wahr wird. Das ist aber leider nicht so, sondern in dem Moment wo der Status des Türkontaktes von false auf true springt wechselt auch das DOIF.
Auch habe ich das Fragezeichen so verstanden, das eine Änderung an diesem Gerät nur abgefragt wird und nicht auslöst. Scheinbar ist das aber nicht der Fall.

Ausserdem habe ich in CMD_3 auch noch ein kleines Problem. Gibt es bei doif eine Möglichkeit nur zu triggern wenn die Bedingugn wahr ist?
Hier ein Bespielt, weil der vorherige Satz nicht so zu verstehen ist:
Mein Bewegungsmelder hat folgendes Verhalten: Bemerkt er eine Bewegung sendet er einmal "false" und sofort danach "true" dann 90 Sek lang nichts und dann nochmal ein "false". Nach einem solchen Durchgang ist etwa 30 Sek "tot".
Das bewirkt leider, das wenn ich im Raum bin und mich nicht bewege der Bewegungsmelder irgendwann "false" sendet, und darauf springt dann wieder CMD_3 an, Hier ist die erste Bedingung zwar nicht war aber die Tür ist zu und somit wird CMD_3 ausgelöst.
Kann ich DOIF jetzt irgendwie beibringen "reagiere nur wenn Bewegungsmelder=wahr und schau dir den rest auch nur an wenn Bewegungsmelder=wahr?

peterk_de

#5
Schau dir mal die Syntax oben an, mit der ich meine Bewegungsmelder abfrage. Du machst [xy] eq "irgendwas". Ich mache [xy:"irgendwas"] - das heißt ich triggere nur auf die Flanke (also exakt den Moment bzw. das Event, wo die Bewegung erkannt wird) - du aber auf den gesamten Zustand mit Nachlaufzeit des BWMs von 90s (also auf den Wert des Readings). Das geht schief. So einen "Nachlauf" haben meine BWMS übrigens auch, daher mach ich das so.
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...

patlabor

Das verstehe ich dann wieder nicht. Vielleicht bin ich auch einfach nur zu doof.
Aber wenn ich doch nur auf die Flanke triggere kann das doch eigentlich gar nicht funktionieren.
Wenn ich das richtig verstehe ist der Ablauf dann dieser:

1.Ich mache die Tür auf: cmd_3
2.Ich gehe in den Raum, der Bewegungsmelder triggert, die Tür ist aber noch auf: cmd_3
3. Ich mache die Tür zu, der Bewegungsmelder ist immer noch auf "true", hat aber noch nicht neu getriggert: cmd_3
4. Ich sitzte und bewege mich nicht mehr, also läuft irgendwann cmd_1 aus und Präsenz geht auf "off"

Zumindest ist das so wie ich den Ablauf verstehe und was sich auch so in fhem zeigt. cmd_2 triggert eigentlich nie und ich sitze irgendwann im dunkeln.
Das einzige wie ich das gelöst bekommen würde wenn ich das wait attribut für den letzten teil von cmd_1 viel länger machen würde. aber selbst dann triggert der Bewegungsmelder frühestens nochmal nach ca. 2 minuten. Und so lange bin ich entweder nicht im Raum, oder es dauert sowieso länger und ich bewege mich 10 sekunden nachdem ich den Raum betreten habe so gut wie nicht mehr.
Ich kann die Meldezeit des Bewegungsmelders zwar frei zwischen 1 Sek bis unendlich frei einstellen, aber öfter als ca. alle 60 sek meldet er keine Bewegung. 

peterk_de

#7
Hallo pat,

das hast du alles genau richtig erkannt - du bist nicht zu doof. ;-)

Du kannst aber, wenn du es zuverlässig haben willst, tatsächlich nur auf die ,,Bewegung erkannt"-Flanke triggern. Der Zustand ,, Bewegung erkannt" und die Flanke für ,,keine Bewegung mehr" sind in unserem Szenario hier völlig irrelevant.

Das hat einen ganz pragmatischen Grund: In den - in deinem Fall mindestens 60 - Sekunden, in denen der BWM ,,aktiviert" bleibt, weißt du ganz einfach nichts über seinen Status. Kann sein, dass er da noch Bewegungen wahrnimmt - kann aber auch sein, dass nicht. Dieser Zustand sagt einfach nichts aus - es ist wie mit Schrödingers Katze.

Dadurch ergibt sich natürlich nun das von dir gut erkannte Problem. Und das könnte in deinem Fall ein großes sein, dass sich mit deinem BWM nicht lösen lässt: Wenn der sich nur erbarmt, alle Minute eine verlässliche Messung zu FHEM (= Bewegung-erkannt-Flanke) zu senden, ist das für manche Räume einfach zu wenig. Ich habe bei mir die HM-Wandtaster mit BWM - die können als schnellstes 15 Sekunden, das reicht um die erste Wait-Zeit (von Ja auf Unbekannt) auf 60s Sekunden setzen zu können. Beispiel:

Sekunde 0 -  Tür auf, Raum betreteten - Anwesenheit bis Sekunde 60
Sekunde 3 - BWM feuert - Anwesenheit bis Sekunde 63 und BWM ist bis Sekunde 18 als ,,tot" anzusehen
Sekunde 6 - Tür wird geschlossen - Anwesenheit bis Sekunde 66

Jetzt muss zwischen Sekunde 18 (bis dahin ist der BWM ,,tot") und Sekunde 66 eine erneute Bewegung registriert werden. In zwei räumen musste ich das erste Wait- Intervall auf 90 Sekunden erhöhen, aber so vom prinzip her klappt das dann so schnell.

Aber Meldeintervall von einer Minute ist zu lang. In der Zeit sitzt du ja locker aufm Klo / Sessel / Wo auch immer und bewegst dich nicht mehr. Du brauchst aber definitiv eine An-Flanke nachdem die Tür zugemacht wurde. Alles andere ist raten und klappt nicht.

Edit: Aber wie im vorherigen Post geschrieben:  Licht aus mache ich  nicht schon bei Unbekannt, sondern erst bei Unwahrscheinlich, also erst nach 300 Sekunden. Der WAF für 4 Minuten Licht während man gar nicht im Raum ist (und es also auch gar nicht sieht), ist höher als  Licht das nach 60 Sekunden einmal alle paar Tage fälschlicherweise wieder aus geht, weil man sich zu schnell hingesetzt hat ;-)
FHEM auf Ubuntu-VM / 2xNUC Proxmox Cluster
UI: HomeKit, TabletUI, Grafana
IOdevs: 2xHueBridge, RaspiMatic-CCU, CUL868, 2xHarmonyHub, 6xRaspi-Roomnode mit CO2, VOC und lepresenced
Devices: 107xHomematic(IP), 96xPhilips Hue, 17xTECHEM, 12xBTLE, 8xSONOS, 2xHomeConnect, 1xShelly 3em, 1xNanoleaf ...

binford6000

#8
Hallo patlabor,
schau mal hier: https://forum.fhem.de/index.php/topic,98594.0/topicseen.html
Ein neues Projekt von KernSani namens honezone. Ist so ziemlich genau das was du suchst...  ;)

Ein Raum sieht Beispielsweise dann so aus:
defmod wz_zone homezone
attr wz_zone hz_adjacent fl_zone
attr wz_zone hz_closedEvent PhilipsTV.PRE:present
attr wz_zone hz_decay 300
attr wz_zone hz_occupancyEvent wz_bwm:motion
attr wz_zone hz_openEvent PhilipsTV.PRE:absent

setstate wz_zone 0
setstate wz_zone 2019-03-16 10:16:06 condition open
setstate wz_zone 2019-03-16 10:01:21 occupied 0
setstate wz_zone 2019-03-16 10:01:21 state 0


hz_adjacent ist dabei eine angrenzende Zone, welche die Anwesenheit vererbt bekommen kann.
VG Sebastian

KernSani

Das ist ja interessant. Hab mir das jetzt nich nicht alles im Detail angesehen aber wir scheinen hier ein sehr ähnliches Konzept zu verfolgen. Ich schau mal ob ich da noch etwas in homezone übernehmen kann...


Kurz, weil mobil
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

patlabor

danke für die ausführliche hilfe, habe das genze jetzt entlich hinbekomme.
momentan noch mit dem doif von peterk_de.
Leider gibt es hier ein systemisches problem, das den WAF doch sehr nach unten schraubt: die Schaltzeiten sind deutlich über einer Minute. Jetzt darf ich meiner besseren Hälfte ständig erklären warum das Licht in der Toilette noch an ist, obwohl man doch schon raus ist. Hatte sie im Flur soweit das sie es akzeptiert hat, das das Licht noch 20 Sek brennt nachdem man durch ist und man es doch eigentlich nicht mehr braucht. Deshalb hat sie, wenn sie mal länger Licht im Flur gebraucht hat einfach die Toilettentür aufgemacht und dort das Licht von Hand angeschaltet.
Jetzt komme ich und will das Toilettenlicht auch noch automatisieren.  :-\

Nichts desto trotz werde ich mir auch mal das Projekt von KernSani anschauen. Das sieht sehr interresant aus. Ich bin ja an allem interresiert, mit dem ich selbst "gebastelte" Sachen in ein Modul bekomme und beliebig oft ohne große Probleme und Anpassungen mehrmals verwenden kann