[gelöst durch anderen Ansatz] Selbsttriggerung in einem DOIF

Begonnen von cwagner, 16 September 2024, 19:36:29

Vorheriges Thema - Nächstes Thema

cwagner

Nun habe ich mich offensichtlich mal wieder verbastelt und finde einfach die Ursache nicht: Für eine Pumpensteuerung habe ich ein PWM-Modul (Shelly). Mit folgendem Ausschnitt aus einem größeren DOIF versuche ich nun die Drehzahl der Pumpe einer Temperaturdifferenz folgen zu lassen:
{
if ([$SELF:T_diff] <10 and ![$SELF:OFF] ) {
    fhem_set "PWM_Solarpumpe pct ".([PWM_Solarpumpe:pct:d]-5);
    set_State "Zweig minus: ".[PWM_Solarpumpe:pct]
    }
elsif ([$SELF:T_diff] >10 and ![$SELF:OFF] ) {
    fhem_set  "PWM_Solarpumpe pct ".([PWM_Solarpumpe:pct:d]+5);
    set_State "Zweig plus: ".[PWM_Solarpumpe:pct]
    }
}

T_diff und OFF sind event_Readings im DOIF
T_diff: round(([T_Kollektor:temperature2]-[$SELF:med_T_Speicher]),0),
OFF:[$SELF:med_T_Speicher] >85 or [$SELF:T_diff]<3
.

Meine Idee ist, dass diese Schleife nur von T_diff (und von OFF, was wir hier aber vernachlässigen können) getriggert wird. Tatsächlich ist es aber so, dass ein T_diff-Event den entsprechenden Zweig auch auslöst, doch danach wird er einfach  im knappen Sekundentakt immer wieder ausgelöst, bis der Maximal- bzw. Minimalwert von PWM_Solarpumpe:pct erreicht ist.

Gebe ich aber Festwerte wie
fhem_set  "PWM_Solarpumpe pct 70" in den Bedingungen vor, dann wird genau dieser Wert gesetzt.

Welchen geheimen Mechanismus löse ich denn da aus und vor allem: Wie vermeide ich ihn ;-)

Christian

P.S. Und auch von mir Gratulation zum 10jährigen von DOIF: Für mich ist es unentbehrlich und der "Dremel" im Werkzeugkasten von FHEM.🎂🥂
PI 2B+/5 Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

Damian

Ich kann jetzt keine Schleife innerhalb der Definition erkennen, vielleicht ist da noch eine Abhängigkeit außerhalb des DOIFs. Am besten loggst du alle relevanten Readings, vielleicht fällt dann was auf.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tobi01001

Jede Temperaturänderung (gerundet) setzt einen neuen Wert für T_diff. Jeder neue T_diff Wert triggert das DOIF und jeder Wert kleiner 10 oder größer 10 löst den entsprechenden Zweig aus. Aber ich kann mir kaum vorstellen, dass das sekündlich passiert...

Welche Attribute sind denn gesetzt?

Man könnte jetzt einen T_diff_10 definieren, der -1, 0 oder 1 annimmt: if([T_Kollektor:temperature2]-[$SELF:med_T_Speicher] < 10)
{
   -1;
}
elsif(([T_Kollektor:temperature2]-[$SELF:med_T_Speicher] > 10)
{
   1;
}
else
{
   0;
}
Dann erfolgt der Trigger nur wenn die Bedingung erreicht ist (und sich dann auch ändert). ein DOIF-Reading genügt, außer du brauchst die trigger extern.

Aber so ganz verstanden habe ich das Ziel noch nicht, warum du -5 bzw +5 einmalig ausführen lassen möchtest bzw unter welchen Bedingungen.

Daher andere Frage:
Was nützt es den PCT Wert einmalig um 5 zu erhöhen oder zu erniedrigen? Oder einfach gefragt, was möchtest du denn überhaupt erreichen?
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.

cwagner

Vielen Dank für Eure Auseinandersetzung mit meinem Ziel. Natürlich soll die Bedinungskette immer durchlaufen werden, wenn T_diff sich ändert. Wie Ihr erkannt habt, runde ich, tatsächlich zeigt das Eventlog auch, dass dadurch in einzelnen Minutenabstand ein Event auftritt (die zugrundliegenden Werte werden alle 60 Sekunden aktualisiert).
Das Ziel ist simpel: Wenn die Temperaturdifferenz steigt, soll die Drehzahl der Pumpe erhöht werden, wenn sie sinkt soll sie erniedrigt werden.  Wird bei wenig Sonneneinstrahlung zuviel Wärme abtransportiert, sinkt der Vorlauf unter den förderlichen Wert, ja u.U. sogar unter die veränderliche Speichertemperatur, somit zur Entladung des Speichers. Angestrebt wird eine Differenz von etwa 10 bis 15°. Ist die Fördermenge zu niedrig, erhitzt sich der Kollektor zu sehr und es entstehen Dampfblasen - schlecht fürs Material und schlecht für die Ausbeute.
Tatsächlich haben mir Event-Log und  Beobachtung keinen Hinweis darauf gegeben, dass ich da noch einen anderen Trigger habe - insbesondere, nachdem ich nur noch die gezeigten zwei Bedingungen in ein eigenes DOIF ausgelagert habe, um das Thema einzugrenzen. Aktuell nimmt nur dieses eine DOIF Einfluss auf den PWM (Shelly) der Solarpumpe.

Christian
PI 2B+/5 Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

Per

Erweitere dein DOIF_reading, indem du das >10 mit rein packst, dann triggerst du darauf.

cwagner

#5
Die Vorschläge, auf >|< 10 zusätzlich zu triggern, würden meine Absicht unterlaufen, immer wenn sich T_diff oberhalb 10 verändert, einfach die Drehzahl der Pumpe zu erhöhen (pct um 5 erhöhen) und solange es sich unterhalb von 10 (genau bis 3, weil dann die Abschaltbedingung verlässlich greift) zu erniedrigen.
Eigentlich gilt: je größer oberhalb 10, umso größeres pct und vice versa.
Vielleicht verfolge ich mal diesen Gedanken. Oder ich speichere pct in eine Variable bevor ich fhem_set PWM_Solarpumpe pct X aufrufe...

Also{if ([$SELF:T_diff] and ![$SELF:OFF] ) {
fhem_set "PWM_Solarpumpe pct ". [$SELF:T_diff]*3;
set_State "Solarpumpe auf ".[PWM_Solarpumpe:pct]."%"
}
}

führt schon mal insofern weiter, dass es kürzer ist und kein Selbststriggern auslöst...
Vielen Dank
PI 2B+/5 Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

Per

Ehrlicherweise muss ich gestehen, ich habe deine Aufgabe nicht ganz verstanden.

Entweder du berechnest pct aus der Differenz (wo ist da das Problem?).  Oder du änderst den aktuellen Wert nach Zeit um einen bestimmten Betrag (so schnell dürfte sich die Diff nicht ändern, um da Probleme zu bekommen).
Für Letzteres wäre cmdPause noch eine Hilfe.
Damit kannst du, solange die Differenz besteht, hoch- bzw runrerregeln, ohne dass du deb hohe Takt des Sensors übernimmst.

Sany

Hallo cwagner,

etwas spät, und auch wenn Du schon eine Lösung gefunden hast, hier noch ein paar Hinweise, die evtl. zum Verständnis dienen.
Ich beziehe mich nur auf den Perl-DOIF Ausschnitt aus Deinem ersten Post, es geht auch nicht um den Inhalt (sprich was dabei rauskommen soll), sondern nur um die Art und Weise, wie das Perl-DOIF arbeitet:

Das gezeigte Kontrukt ist ein Perl-Block innerhalb der Definition deines DOIF-Devices. Für solch einen Perlblock gelten die Hinweise aus dem Wiki zu Perl-DOIF unter "Für Umsteiger vom DOIF-fhem Modus":
ZitatEreignis-/Zeittrigger sind intern Perlfunktionen, daher können sie an beliebiger Stelle im Perlcode angegeben werden, wo Perlfunktionen vorkommen dürfen.
ZitatInnerhalb eines Perlblocks sind beliebige Hierarchietiefen möglich, dabei kann der Trigger irgendwo innerhalb des Blocks vorkommen:
ZitatInnerhalb eines DOIF-Perl-Blocks muss mindestens ein Trigger definiert werden. Zu beachten ist, dass beim passenden Trigger nicht nur ein Zweig, sondern der gesamte Block ausgeführt wird.
Wenn man nun Deinen Code anschaut: in der if und elsif Bedingung hast Du Deinen Trigger
[$SELF:T_diff] und dann noch der OFF-Trigger, der aber wohl nicht auslöst.
Im Rest (also den Ausführungsteilen) des Codes stehen dann noch
mehrmals
[PWM_Solarpumpe:pct] Verglichen mit den Anmerkungen aus dem Wiki würde ich sagen: die triggern alle, und jedesmal wird der gesamte Block abgearbeitet. Da Du nur Vergleiche in den Bedingungen hast und keine Ereignistrigger werden die Bedingungen immer wieder ausgewertet, sobald sich PWM-Solarpumpe:pct mit enem neuen Wert meldet.
Ich habe selbst in dieser Richtung etliche Erfahrungen gemacht, dass DOIFs nicht so wollten wie ich. Nun schaue ich konsequent nach Triggern und "entschärfe" alles, was nicht triggern soll, entweder mittels [?device:reading] oder gleich ReadingsVal bzw. ReadingsNum für Zahlen. Als Trigger nutze ich am liebsten Event-trigger (da wo es geht), da diese wirklich triggern und nicht jedesmal, wenn ein Device "zuckt", die Bedingungen abgearbeitet werden.
Dann gibt es zur Fehlersuche in einem Perl-DOIF noch die Möglichkeit, ohne Klimmzüge einfach ins Log schreiben zu lassen:
Log (1,"$SELF: device: $device event: $event");Diese Zeile am Ende des Blocks (also nach dem 2ten Zweig) eingetragen liefert Dir im Log ganz bequem den Überblick, wer hat was "gesagt" um das DOIF zu triggern.
Das $SELF stellt noch den Namen des DOIF an den Anfang der Zeile und mittels einem
tail -f -n 5000 /opt/fhem/log/fhem-2024-38.log | grep <Name des DOIF>im Terminalfenster, wo Du auf dem fhem-Server verbunden bist, bekommst Du alles von diesem DOIF, ohne den "störenden" Rest. Und wenn alls läuft, entweder die Zeile mit dem Log... löschen oder auskommentieren für spätere Änderungen.

Wie gesagt, dass sind nur meine Erfahrungen theoretisch auf Deinen DOIF-Auszug angewendet. Vielleicht hast Du ja Lust, das mal zu testen und zu berichten.

Viel Erfolg!



Sany
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

Man müsste erstmal wissen, ob die Anweisung in DOIF-Perl-Modus oder in Perl aber im FHEM-Modus sind. Das kann man nicht erkennen, da nicht die ganze Definition zu sehen ist.

Wie Sany schon geschrieben hat, im Gegensatz zum FHEM-Modus würden im DOIF-Perl-Modus auch diese Teile in der Ausführung das DOIF-Device triggern:

   fhem_set "PWM_Solarpumpe pct ". [$SELF:T_diff]*3;
   set_State "Solarpumpe auf ".[PWM_Solarpumpe:pct]."%"

Daher am besten mit Fragezeichen die Trigger hier rausnehmen, weil sie mit Sicherheit nicht gewollt sind.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sany

ZitatMan müsste erstmal wissen, ob die Anweisung in DOIF-Perl-Modus oder in Perl aber im FHEM-Modus sind. Das kann man nicht erkennen, da nicht die ganze Definition zu sehen ist.
ich hatte wegen fhem_set und set_State auf DOIF-Perl getippt.
Die ganze DEF wäre natürlich besser, oder zumindest ein Hinweis auf den Modus.
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

ja, dann muss es der Perl-Modus sein.

In dem Fall kann man die Schreibweise mit eckigen Klammern bei nicht Triggern sinnvoll umgehen, z. B.

  fhem_set "PWM_Solarpumpe pct ".get_Reading(T_diff)*3;

oder

   set_State "Solarpumpe auf ". ReadingsVal("PWM_Solarpumpe","pct","")."%"
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF