[gelöst] global:INITIALIZED zu früh seit Update heute?

Begonnen von DeeSPe, 21 April 2017, 11:22:48

Vorheriges Thema - Nächstes Thema

rudolfkoenig


DeeSPe

{ DoTrigger( "global", "INITIALIZED XXXXXXX", 1 ) }

Probiert's mal bei Euch aus!
Ich sehe schon evtl. aufkommende Schwierigkeiten im Event Monitor / Log.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Loredo

#47
Zitat von: betateilchen am 22 April 2017, 13:29:02
Allerdings verstehe ich nicht, warum da ein "global" am Anfang stehen soll, denn ein von RESIDENTS erzeugter event hat doch überhaupt nix mit dem device "global" zu tun.

Weil man es sonst nicht von einem STATE Event unterscheiden kann.

Zitat von: justme1968 am 22 April 2017, 13:53:37
<device>:INITIALIZEDist nicht gut da man dann den device namen kennen muss oder jedes mal den type nachschauen muss.

Genau. Man kann da nicht sicher unterscheiden, ob davor jetzt ein Devicename oder ein Modulname steht.

Zitat von: DeeSPe am 22 April 2017, 13:59:18
Es können ungewünschte Nebenwirkungen auftreten wenn in bestehenden Modulen nur auf /^INITIALIZED/ statt auf /^INITIALIZED$/ geprüft wird.

Da bin ich anderer Meinung. Das globale Event ist als ^INITIALIZED$ deklariert. Wer nach ^INITIALIZED filtert, hat unsauber gearbeitet.

Zitat von: rudolfkoenig am 22 April 2017, 13:49:13
Neuer Vorschlag:

global:INITIALIZED
global:INITIALIZED <TYPE>
<device>:INITIALIZED



Die dann wohl beste Lösung.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

#48
Zitat von: rudolfkoenig am 22 April 2017, 13:11:13
Wir haben jetzt
global:INITIALIZED
global:<TYPE> INITIALIZED
global:INITIALIZED <device>


Ich finde das ist "unordentlich".

Gedacht war eigentlich, dass ein Modul seinen eigenen globalen Scope bekommt, um ggf. auch andere Events als INITIALIZED nutzen zu können (nicht dass ich das derzeit vor hätte). Deshalb sollte das Event mit dem Modulnamen beginnen, wenn es das Modul insgesamt und unabhängig seiner Devices betrifft.

Für die einzelnen Devices bedarf es ein globales Event, damit man es von einem STATE Event unterscheiden kann.


Ergo vielleicht während der FHEM Initialisierungsphase:

global:INITIALIZED
global:<TYPE>:INITIALIZED <device>
global:<TYPE>:INITIALIZED


Während der FHEM Laufzeit:

global:<TYPE>:MODIFIED <device>
global:<TYPE>:.+


Im Grunde genommen würde ich damit annehmen, dass man allen Events, die global bereits definiert hat, ein <TYPE>: voranstellen kann. Neu im Scope eines Moduls ist dann einzig, dass es neben "INITIALIZED" noch "INITIALIZED <device>" gibt. Das ist im Scope eines Moduls logisch und führt auch zu keinen bestehenden Konflikten.

Um das Format sicherzustellen, können wir eine Wrapper-Funktion DoModuleTrigger() bereitstellen:


sub DoModuleTrigger($$@) {
    my ($type, $newState, $noreplace) = @_;
    $noreplace = 1 unless(defined($noreplace));
    return DoTrigger("global", $type.":".$newState, $noreplace);
}


Das entspräche wohl auch in etwa dem, was André sich vorgestellt hat.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

#49
rudi voraschlag ist immer noch am einheitlichsten und verträgt sich glaube ich am besten mit NOTIFYDEV. die wenn das event zur laufzeit INITIALIZED nicht ausreicht würde ich trotzdem das gleiche format wie wie beim INITALIZED event verwenden.

hab gerade mal grob über alle module geschaut. direkt aufgefallen sind mir nur CUL_HM, pilight_ctrl, HMinfo, weekprofile und DOIFtools die probleme bekommen. es sollte aber auf jeden fall vorher angekündigt werden.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Loredo

#50
Siehe aktualisierten Post vorher:


Zitat von: Loredo am 22 April 2017, 15:41:05
Im Grunde genommen würde ich damit annehmen, dass man allen Events, die global bereits definiert hat, ein <TYPE>: voranstellen kann. Neu im Scope eines Moduls ist dann einzig, dass es neben "INITIALIZED" noch "INITIALIZED <device>" gibt. Das ist im Scope eines Moduls logisch und führt auch zu keinen bestehenden Konflikten.

Um das Format sicherzustellen, können wir eine Wrapper-Funktion DoModuleTrigger() bereitstellen:


sub DoModuleTrigger($$@) {
    my ($type, $newState, $noreplace) = @_;
    $noreplace = 1 unless(defined($noreplace));
    return DoTrigger("global", $type.":".$newState, $noreplace);
}


Das entspräche wohl auch in etwa dem, was André sich vorgestellt hat.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

das klingt gut. so rum gibt es keine konflikte und es ist in sich konsistent und einheitlich.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Loredo

Zitat von: justme1968 am 22 April 2017, 16:03:40
das klingt gut. so rum gibt es keine konflikte und es ist in sich konsistent und einheitlich.


Ich habe es jetzt einmal testweise so umgestellt; damit kommt es erstmal zu keinen Konflikten mehr.

Auch habe ich nun wohl auch eine Lösung dafür gefunden zunächst alle Devices zu initialisieren (Event pro Device: ^<TYPE>:INITIALIZED <device>$) , bevor ich das Modul-globale Event sende, dass das Modul fertig initialisiert ist.
Damit kann man sicher sagen, dass alle Devices auf jeden Fall auch initialisiert sind, wenn ^<TYPE>:INITIALIZED$ geschickt wird.

Was ich den ganzen Vormittag/halben Nachmittag nicht geschafft habe ist, dass das bei einem rereadcfg auch genauso klappt. Das Problem ist dabei, dass alle Devices natürlich das REREADCFG Event erhalten. Beim ^INITIALIZED$ kriege ich das gefiltert, so dass nur das allererste Device die Modulinitialisierung übernimmt. Aber bei REREADCFG gelingt mir das einfach nicht, so dass jedes Device nochmals alle anderen Devices des gleichen TYPE initialisieren. Das ist natürlich mehr als unschön :-/

Hat da jemand Lust auch drüber zu grübeln?
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Thorsten Pferdekaemper

Zitat von: justme1968 am 22 April 2017, 13:53:37
<device>:INITIALIZEDist nicht gut da man dann den device namen kennen muss
Na und? Es geht doch gerade um den Fall, dass man auf die Initialisierungsphase eines bestimmten Device wartet.

Zitat von: Loredo am 22 April 2017, 15:32:19
Weil man es sonst nicht von einem STATE Event unterscheiden kann.
Was ist denn ein "STATE Event"?

Meiner Meinung nach sollte man verbieten, dass ein Modul ein global-Event feuert. ...am besten im fhem.pl abfangen.
Wenn unbedingt jemand eine Funktion braucht, die ihm sagt, dass alle Devices eines Moduls initialisiert sind, dann kann er sich das ja selbst bauen. (Wozu eigentlich???) Das geht, indem man nach global:INITIALIZED sich alle Devices zum Modul holt und sie dann nach und nach "abhakt", wenn alle INITIALIZED-Events da sind.
Am besten macht man das Device-INITIALIZED-Event gleich zu einem ordentlichen Reading, dann geht das ganze noch einfacher.
Gruß,
   Thorsten





FUIP

justme1968

mal unabhängig vom wozu braucht man das: das selber bauen geht nicht da die liste der devices nach dem INITIALIZED nicht unbedingt vollständig ist falls ein master device noch child devices per autocreate hinzufügt.

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Loredo

#55
Zitat von: Thorsten Pferdekaemper am 22 April 2017, 16:17:54
Meiner Meinung nach sollte man verbieten, dass ein Modul ein global-Event feuert. ...am besten im fhem.pl abfangen.

Nicht sonderlich liberal... die Frage ist ja, weshalb du das unterbinden willst? Was bringt es dir denn?
Module mit X_Notify() Funktion sollen ja bestmöglich ihren Scope per NOTIFYDEV einschränken. Ein Modul holt sich die Events also nur, wenn es sie auch braucht.
Man kann darüber nachdenken, ob man die Modul-globalen Events noch über NOTIFYDEV filterbar macht, indem man z.B. "global:<TYPE>:" dort mit berücksichtigt (wäre ein Sonderfall bzw. eine Abweichung vom reinen devspec2array() ).

Zitat von: Thorsten Pferdekaemper am 22 April 2017, 16:17:54
(Wozu eigentlich???) Das geht, indem man nach global:INITIALIZED sich alle Devices zum Modul holt und sie dann nach und nach "abhakt", wenn alle INITIALIZED-Events da sind.

Das funktioniert nur, wenn das andere Modul keine seiner Initialisierungsfunktionen von global:INITIALIZED abhängig macht. Sobald beide Module X_Notify() verwenden und darin für ihre Funktion auf global:INITIALIZED setzen, wird es schwieriger. Man kann in einigen Fällen NotifyOrderPrefix als Krücke verwenden, aber alle Fälle deckt das auch nicht ab. Ändert sich ein Modul, kann es dann sehr leicht davon abhängige andere Module brechen. Um davon unabhängig zu sein, braucht es die beschriebenen globalen Events, vor allem für die Initialisierungsphase.

Zitat von: Thorsten Pferdekaemper am 22 April 2017, 16:17:54
Was ist denn ein "STATE Event"?

Ich habe das bisher so verstanden:
Devices verschicken normalerweise Events in der Form "reading: value". Allerdings gibt es eine Ausnahme, wenn sich das Value für das Internal STATE ändert.
Früher wurde dabei das Präfix "reading:" weggelassen, weshalb dann nur "value" geschickt wurde. Man kann zwar auch inzwischen ein Event in der Form "state: value" erhalten, das ist aber nicht abwärtskompatibel. Ein Event auf Device Ebene ala DoTrigger($name, "INITIALIZED",1) lässt sich also nicht von einem Event unterscheiden, bei dem das Reading state zufällig auch den Wert "INITIALIZED" hat.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

justme1968

das event ohne den reading namen ist für state. nicht STATE. der rest bzw. die probleme damit stimmen aber.

nur per longpoll gibt es tatsächlich ein event für STATE. da kommt man aber per notify nicht dran.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Loredo

Zitat von: justme1968 am 22 April 2017, 16:43:04
das event ohne den reading namen ist für state. nicht STATE. der rest bzw. die probleme damit stimmen aber.

nur per longpoll gibt es tatsächlich ein event für STATE. da kommt man aber per notify nicht dran.


Mist, die Chance war 50/50 und ich hatte mich nochmal umentschieden  ;D
Danke für die Richtigstellung, ist immer gut die Details zu kennen und zu verstehen.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Thorsten Pferdekaemper

Zitat von: justme1968 am 22 April 2017, 16:25:59
mal unabhängig vom wozu braucht man das: das selber bauen geht nicht da die liste der devices nach dem INITIALIZED nicht unbedingt vollständig ist falls ein master device noch child devices per autocreate hinzufügt.
Mir fällt jetzt irgendwie kein richtiges Szenario ein, wo man dann auch nich wissen muss, dass alle Devices zu einem Modul angelegt sind und nicht doch noch später sowieso weitere Devices dazukommen können. Ich denke mal, in so einem Fall müsste man halt auf das "Erscheinen" jedes Device reagieren.
...oder eben das Master-Device darf sein INIZIALIZED nicht triggern bevor es nicht alle Kinder angelegt hat.

Zitat von: Loredo am 22 April 2017, 16:37:54
Nicht sonderlich liberal... die Frage ist ja, weshalb du das unterbinden willst? Was bringt es dir denn?
Ok, das war vielleicht etwas hart formuliert. Ich fände es halt schon irgendwie seltsam, wenn jemand ein Modul schreibt, welches Events generiert, die von "meinem" Modul auszugehen scheinen. ...und für mich ist "global" halt auch jemandes Modul.
Ich verstehe halt immer noch nicht, warum das unbedingt ein globales Event sein muss.

ZitatDas funktioniert nur, wenn das andere Modul keine seiner Initialisierungsfunktionen von global:INITIALIZED abhängig macht. Sobald beide Module X_Notify() verwenden und darin für ihre Funktion auf global:INITIALIZED setzen, wird es schwieriger...
Das verstehe ich jetzt nicht. Kannst Du dafür mal ein Beispiel zeigen?


ZitatIch habe das bisher so verstanden:
Devices verschicken normalerweise Events in der Form "reading: value". Allerdings gibt es eine Ausnahme, wenn sich das Value für das Internal STATE ändert.
Früher wurde dabei das Präfix "reading:" weggelassen, weshalb dann nur "value" geschickt wurde. Man kann zwar auch inzwischen ein Event in der Form "state: value" erhalten, das ist aber nicht abwärtskompatibel. Ein Event auf Device Ebene ala DoTrigger($name, "INITIALIZED",1) lässt sich also nicht von einem Event unterscheiden, bei dem das Reading state zufällig auch den Wert "INITIALIZED" hat.
Ok, mal davon ausgehend dass Du tatsächlich state und nicht STATE meinst: Unter Anderem deshalb meine ich ja, dass man daraus ein richtiges Reading machen sollte. Dann gibt's das Problem nicht mehr.

Gruß,
   Thorsten
FUIP

Loredo

Zitat von: Thorsten Pferdekaemper am 22 April 2017, 19:31:50
Mir fällt jetzt irgendwie kein richtiges Szenario ein, wo man dann auch nich wissen muss, dass alle Devices zu einem Modul angelegt sind und nicht doch noch später sowieso weitere Devices dazukommen können. Ich denke mal, in so einem Fall müsste man halt auf das "Erscheinen" jedes Device reagieren.
...oder eben das Master-Device darf sein INIZIALIZED nicht triggern bevor es nicht alle Kinder angelegt hat.

Man muss unterscheiden zwischen dem FHEM Startvorgang und den Änderungen während der Laufzeit, die dann entweder durch User-Interaktion oder durch Modul-interne Vorgänge stattfinden. Ob es sinnvoll ist eine Reihenfolge bei den Modul-globalen INITIALIZED Meldungen für das Modul selbst und den Devices einzuhalten, ist dem Modulautor zu überlassen. In der Regel dürfte es aber Sinn machen zunächst über die einzelnen Devices zu informieren und abschließend über das Modul.

Für Änderungen während der Laufzeit gibt es ja die definierten Events wie "MODIFIED", welche man dann natürlich auch entsprechend im Kontext des Moduls verwenden kann, um nach der Initialisierungsphase zu informieren. Auch das ist Modul-spezifisch. RESIDENTS macht das nun derzeit so:


    # finish module initialization
    if ( !$modules{$TYPE}{READY} && !$modules{$TYPE}{INIT} ) {
        $modules{$TYPE}{INIT} = 1;

        foreach ( devspec2array("TYPE=$TYPE") ) {
            $defs{$_}{'.READY'} = 0;
            RESIDENTStk_findResidentSlaves( $defs{$_} )
              if ( $TYPE eq "RESIDENTS" );
            RESIDENTStk_findDummySlaves( $defs{$_} )
              if ( $TYPE ne "RESIDENTS" );
        }

        Log 5, "$TYPE: module initialization completed";
        delete $modules{$TYPE}{INIT};
        $modules{$TYPE}{READY} = 1;
        RESIDENTStk_DoModuleTrigger( $TYPE, "INITIALIZED" );
    }

    # finish device initialization
    elsif ( !$hash->{'.READY'} ) {
        Log3 $name, 5, "$TYPE $name: device initialization completed";
        $hash->{NOTIFYDEV} = $NOTIFYDEV;
        $hash->{'.READY'} = 1;
        RESIDENTStk_DoModuleTrigger( $TYPE, "INITIALIZED $name" );
    }

    # device setup changed during runtime
    elsif ( $hash->{NOTIFYDEV} ne $NOTIFYDEV ) {
        $hash->{NOTIFYDEV} = $NOTIFYDEV;
        Log3 $name, 5, "$TYPE $name: device re-configuration completed";
        RESIDENTStk_DoModuleTrigger( $TYPE, "MODIFIED $name" );
    }


Zitat von: Thorsten Pferdekaemper am 22 April 2017, 19:31:50
Ok, das war vielleicht etwas hart formuliert. Ich fände es halt schon irgendwie seltsam, wenn jemand ein Modul schreibt, welches Events generiert, die von "meinem" Modul auszugehen scheinen. ...und für mich ist "global" halt auch jemandes Modul.

Deshalb unterhalten wir uns hier ja darüber.

Zitat von: Thorsten Pferdekaemper am 22 April 2017, 19:31:50
Ich verstehe halt immer noch nicht, warum das unbedingt ein globales Event sein muss.
[...]
Das verstehe ich jetzt nicht. Kannst Du dafür mal ein Beispiel zeigen?

Ich kann dir hier nicht das gesamte Event Handling von FHEM erläutern. Das beste Beispiel ist der ursprüngliche Grund dieses Threads, nämlich Dans HOMEMODE Modul im Zusammenspiel mit RESIDENTS. Dazu musst du nur die Nachrichten von Anfang an lesen.

Zitat von: Thorsten Pferdekaemper am 22 April 2017, 19:31:50
Ok, mal davon ausgehend dass Du tatsächlich state und nicht STATE meinst: Unter Anderem deshalb meine ich ja, dass man daraus ein richtiges Reading machen sollte. Dann gibt's das Problem nicht mehr.

Ein Reading ist mehr als nur ein Event und es kann nur auf Device-Ebene stattfinden. Wir reden hier von eine Abstraktionsebene höher, der allgemeinen Modulebene, die zunächst erst einmal gerätelos ist. Deshalb sind wir dann auch automatisch bei Events des Pseudo-Devices "global", da nur dafür ein gesondertes Event Handling in FHEM existiert. Es ist schlicht der Architektur von FHEM geschuldet, dass Events IMMER an einem Device hängen müssen, FHEM selbst und alle Module jedoch zunächst einmal gerätelos sind.
Deshalb gibt es auch zwei Funktionen, die bei der Initialisierung eines Moduls eine Rolle spielen: X_Initialize() initialisiert das Modul ansich unter %modules, X_Define() das jeweilige Device unter %defs.
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER