Fensterkontakt-Event: Zählung der offenen Fenster misslingt

Begonnen von stobor, 15 September 2024, 13:42:18

Vorheriges Thema - Nächstes Thema

stobor

Hallo,

ich würde mich freuen, wenn mir jemand einen Tipp geben kann:

Ich Zeige mit über die TabletUI den Status der Fenster an (Homematic Fensterkontakte) und zähle über eine Perl-Funktion die Anzahl der offenen Fenster. Diese Funktion wir aufgerufen, sobald ein Fensterkontakt-Event eintrifft:

fhem.cfg:

define HM_SC_OG_Schlafzimmer CUL_HM 4C0CB5
setuuid HM_SC_OG_Schlafzimmer 5d4f2725-f33f-2cfb-071a-352cbeb7b23acacd
attr HM_SC_OG_Schlafzimmer .mId 00C7
attr HM_SC_OG_Schlafzimmer IODev CUL_1
attr HM_SC_OG_Schlafzimmer actCycle 000:50
attr HM_SC_OG_Schlafzimmer actStatus alive
attr HM_SC_OG_Schlafzimmer alias Schlafzimmer
attr HM_SC_OG_Schlafzimmer autoReadReg 4_reqStatus
attr HM_SC_OG_Schlafzimmer devStateIcon open:fts_window_1wbb_open@red closed:fts_window_1w@green
attr HM_SC_OG_Schlafzimmer expert defReg,rawReg
attr HM_SC_OG_Schlafzimmer firmware 1.0
attr HM_SC_OG_Schlafzimmer group Fensterkontakt
attr HM_SC_OG_Schlafzimmer icon fts_window_1w
attr HM_SC_OG_Schlafzimmer model HM-SEC-SCO
attr HM_SC_OG_Schlafzimmer peerIDs 00000000,4B262F3F,4CEE9803
attr HM_SC_OG_Schlafzimmer room Fensterkontakte
attr HM_SC_OG_Schlafzimmer serialNr NEQ0634521
attr HM_SC_OG_Schlafzimmer subType threeStateSensor
attr HM_SC_OG_Schlafzimmer userReadings windowState { ReadingsVal("HM_SC_OG_Schlafzimmer","state",0) }

...

define HOME.OpenWindows dummy
setuuid HOME.OpenWindows 5ea852a2-f33f-2cfb-8fb1-0a3e2657f6ed1814
attr HOME.OpenWindows fm_type state
attr HOME.OpenWindows room Fensterkontakte

...

define HM_SC_EG_opened notify HM_SC_EG_.*:open.* {\
CommandSet(undef,'HOME.OpenWindows ' . numberOfOpenWindows());;\
}
...



99_myUtils:
sub numberOfOpenWindows() {
    my $openWindows = 0;
    Log 1, "Anzahl offener Fenster -------------------------------";
    foreach my $windowName (devspec2array("group=Fensterkontakt")) {
        my $device2test = ReadingsVal("$windowName", "state", "closed???");
        my $device2testORIGINAL = ReadingsVal("$windowName", "windowState", "closed?");
         Log 1, "$windowName: $device2test >>$device2testORIGINAL<<";
        if ($device2test ne "closed") {
            $openWindows++;
        }
    }
    my $FHEMvalue = ReadingsVal("HOME.OpenWindows", "state", "closed???");
    Log 1, "Anzahl offener Fenster: $FHEMvalue -  -------------------------------";
    Log 1, "Anzahl offener Fenster: $openWindows - ENDE -------------------------------";
    return $openWindows;
}

In der TabletUI wird mir der Fenster-Status sofort aktualisiert angezeigt.
Der Zähler wird allerdings oft nicht zeitgleich aktualisiert.

Im Log steht dann:

2024.09.15 13:22:42 1: Anzahl offener Fenster -------------------------------
2024.09.15 13:22:42 1: HM_SC_EG_GaesteWC: open >>open<<
2024.09.15 13:22:42 1: HM_SC_EG_HWRFenster: open >>open<<
2024.09.15 13:22:42 1: HM_SC_EG_HWRTuer: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_Haustuer: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_KuecheOst: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_KuecheSued: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_WohnzimmerSued: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_WohnzimmerTerrassentuer: open >>open<<
2024.09.15 13:22:42 1: HM_SC_EG_WohnzimmerWestNord: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_EG_WohnzimmerWestSued: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_OG_Arbeitszimmer: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_OG_Badezimmer: closed >>closed<<
2024.09.15 13:22:42 1: HM_SC_OG_Kinderzimmer: open >>open<<
2024.09.15 13:22:42 1: HM_SC_OG_Schlafzimmer: closed >>closed<<
2024.09.15 13:22:42 1: Anzahl offener Fenster: 4 -  -------------------------------
2024.09.15 13:22:42 1: Anzahl offener Fenster: 4 - ENDE -------------------------------

obwohl bspw. das Arbeitszimmer gerade geöffnet wurde - und somit das Zähl-Event ausgelöst haben sollte.

Hat jemand eine Idee, was ich gedanklich falsch mache?

Wie kann es sein, dass das Device einen Trigger für eine Status-Änderung generiert, aber der Status dann noch nicht abgefragt werden kann?

Beim Schließen der Fenster scheint es diese sProblem übrigens nicht zu geben:
define HM_SC_closed notify HM_SC_.*:closed.* {\
my $devName = AttrVal($NAME,"name",$NAME);;\
CommandSet(undef,'HOME.OpenWindows ' . numberOfOpenWindows("$devName"));;\
}
Intel NUC (Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-113-generic x86_64))  mit CUL V3.2 (Firmware 1.57 CUL868) für FS20 und CUL V3.4 (Firmware 1.57 CUL868) für HM + Arduino Mega
FHEM Revision: 29003
FS20-Schalter und Dimmer
HM Fensterkontakte, Heizungsthermostate, Temperatursensoren

tobi01001

Zitat von: stobor am 15 September 2024, 13:42:18obwohl bspw. das Arbeitszimmer gerade geöffnet wurde - und somit das Zähl-Event ausgelöst haben sollte.

Hat jemand eine Idee, was ich gedanklich falsch mache?

Machst du das "nur" am Logfile fest?
Deine Log-Einträge generierst du in der sub numberOfOpenWindows. Das Reading (bzw state) des dummy HOME.OpenWindows wird aber erst über den Rückgabewert gesetzt (aktualisiert). In der sub fragst du das allerdings ab. Sobald sich die Anzahl offener Fenster ändert, würden die Log-Einsträge über die Anzahl auseinanderlaufen.

Ansonsten: Sofern keine "event-on-" bei den Fensterkontakten gesetzt sind, wird jedes "open" oder "closed" Event das notify auslösen. Nachdem dein Userreading keinen Trigger definiert hat, kann das bei jeder Aktualisierung des entsprechenden Device passieren.

Ein notify, was auf state oder auf das userReading windowState reagiert sollte genügen - letztendlich tun sie ja exakt das selbe?

Achso, das Notify sagt dir doch auch welches Event das notify ausgelöst hat?

Eventuell hilft dir das weiter?

LG,
Tobias
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Prof. Dr. Peter Henning

#2
Ich stelle die Sinnhaftigkeit des Ansatzes insgesamt in Frage.

Was nutzt es, wenn man die Mitteilung erhält, dass zwei (von sagen wir 10) Fenstern geöffnet sind? Dann muss man losziehen und alle überprüfen.

Es könnte stattdessen eine Routine geben (die man jederzeit, gerne auch periodisch aufrufen kann), welche alle Fenster überprüft und mitteilt, _welche_ Fenster geöffnet sind.

Bei mir sieht das in der permanenten Wandanzeige (Tablet) so aus, wie im Bild dargestellt (derzeit nur die Tür vom Wohnzimmer zur Terrasse offen). Und wenn ich das Sprachinterface aufrufe mit "Ist irgendwo ein Fenster offen?", liefert das vor Ausführung gegenwärtig zurück

{speak('Tab2.EG',' Kein Fenster offen. Kein Fenster gekippt.')}
Und natürlich die genaue Lage der offenen Fenster, wenn dies nicht der Fall ist.
Geht natürlich auch aus der Ferne, per Telegram.

LG

pah

juemuc

Hallo zusammen,

hierfür gibt es auch eine "DOIF-Möhlichkeit"

defmod di_uiTable_windows DOIF ## Visualisierung offener Türen und Fenster
attr di_uiTable_windows addStateEvent 1
attr di_uiTable_windows alias Fenster- und Türstatus
attr di_uiTable_windows devStateStyle style="text-align:right"
attr di_uiTable_windows event-on-change-reading .*
attr di_uiTable_windows event_Readings windows:[@as(<br>)"^HMIP|^HM_Sec_RHS|OEQ0424862$:^state":state:"open|tilted","alles zu"],\
doors:[@as(<br>)"0007DF29950D53$:^state|OEQ0223456$:^state":state:"open|tilted","alles zu"],\
count:[#"HM|HmIP_SRH":state:"open|tilted","0"]
attr di_uiTable_windows group Fenster-/Türkontakte
attr di_uiTable_windows room Statuszentrale
attr di_uiTable_windows uiTable {\
package ui_Table;;\
$TC{1}="align='center'";;\
$TC{2}="align='left'";;\
}\
"Fenster"|icon([$SELF:windows],"fts_window_roof_open_2\@red","fts_window_roof\@black",".*","alles zu")|[$SELF:windows]\
"Türen"|icon([$SELF:doors],"fts_door_open\@red","fts_door\@black",".*","alles zu")|[$SELF:doors]\
"Anzahl"|[$SELF:count]

Du darfst diesen Dateianhang nicht ansehen.

Hiermit werden mir alle offenen Türen und Fenster angezeigt und zusätzlich die Anzahl. Die Anzahl > 0 nutze ich dann für weitere Aktionen.


Viele Grüße
Jürgen
3x Sonos Play 1, 1x Sonos Arc + Sub, 1 Sonos-One, 1x Sonos Playbar
FB6690 + FB7490 mit 4x Dect 200 und 3 Dect-ULE-Thermostate,  raspberry3B+, HM Funkmodul HM-MOD-RPI-PCB, HM Klingelsensor HM-Sen-DB-PCB, HM (IP) Fensterkontakte und  Amazon Echo Dot,  piVCCU, pi OS (bookworm).

betateilchen

Zitat von: Prof. Dr. Peter Henning am 16 September 2024, 15:51:10Es könnte stattdessen eine Routine geben (die man jederzeit, gerne auch periodisch aufrufen kann), welche alle Fenster überprüft und mitteilt, _welche_ Fenster geöffnet sind.

Man braucht weder eine extra Routine noch diese Routine periodisch aufrufen.

Wenn man alle Fensterkontakte in eine structure packt, hat man zumindest schonmal die Information, ob "alle" Fenster geschlossen (structure = closed) oder offen (structure = open) sind.

Und über das NOTIFYDEV der structure hat man auch Zugriff auf jeden einzelnen Fensterkontakt und kann diesen direkt abfragen, wenn man die Einzelinformation braucht.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

eisman

1x FHEM Debian, Homematic,ZigBee,FS20 / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian, Homematic,ZigBee         / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian,MQTT                               / 1X Raspberry, i2c,onewire,gpio
1x auf Windows 2012 Hyper-V-S

Prof. Dr. Peter Henning

Zitat von: betateilchen am 17 September 2024, 09:52:07Fensterkontakte in eine structure
Hm, da muss ich widersprechen.

Erst einmal ist das update-Verhalten von structure nach meiner Erfahrung ziemlich kryptisch. Ich fluche ziemlich oft darüber, dass wieder einmal die structure meiner Rollläden im Wohnzimmer nicht mitbekommen hat, dass alle Rollläden geöffnet sind (clientstate_behavior=absolute). Auch jetzt gerade wieder: Alle vier Rollläden haben pct=100, dieses Reading wird korrekt zur structure gemapt - aber die behauptet "undefined" zu sein.

Zweitens ist hier dasselbe Problem gegeben wie beim TE: ES geht ja nicht nur drum, ob ein Fenster geöffnet ist. Sondern _welches_. Und ob diese Abfrage (und Anzeige) mit einer Iteration über das NOTIFYDEV macht, oder irgendwie anders, ist egal.

LG

pah