DOIF erneutes ausführen bei Änderung von $self reading in Ausführungsteil

Begonnen von Hadl, 08 August 2025, 12:42:38

Vorheriges Thema - Nächstes Thema

Damian

Zitat von: Hadl am 23 August 2025, 16:00:22Ich hatte dazu einen Vorschlag zur Erweiterung.
Mit einem neuen Attribut wie "do triggeredExec" oder noch besser einen "!" nach der eckigen Klammer im Ausführungsteil könnte man die Wiederholung bei Änderung definieren.

DOIF ([Ladeempfehlung]==true )
  (set PV_Batterie BatConfigMaxChargeWatt [!$SELF:BatMaxCharge];; )

Das Doif müsste dann auf das Reading auch triggern aber nur den Zweig wiederholen der auch den Trigger in sich trägt, falls dieser noch aktuell ist.

Ich könnte mir vorstellen dass man das ganz oft braucht wenn man ein Reading im Ausführungsteil verwendet.


Das kannst du auch heute schon erreichen, indem du für den Zweig, den du per Trigger wiederholen willst Attribut repeatsame auf 2 setzt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Hadl

Das hab ich probiert, aber so wie es aussieht wiederholt er dann den Zweig dann zwar ein weiteres mal sobald ein neuer Trigger in der Bedingung kommt, aber nicht nochmal, wenn ich den Trigger (Maximale Ladeleistung) im Ausführungsteil danach ändere.

Als Ergebnis wurde also zweimal der alte Wert an die Batterie gesendet, jedoch nicht der neue.

Damian

Zitat von: Hadl am 23 August 2025, 16:00:22Ich hatte dazu einen Vorschlag zur Erweiterung.
Mit einem neuen Attribut wie "do triggeredExec" oder noch besser einen "!" nach der eckigen Klammer im Ausführungsteil könnte man die Wiederholung bei Änderung definieren.

DOIF ([Ladeempfehlung]==true )
  (set PV_Batterie BatConfigMaxChargeWatt [!$SELF:BatMaxCharge];; )

Das Doif müsste dann auf das Reading auch triggern aber nur den Zweig wiederholen der auch den Trigger in sich trägt, falls dieser noch aktuell ist.

Ich könnte mir vorstellen dass man das ganz oft braucht wenn man ein Reading im Ausführungsteil verwendet.


Im Ausführungsteil eines FHEM-DOIF-Zweiges gibt es grundsätzlich keine Trigger, die gibt es nur in der Bedingung. Trigger an beliebiger Stelle im Code gibt es nur im DOIF-Perl-Modus.

PS. Nach zehn Jahren Eingewöhnung, möchte ich keine grundsätzlichen Eigenschaften des Moduls ändern
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Hadl

Zitat von: Damian am 25 August 2025, 09:59:37Im Ausführungsteil eines FHEM-DOIF-Zweiges gibt es grundsätzlich keine Trigger, die gibt es nur in der Bedingung. Trigger an beliebiger Stelle im Code gibt es nur im DOIF-Perl-Modus.
OK, verstanden. Das war mir nicht bewusst. Das schränkt aber die Nutzung von Readings im Ausführungsteil deutlich ein, bzw erzwingt workarounds.
Ich werde mal wenn ich Zeit habe das Beispiel auf den Perl Modus umstellen und hier schreiben welche Variante die übersichtlichere ist.

Zitat von: Damian am 25 August 2025, 09:59:37PS. Nach zehn Jahren Eingewöhnung, möchte ich keine grundsätzlichen Eigenschaften des Moduls ändern
Kann ich auf der einen Seite verstehen, wird aber die Weiterentwicklung auch blockieren.
Mein Vorschlag war schon so gedacht das er rückwärtskompatibel ist, daher das neue Attribut bzw Trigger Zeichen.
Oder meintest du das am Doif Code dadurch so viele Änderungen notwendig wären das dass Risiko von Fehlern zu groß ist?

Danke auf jeden Fall für deine Erklärungen und das sehr hilfreiche Modul.

Damian

Zitat von: Hadl am 26 August 2025, 18:11:09Oder meintest du das am Doif Code dadurch so viele Änderungen notwendig wären das dass Risiko von Fehlern zu groß ist?


Auch das, das würde den Code "auf den Kopfstellen". Der Perl-Modus entstand dagegen an einem Tag. Es ist im Grunde nur die Bedingung aus dem FHEM-Modus, die übrigens auch im FHEM-Modus nach paar Ersetzungen vom Perlinterpreter ausgeführt wird.

Das Modul ist viel besser bei den Usern angekommen, als ich ursprünglich gedacht hatte. Es hat allerdings im Laufe der Zeit schon einige Erweiterungen erhalten.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Ich habe mir jetzt nochmal die anfängliche Aufgabenstellung angesehen.
Warum wird nicht gleich PV_Batterie BatConfigMaxChargeWatt vom WebCmd gesetzt? Dann kann man auch direkt ohne Handstände drauf triggern.

Hadl

Hallo Per,
ja, aktuell wird BatMaxCharge vom WebCmd gesetzt. Prinzipiell könnte auch also auch drauf triggern. Nur brauch ich den Wert nicht in der Bedingung, sondern in der Ausführung. Da unterstützt Doif Fhem keine Trigger.

Der Doif entscheidet aktuell zwischen zwei Werten die er an die Batterie sendet. Null Watt oder den Wert von BatMaxCharge. Vielleicht werden es auch mal mehr Möglichkeiten oder ein berechneter Wert.

tobi01001

Zitatdefmod doif_PvBatteryChargeForecast DOIF (\
 ([PV_SolarForecast:Battery_ChargeUnrestricted_01] == 1) or\
 ([PV_SolarForecast:Battery_ChargeRequest_01] == 1) or\
 ([Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < [PV_SolarForecast:Battery_OptimumTargetSoC_01:d])\
)\
  (set PV_Batterie BatConfigMaxChargeWatt [$SELF:BatMaxCharge];; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\
DOELSE\
  (set PV_Batterie BatConfigMaxChargeWatt 0;; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\

Ich nehme an [$SELF:BatMaxCharge] ist numerisch. Ein do always bzw. unnötige erneute Ausführung möchtest du vermeiden.
Für erneute Ausführung (bei Änderung) braucht DOIF aber entweder einen Zustandswechsel (anderen Zweig) oder do always.

Ich würde die ersten 3 Bedingungen in ein DOIFReading packen und [$SELF:BatMaxCharge] als Bedingung hinzufügen und do always setzen.
In etwa:
attr doif_PvBatteryChargeForecast DOIF_Readings LadeEmpfehlung:{\
    if(\
        ([PV_SolarForecast:Battery_ChargeUnrestricted_01] == 1) or \
        ([PV_SolarForecast:Battery_ChargeRequest_01] == 1) or \
        ([Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < [PV_SolarForecast:Battery_OptimumTargetSoC_01:d])\
       ) \
    { \
       1;; \
    } \
    else \
    { \
        0;;\
    }\
}
attr doif_PvBatteryChargeForecast do always

defmod doif_PvBatteryChargeForecast DOIF ([$SELF:LadeEmpfehlung] and [$SELF:BatMaxCharge:d]) \
   (set PV_Batterie BatConfigMaxChargeWatt [$SELF:BatMaxCharge];; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\
DOELSE\
  (set PV_Batterie BatConfigMaxChargeWatt 0;; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\

So - ungestestet - würde ich das realisieren, ohne ständig zu senden.
Damit erfolgt der entsprechende set Befehl bei Änderung BatMaxCharge oder bei Änderung des Sammelzustands Ladeempfehlung. Da BatMaxCharge numerisch ist, wird bei 0 ebenso der DOELSE Zweig aufgerufen.


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.

Hadl

Zitat von: tobi01001 am 29 August 2025, 11:26:17defmod doif_PvBatteryChargeForecast DOIF ([$SELF:LadeEmpfehlung] and [$SELF:BatMaxCharge:d]) \
   (set PV_Batterie BatConfigMaxChargeWatt [$SELF:BatMaxCharge];; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\
DOELSE\
  (set PV_Batterie BatConfigMaxChargeWatt 0;; set PV_Batterie BatConfigMaxEnabled chargeMax;;)\

So - ungestestet - würde ich das realisieren, ohne ständig zu senden.
Damit erfolgt der entsprechende set Befehl bei Änderung BatMaxCharge oder bei Änderung des Sammelzustands Ladeempfehlung. Da BatMaxCharge numerisch ist, wird bei 0 ebenso der DOELSE Zweig aufgerufen.
Ja, das sieht auch gut aus. Mit der Dummy Bedingung auf ungleich Null funktioniert auch der Trigger und bei Null ist's eh egal welchen Zweig ich nehme. Das Doif Reading filtert dann gleiche Trigger raus.
Nur wenn's mal mehrere Bedingungen werden könnte es etwas unübersichtlicher werden.
Ich denke dann müsste ich sicherstellen dass immer nur eine Bedingung für einen Zweig wahr wird. Evtl. geht auch checkall

Danke schonmal, ich probiere das auch mal aus