DOIF - Perl: Triggert zyklisch und finde den Grund nicht

Begonnen von bmwfan, 08 Juli 2025, 11:42:37

Vorheriges Thema - Nächstes Thema

bmwfan

Hallo,

ich habe eine Logik zur Steuerung meiner Lüftungsanlage, abhängig von Außen- und Innentemperatur sowie der Luftfeuchtigkeit im Bad entworfen. Funktioniert soweit auch, allerdings wird der jeweils aktive Zweig der Logik zyklisch durchlaufen und somit werden auch unnötigerweise zyklisch Sollwertvorgaben an die Lüftungsanlage bzw. in einem anderen Zweig auch Stellbefehle an Lüftungsklappen gesendet. Da in dem hier gezeigten Zweig (Zweig 2) das Triggerargument ein Mittelwert einer alle 20 min. aktualisierten Luftfeuchtigkeit ist, der bei Änderung und nach einem Mindestzeitraum (für den Plot) in ein Log geschrieben wird, verstehe ich das nicht und würde den Fehler gerne finden und beheben.
Zusatzfrage: Damit ich besser debuggen kann, schreibe ich mir immer Einträge ins Logfile. Gibt es da keine einfachere Methode, den Programmablauf nachzuvollziehen?

defmod di_HomeVent DOIF ## Bedingung fuer Lueften erfuellt? Feuchtigkeit abfragen\
{if ([HmIP_BWTH_000C9BE99C66F8_9:humidity] > [?HmIP_BWTH_000C9BE99C66F8_9:humidity20minSchwelle])\
## {if ([du_Test] eq "Lueften_EIN")\
{\
Log3("HomeVent", 3, "Zweig 1");;;;\
set_Reading("Status_Lueftung", "Lueften EIN");;;;\
  ## (1) Es muss gelüftet werden => Abfrage Lueften schon eingestellt?\
  if ([di_HomeVent:Lueften] ne "EIN")\
##  (1.1) Lueften noch nicht eingestellt => aktuelle Leistung speichern, Leistung auf Lueften stellen. Klappen mit 60 Sec. delay umschalten\
{\
fhem("setreading MQTT2_ESP32_a9D27C HomeVent_Leistung_Soll {(ReadingsVal('MQTT2_ESP32_a9D27C','Normal_Lueftungsmodulation_percent',''))}");;;;\
.....
}\
else\
{\

} ## (1.2) Aussprung mit return, da Lüftung Bad OG schon auf EIN steht\
  }\
 [b][size=4]## (2) Es muss nicht gelüftet werden => Abfrage: Noch im Lüftungsvorgang?\[/size][/b]
 elsif ([?HmIP_BWTH_000C9BE99C66F8_9:humidity] <= ([HmIP_BWTH_000C9BE99C66F8_9:humidity20minSchwelle] + 1))\
 ## elsif ([du_Test] eq "Lueften_AUS")\
  {\
Log3("HomeVent", 3, "Zweig 2");;;;\
set_Reading("Status_Lueftung", "Lueften AUS");;;;\
## (2.1) Ist nicht mehr im Lüftungsvorgang => Leistungssollwert von vor Lüften setzen, Info senden\
fhem_set("MQTT2_FHEM_Server publish cangateway/Normal_Lueftungsmodulation_percent/set {(ReadingsVal('MQTT2_ESP32_a9D27C','HomeVent_Leistung_Soll',''))}");;;;\
## Lueften noch im Lüftungsmodus obwohl Soll "nach Lüften" => Ist Merker Lüftung AUS schon gesetzt?\
if ([di_HomeVent:Lueften] eq "EIN")\
{\
## (2.1.1) Merker steht noch auf Lüften => Merker Lüften AUS setzen\
set_Reading("Lueften", "AUS");;;;\
Log3("HomeVent", 3, "Zweig 2.1");;;;\
## Klappenstellung nach Schaltervorgabe im SZ einstellen. if (2.1.1.1): Schalter auf EG => EG setzen, else (2.1.1.2): Schalter nicht auf EG => OG Setzen\
if ([MQTT2_shellyplus2pm_345f451a4c0c:Schalterstellung] eq "EG")\
{\
fhem_set("MQTT2_shellyplus2pm_345f451a4c0c_CH2 on");;;;\
fhem_set("MQTT2_shellyplus2pm_345f451a4c0c off");;;;\
set_Reading("Klappenstellung", "EG");;;;\
set_Reading("Schalterstellung", "EG");;;;\
Log3("HomeVent", 3, "Zweig 2.1.1.1 EG");;;;\
## return;;;;\
}\
else {\
fhem_set("MQTT2_shellyplus2pm_345f451a4c0c_CH2 off");;;;\
fhem_set("MQTT2_shellyplus2pm_345f451a4c0c on");;;;\
set_Reading("Klappenstellung","OG");;;;\
set_Reading("Schalterstellung", "OG");;;;\
Log3("HomeVent", 3, "Zweig 2.1.1.1 OG");;;;\
## return;;;;\
}\
}\
## (2.1.2) Merker steht nicht mehr auf Lüften => Reduzierung Lüftung abfragen Sommer: Aussen Garten > Anluft Hoval;; Winter: Aussen Garten <= Abluft Hoval\
else \
{\
if (([?Wetter_Pro:fc0_tempMax] > 25 && ([Ga_UmweltSen:temperatureT20min.av] > [?di_Thermostate_Average:Mittelwert])) || ([?Wetter_Pro:fc0_tempMin] < 0 && ([?Ga_UmweltSen:temperatureT20min.av] <= [?di_Thermostate_Average:Mittelwert])))\
## if ([du_Test1] eq "Reduziert")\
## (2.1.2.1) Reduzierter Betrieb ist notwendig => aktuelle Leistung speichern, reduzierte Leistung setzen, Info Leistung reduziert senden, Merker Lüftung RED setzen, \
{\
fhem_set("MQTT2_FHEM_Server publish cangateway/Normal_Lueftungsmodulation_percent/set {(ReadingsVal('di_HomeVent','Power_reduziert',''))}");;;;\
set_Reading("Lueften", "RED");;;;\
set_Reading("Status_Leistung", "Reduziert");;;;\
Log3("HomeVent", 3, "Zweig 2.1.2.1");;;;\
}\
## (2.1.2.2)Reduzierter Betrieb ist nicht notwendig => Leistung von vor Reduzierung setzen, Info Lüftung AUS über RED senden, Merker Lüftung AUS setzen, \
else {\
fhem_set("MQTT2_FHEM_Server publish cangateway/Normal_Lueftungsmodulation_percent/set {(ReadingsVal('di_HomeVent','Power_Standard',''))}");;;;\
set_Reading("Lueften", "AUS");;;;\
set_Reading("Status_Leistung", "Normal");;;;\
Log3("HomeVent", 3, "Zweig 2.1.2.2");;;;\
}\
}\
}\
 ## (2.2) else-Zweig unnötig, da noch im Lüftungsvorgang\
}
attr di_HomeVent cmdState Reduziert | Lüften EIN | Lüften AUS | Reset
attr di_HomeVent disable 0
attr di_HomeVent readingList Lueften Status_Lueften Status_Leistung
attr di_HomeVent room 3.4_Technik,9.8.1_DOIF
attr di_HomeVent verbose 5

setstate di_HomeVent initialized
setstate di_HomeVent 2025-07-08 11:09:52 Device HmIP_BWTH_000C9BE99C66F8_9
setstate di_HomeVent 2025-07-04 17:51:55 Klappenstellung EG
setstate di_HomeVent 2025-07-08 11:09:52 Lueften AUS
setstate di_HomeVent 2024-12-01 11:20:22 Power_Lueften 80
setstate di_HomeVent 2024-12-24 16:37:53 Power_Standard 60
setstate di_HomeVent 2024-12-01 11:18:01 Power_reduziert 20
setstate di_HomeVent 2025-07-04 17:51:55 Schalterstellung EG
setstate di_HomeVent 2024-11-30 11:18:11 Schalterstellung_Zuvor Reset
setstate di_HomeVent 2025-07-08 11:09:52 Status_Leistung Normal
setstate di_HomeVent 2025-07-08 11:09:52 Status_Lueftung Lueften AUS
setstate di_HomeVent 2025-07-08 11:09:52 block_01 executed
setstate di_HomeVent 2025-07-08 11:05:44 e_Ga_UmweltSen_temperatureT20min.av 13.6
setstate di_HomeVent 2025-07-08 11:04:47 e_HmIP_BWTH_000C9BE99C66F8_9_humidity 61
setstate di_HomeVent 2025-07-08 11:09:52 e_HmIP_BWTH_000C9BE99C66F8_9_humidity20minSchwelle 69
setstate di_HomeVent 2025-07-04 14:19:00 logEntry Zweig 2.1.2.1
setstate di_HomeVent 2025-07-07 12:21:22 mode enabled
setstate di_HomeVent 2025-07-07 12:21:23 state initialized

Da aktuell immer der Zweig 2 (Bad muss nicht gelüftet werden und es ist auch kein reduzierter Betrieb aufgrund hoher Außentemp. notwendig) durchlaufen wird, steht im Logfile ständig:
2025.07.08 11:19:31.968 3: Zweig 2.1.2.2
2025.07.08 11:19:31.965 3: Zweig 2
2025.07.08 11:18:37.226 3: Zweig 2.1.2.2
2025.07.08 11:18:37.222 3: Zweig 2
2025.07.08 11:15:17.923 3: Zweig 2.1.2.2
2025.07.08 11:15:17.919 3: Zweig 2
2025.07.08 11:14:38.969 3: Zweig 2.1.2.2
2025.07.08 11:14:38.966 3: Zweig 2
2025.07.08 11:09:52.486 3: Zweig 2.1.2.2
2025.07.08 11:09:52.483 3: Zweig 2
2025.07.08 11:05:44.461 3: Zweig 2.1.2.2
2025.07.08 11:05:44.457 3: Zweig 2
2025.07.08 11:04:47.166 3: Zweig 2.1.2.2
2025.07.08 11:04:47.163 3: Zweig 2
2025.07.08 11:04:08.219 3: Zweig 2.1.2.2
2025.07.08 11:04:08.216 3: Zweig 2
2025.07.08 11:03:30.706 3: Zweig 2.1.2.2
2025.07.08 11:03:30.703 3: Zweig 2
2025.07.08 10:59:34.227 3: Zweig 2.1.2.2
2025.07.08 10:59:34.223 3: Zweig 2

Das bedeutet ja, dass das userreading humidity20minSchwelle des Thermostaten im Bad HmIP_BWTH_000C9BE99C66F8_9: ein Event auslöst.

defmod HmIP_BWTH_000C9BE99C66F8_9 HMCCUDEV 000C9BE99C66F8 forceDev sd=1.ACTUAL_TEMPERATURE cd=1.SET_POINT_TEMPERATURE
attr HmIP_BWTH_000C9BE99C66F8_9 alias Thermostat_BadOG
attr HmIP_BWTH_000C9BE99C66F8_9 ccureadingfilter 1,10,9..*
attr HmIP_BWTH_000C9BE99C66F8_9 cmdIcon auto:sani_heating_automatic manu:sani_heating_manual boost:sani_heating_boost on:general_an off:general_aus
attr HmIP_BWTH_000C9BE99C66F8_9 devStateIcon OK:10px-kreis-gruen Error:10px-kreis-rot Initialized:10px-kreis-gelb
attr HmIP_BWTH_000C9BE99C66F8_9 event-min-interval activity:21600,state:300,1.ACTUAL_TEMPERATURE:240,1.HUMIDITY:240,1.SET_POINT_TEMPERATURE:240,10.STATE:240,humidity20minSchwelle:240,humidity20min.av:240
attr HmIP_BWTH_000C9BE99C66F8_9 event-on-change-reading activity,state,1.SET_POINT_TEMPERATURE,10.STATE
attr HmIP_BWTH_000C9BE99C66F8_9 event-on-update-reading humidity,humidity20min.av,humidity20minSchwelle
attr HmIP_BWTH_000C9BE99C66F8_9 icon hm-tc-it-wm-w-eu
attr HmIP_BWTH_000C9BE99C66F8_9 room 2.1_OG_Bad,9.6.0_System
attr HmIP_BWTH_000C9BE99C66F8_9 stateFormat T: 1.ACTUAL_TEMPERATURE° H: 1.HUMIDITY% D: 1.SET_POINT_TEMPERATURE° V: Stellventil
attr HmIP_BWTH_000C9BE99C66F8_9 substexcl desired-temp
attr HmIP_BWTH_000C9BE99C66F8_9 userReadings Stellventil {if (ReadingsVal("$name","10.STATE","") eq "on") {return 1}\
elsif (ReadingsVal("$name","10.STATE","") eq "off") {return 0}},\
onoff {ReadingsVal($name,"10.STATE",0) ne "on" ? 0 : 1},\
humidity20minSchwelle {ReadingsVal("$name","humidity20min.av","")+8},\
humidity20min.av {sprintf("%.0f",int(movingAverageT("HmIP_BWTH_000C9BE99C66F8_9","humidity",1200)+0.5))}\
attr HmIP_BWTH_000C9BE99C66F8_9 webCmd desired-temp:auto:manu:boost:on:off
attr HmIP_BWTH_000C9BE99C66F8_9 widgetOverride desired-temp:slider,4.5,0.5,30.5,1

setstate HmIP_BWTH_000C9BE99C66F8_9 T: 22.1° H: 61% D: 17.0° V: 0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.ACTIVE_PROFILE 1
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.ACTUAL_TEMPERATURE 22.1
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.ACTUAL_TEMPERATURE_STATUS NORMAL
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.BOOST_MODE off
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.BOOST_TIME 0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.FROST_PROTECTION false
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.HEATING_COOLING HEATING
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.HUMIDITY 61
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.HUMIDITY_STATUS NORMAL
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.PARTY_MODE false
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-14 11:39:54 1.PARTY_SET_POINT_TEMPERATURE 0.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-14 11:39:54 1.PARTY_TIME_END
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-14 11:39:54 1.PARTY_TIME_START
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.QUICK_VETO_TIME 0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.SET_POINT_MODE auto
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.SET_POINT_TEMPERATURE 17.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.SWITCH_POINT_OCCURED false
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 1.WINDOW_STATE closed
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:11 10.STATE off
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:11 9.STATE off
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-14 11:39:25 IODev myHMCCU3
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 Stellventil 0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 activity alive
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 boost off
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 control 17.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 desired-temp 17.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 devstate ok
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 hmstate 22.1
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 humidity 61
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 humidity1Std.av 61.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 humidity20min.av 61
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 humidity20minSchwelle 69
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 humidity3Std.av 61
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 humidityT1S.av 61.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 measured-temp 22.1
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 onoff 0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:26:39 rssidevice -76
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-16 00:35:01 rssipeer -76
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 state 22.1
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-06-14 11:39:54 voltage 0.0
setstate HmIP_BWTH_000C9BE99C66F8_9 2025-07-08 11:25:10 week-program 1

Kann das zyklische triggern an den Einstellungen event-min-interval, event-on-change-reading und event-on update-reading liegen? Ist die Zusammenstellung falsch?
Oder liegt as zyklische triggern daran, dass Perl-DOIF Routinen tatsächlich ständig durchlaufen werden und ich über einen zusätzlichen Merker dafür sorgen muss, das nur 1 mal ausgelöst (Sollwertvorgabe) wird?

Ich hatte vorher eine ähnliche Logik in DOIF realisiert, wo ich die Wiederholungen über repeatsame unterbunden habe. Wie löse ich das in Perl, da es das Attribut nicht gibt.

Grüße Jürgen
Synology DS720+ mit Docker-Container und Haupt-FHEM, HM-LAN, Jalousienaktoren HmWired, Shelly-Devices; Raspi 3B+ mit piVCCU ohne FHEM-Instanz, CUL, JeeLink; Raspi 3B+ mit FHEM und HMUARTUSB,  Raspi 3B+ mit HMUARTGPIO, 1-wire, ebusd

Damian

Wenn du DOIF-Perl benutzt, dann kannst du für jeden Trigger jeweils einen eigenen Block erzeugen, statt alles in ein if-elsif-Konstrukt zu packen. Dann wird bei einem Event zumindest nur der jeweiligen Block ausgeführt.

Um die Unterbindung einer Wiederholung einer Ausführung muss man sich im Gegensatz zu DOIF-FHEM-Modus allerdings selbst kümmern, indem man z. B. eine Instanzvariable (beginnt mit $_ im DOIF-Perlmodus) mit einem Wert belegt und wieder abfragt.

Debuggen in FHEM ist grundsätzlich schwer. Ich nutze ebenfalls Testausgaben.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF