Verbesserungsvorschlag: DOIF Attribute im Ausfürhungsblock und indirekte Bedingu

Begonnen von Elektrolurch, 18 Februar 2025, 10:40:27

Vorheriges Thema - Nächstes Thema

Elektrolurch

Hallo Damain,

zunächst einmal mein Lob: Das DOIF - Modul ist einfach Klasse und ich habe sehr viel eigenen perl-Code durch DOIF - Objekte erfolgreich ersetzen können.
Dabei bin ich allerdings auch auf einige kleinere "Unbequemlichkeiten" gestossen:
1. Alle Attribute, die sich auf Ausführungsblöcke  beziehn, wie z.B. "wait" usw. haen ja die Form: ... wait 0:20,50:... usw.
Ändert man nun die Reihenfolge seiner Bedingungen oder fügt zusätzliche Ausfürhungsblöcke ein, so  muss man von  Hand die Attribute anpassen.
Schön und praktischer wäre es, wenn man diese Attribute alternativ auch als Anweisung (erste) in einem Ausfürhungsblock angeben könnte, z.B.
DOIF(...Bedingung)
(
wait 10,
set lamp on
)
(
wait 120,
set lamp off
)

2. Es gibt zwar die Möglichkeit, von indirekten Zeitangaben, d.h. der Zeitpunkt steht in  einem reading, prima Sache, leider geht das aber nicht für andere Bedingungen.
Ich will das an einem Beispiel demonstrieren, bei dem es durchaus sinnvoll wäre:
Ich habe 9 Räume mit Heizungsthermostaten und Fensterkontakten. Wenn ein Fenster geöffnet wird, regelt das Thermostat herunter. Das machen die fht - Komponenten selbstständig.
Um nun aber durch versehentliches Dauerlüften die Temperatur allzu sehr absenken zu lassen, löse ich einen akustsischen  Warnton aus und starte über die fritzbox einen internen Anruf, über den mitgeteilt wird, in welchem Zimmer die Temperatur unter einen Schwellwert gefallen ist.
Der Alarm wird einige Male  wiederholt und sollte sofort beendet werden, wenn das entsprechende Fenster wieder geschlossen wird.
defmod Alarm_Fenster_Temp_doif DOIF
## cmd 1: aus
(0)
(
setreading $SELF scharf 0,
set sig2 reset,
{Log3("$SELF",3,"$SELF: cmd 1 - aus")}
)

## cmd 2: ein
## reset ALARM, wenn Fenster geschlossen wird
DOELSEIF([07:00]
or
(
## hier wäre das "indirekte" Erreignis, was leider so nicht geht....
## [[$SELF:AlarmDevice]:"closed"]
## mit perl - code in der Bedingung geht es auch nicht....
## [{(ReadingsVal("$SELF","AlarmDevice","").":\"closed\"")}]
( ReadingsVal(ReadingsVal("$SELF", "AlarmDevice", ""), "window", "") eq "closed" ? 1 : 0)
and
[$SELF:state] eq "ALARM"
) ## or
)
(
setreading $SELF scharf 1,
{Log3("$SELF",3,"$SELF: cmd 2: ein")}
)

## cmd 3: ausgelöst
DOELSEIF([$SELF:scharf,1] == 1
and
## über alle Räume
["^.._Thermostat:measured"]
and
[$DEVICE:measured-temp,15] < AttrVal("ThermostatControl","limit-low-temp",15)
and
[$DEVICE:window] eq "open"
## beim Thermostat gibt es ein reading, welches den Fensterstatus anzeigt
) ## if

(
## Fenster von Raum merken, damit beim Schliessen der Alarm zurückgesetzt werden kann - cmd 2 
setreading $SELF AlarmDevice $DEVICE,
{(DoSet("Monitor","ID:FensterOffen",
GetRoom("$DEVICE"),
[$DEVICE:measured-temp,15],
AttrVal("ThermostatControl","limit-low-temp",15)))},
## in Monitor enthalten:
## {AI_CallIntern("$SELF","$DEVICE","$EVENT","Alarm innen wurde ausgelöst")},
{Log3("$SELF",2,"$SELF: cmd 3: ausgelöst d: $DEVICE e: $EVENT t: [$DEVICE:measured-temp] w: [$DEVICE:window] ".GetRoom("$DEVICE"))}
)
Vielleicht habe ich da auch etwas übersehen und es gibt eine elegantere Lösung?

cmd1 und cmd2 sind mit einem Ikon verknüpft, über den ich das DOIF für die Überwachung "scharf" schalten kann.

Gruß

Elektrolurch



configDB und Windows befreite Zone!

Damian

Du kannst innerhalb der Anweisungen statt mit wait mit FHEM-SLEEP arbeiten. Zu bedenken ist allerdings, dass SLEEP nicht automatisch abbricht, wenn sich eine Bedingung ändert, wie es das Attribut wait macht.

Im DOIF-Perlmodus gibt´s z. B. das Attribut wait nicht, dort werden Verzögerungen direkt im Code mit set_Exec() programmiert, welches mit Wiederholungen und Abbruchbedingungen ziemlich mächtig ist.

Es gibt viele Möglichkeit und alle haben irgendwo ihre Vor- und Nachteile.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Elektrolurch

Danke für die rasche Antwort.
- Den "Komfort", dass der timer abgebrochen wird, wenn sich die Bedingungen ändern, nutze ich sehr häufig, daher kommt "FHEM-SLEEP"   statt wait für mich nicht in Frage, auch habe ich bis jetzt den perl-Modus nicht verwendet.
Die Frage war ja, ob man die "wait" - Anweisung nicht alternativ auch direkt im Ausführungsteil angeben könnte, so als Verbesserungsvorschlag gemeint, weil damit der Ablauf meiner Meinung nach deutlich übersichtlicher würde.
Ich hatte gerade den Fall, dass ich meine Steckdosen zur Strommessung an Waschmaschine und Trockner für eine Signalisierung für "fertig" von DECT200 auf zigbee umgestellt hatte und daher 2 Bedingungen im DOIF überflüssig geworden sind und natürlich hatte ich vergessen, das  entsprechende wait anzupassen... und schon war die Waschmaschine immer 2 x Mal hintereinander "fertig", obwohl ich sie nicht erneut gestartet hatte.
Und der 2. Vorschlag bezieht sich darauf, dass man zwar für Zeitwerte in Konditionen ein reading oder auch einen perl-Ausdruck angeben kann, aber leider nur für Zeitwerte und nicht für andere logische Operationen.

Gruß

Elekttrolurch
configDB und Windows befreite Zone!

Damian

1) DOIF hat keine eigenen Befehle, d. h. das was im Ausführungsteil angegeben wird, wird an FHEM-Parser weitergegeben und dort ausgewertet und ausgeführt.

Wait als ein eigener DOIF-Befehl würde also größere Umbauten im DOIF bedeuten.

Dazu ist mir der Aufwand zu groß, zumal man keine neue Funktionalität erhalten würde.


2) Man kann beliebige logische Operationen in DOIF-Readings einbauen, die man in der DOIF-Bedingung abfragen kann.


Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Das mit wait im jeweiligen Zweig klingt im ersten Moment gut, aber wenn dann noch die anderen Attribute, welche pro Zweig konfigurierbar sind, dazu kämen, wäre es wiederum sehr unübersichtlich.
Wenn fände ich eine Vereinheitlichung der Syntax wichtiger, Komma, Semikolon, Doppelpunkt, was man nicht ständig braucht, muss man (ich!) immer nachschauen.