Hallo,
ich habe ein at erstellt, dass die nachfolgende Struktur besitztdefmod at_Licht_Esstisch at +*00:00:15 {\
my $dev = "wz_Esstisch_RGB_Lampe";;\
my $val = Value($dev);;\
if ($val ne "Aus"){\
fhem ("get $dev swmStatus");;\
Log3 undef, 3, "1. Schleife at_RGB hat den Wert für \$val $val Status des $dev";;\
}\
else{\
fhem ("set at_Licht_Esstisch inactive");;\
Log3 undef, 3, "1. Schleife else at_RGB hat den Wert für \$val $val Status des $dev";;\
fhem ("set nt_Licht_Esstisch active")\
}\
my $ack = ReadingsVal ($dev,"transmit","FEHLER");;\
Log3 undef, 3, "Nach 1. Schleife hat at_RGB den Wert für \$ack $ack";;\
if ($ack eq "NO_ACK"){\
Log3 undef, 3, "2. Schleife at_RGB hat den Wert für \$val $val Status des $dev \nund für \$ack $ack";;\
fhem ("set $dev $val;;;;sleep 20");;\
$ack = ReadingsVal ($dev,"transmit","Fehler");;\
Log3 undef, 3, "2. Schleife at_RGB hat beim erneuten Auslesen von \$ack den Wert $ack";;\
if ($ack eq "NO_ACK"){\
Log3 undef, 3, "3. Schleife (in 2. Schleife) at_RGB hat den Wert für \$ack $ack \nLicht wird ausgeschaltet\n und at aus";;\
fhem ("set $dev Aus");;\
fhem ("set at_Licht_Esstisch inactive");;\
fhem ("set nt_Licht_Esstisch active")\
}\
\
} \
}
An dieser Stelle if ($ack eq "NO_ACK"){\
Log3 undef, 3, "2. Schleife at_RGB hat den Wert für \$val $val Status des $dev \nund für \$ack $ack";;\
fhem ("set $dev $val;;;;sleep 20");;\
$ack = ReadingsVal ($dev,"transmit","Fehler");;\
(also nach dem Log3) würde ich sehr gerne das at für 20 Sekunden pausieren und danach die Wertzuweisung $ack vornehmen. Leider finde ich keinen geeigneten Weg. Wenn ich sleep 20 -also ohne FHEM- nutze, steht, wie überall beschrieben das gesamte System. Das Verhalten ist aber komplett unerwünscht. Ich will lediglich das at einfrieren und nach 20 Sekunden fortsetzen.
Wie müsste das korrekt aussehen oder gibt es evtl Alternativen?
Gruß
Ich verstehe zwar nicht was Du genau dort machst, aber wenn ich richtig vermute, möchtest Du auf Ausnahmesituationen reagieren, wenn Befehle vom Device nicht korrekt angenommen werden?
Mir fallen spontan 2 Ansätze ein, die hier helfen könnten
- Umstellung auf DOIF, dort gibt es auch zeitgesteuerte Abarbeitung wie at und mit dem Attribut wait kann man in Befehlsfolgen pausen einbauen
- Verwendung eines separaten notifies, der auf das noack reagiert (und auch nur aktiviert werden könnte, wenn Du es gerade brauchst)
Eine weitere Lösung wäre den Teil, den Du nach 20 sekunden erst abarbeiten willst wiederum in ein (anonymes) at einzupacken, aber wenn ich es richtig verstehe soll ja die ganze Befehlsabarbeitung angehalten werden?
DU könntest natürlich auch im at einen zusätzlichen Status setzen, so dass Du bei der nächsten Ausführung (nach 15sek) in den Fall verzweigst, der den noack behandelt wenn nötig und dann erst beim übernächsten Mal normal weiterläuft
1. www.if-schleife.de
2. ich hab ehrlich gesagt nicht verstanden was du machen willst bzw. "abfangen" willst mit einer 20sec pause in einem at was alle 15sec aufgerufen wird. ::)
beschreib doch mal bitte etwas genauer was du überhaupt vorhast...
Hi,
danke für eure Ausführungen. Ich versuche das Problem zunächst zu skizzieren, habe aber schon eine Lösung gefunden, die ich nutzen kann.
Problem
Ich habe eine RGB-ZWave Lampe, die ich über FHEM steuern kann. Wenn aber jemand den Strom am Lichtschalter ausschaltet, dann kennt FHEM den Status der Lampe nicht und glaubt die Lampe wäre noch an. Und es kommt leider sehr oft vor, dass die RGB-Lampe am Lichtschalter ausgeschaltet wird. Da ZWave im Reading transmit die Werte ACK bzw. NO_ACK speichert, wollte ich darauf eine Abfrage erstellen um das virtuelle Device dem tatsächlichen Schaltzustand anzupassen.
Beim Einschalten tritt ein ähnliches Problem auf (transmit Reading wird nicht schnell genug aktualisiert).
Ich hoffe die Problemstellung ist somit klar und verständlich.
Meine Lösung sieht jetzt wie folgt aus:
Notify, welches an Lampe "lauscht" ;-)
define nt_Licht_Esstisch notify wz_Esstisch_RGB_Lampe:.* {
if (Value("wz_Esstisch_RGB_Lampe") ne "Aus"){
if (Value("at_Licht_Esstisch") eq "inactive"){
fhem("set at_Licht_Esstisch active");
fhem("set nt_Licht_Esstisch inactive");
}
}
}
At, was bei eingeschalteter Lampe regelmäßig einen Status bei der Lampe abfragt um so ein transmit ACK bzw NO_ACK zu erhalten:
define at_Licht_Esstisch at +*00:00:20 {\
my $dev = "wz_Esstisch_RGB_Lampe";;\
my $val = Value($dev);;\
if ($val ne "Aus"){\
fhem ("get $dev swmStatus");;\
my $ack = ReadingsVal ($dev,"transmit","NO_ACK");;\
if ($ack eq "NO_ACK"){\
Log3 undef, 3, "2. Schleife at_RGB hat den Wert für \$val $val Status des $dev \nund für \$ack $ack";;\
fhem ("get $dev swmStatus");;\
fhem ('define at_Licht_Esstisch_temp at +00:00:15 {\
my $dev = "wz_Esstisch_RGB_Lampe";;;;\
my $ack = ReadingsVal($dev,"transmit","NO_ACK");;;;\
Log3 undef, 3, "Temp_at_RGB hat für das $dev den Wert \$ack $ack";;;;\
if ( $ack eq "NO_ACK") {fhem("set $dev Aus")}\
};; attr at_Licht_Esstisch_temp room ADummy;; attr at_Licht_Esstisch_temp group Helfer')\
} \
}\
else{\
fhem ("set at_Licht_Esstisch inactive");;\
Log3 undef, 3, "1. Schleife else at_RGB hat den Wert für \$val $val Status des $dev";;\
fhem ("set nt_Licht_Esstisch active")\
}\
}
So funktioniert das ganze jetzt in meinem Sinne. Das at prüft u.a. das Reading transmit und erstellt bei dem Wert NO_ACK ein temporäres at was nach 15 Sekunden abermals den Wert transmit überprüft. Sollte der Wert noch NO_ACK sein, so wird die virtuelle Lampe ausgeschaltet. In der Folge das Notify wieder aktiviert und das (o.g.) at deaktiviert.
Ich weiß natürlich nicht, ob die Ausführung so elegant bzw. die Ideen richtig sind.
Ergänzend hierzu die Frage, kann ich das erste at (at_Licht_Esstisch) in das Notify einbauen? Mir ist es leider mit Verdopplung von '' bzw. \' nicht gelungen. Der Code wird nicht sauber abgearbeitet
@nils: Das mit dem sleep und den Zeiten war aus meiner Testreihe und machte so überhaupt keinen Sinn :P. Funktionierte auch nie ;D
@viegener:
Zitat von: viegener am 13 Oktober 2017, 12:04:47
Eine weitere Lösung wäre den Teil, den Du nach 20 sekunden erst abarbeiten willst wiederum in ein (anonymes) at einzupacken, aber wenn ich es richtig verstehe soll ja die ganze Befehlsabarbeitung angehalten werden?
Die Idee scheint mit meiner Umsetzung übereinzustimmen.
Zitat von: Mundus am 14 Oktober 2017, 15:29:57
@viegener: Die Idee scheint mit meiner Umsetzung übereinzustimmen.
Ja im wesentlichen schon, hier bekommst Du nur ein Problem, wenn das at schon existiert, aber das sollte bei den eingestellten Intervallen eher nicht passieren.
Ich würde das Konstrukt wohl nicht so bauen, aber wenn es funktioniert absolut in Ordnung.
Zitat von: viegener am 14 Oktober 2017, 16:03:26
Ja im wesentlichen schon, hier bekommst Du nur ein Problem, wenn das at schon existiert, aber das sollte bei den eingestellten Intervallen eher nicht passieren.
wenn ein at schon existiert, wird es doch lediglich nicht erneut angelegt, oder? (Meine bisherigen Beobachtungen waren zumindest so). Den Fall, der vermutlich nicht auftreten wird, halte ich für tolerabel.
Zitat von: viegener am 14 Oktober 2017, 16:03:26
Ich würde das Konstrukt wohl nicht so bauen, aber wenn es funktioniert absolut in Ordnung.
Was wäre deine Wahl?
Gruß
Nein, es kommt dann normalerweise die Meldung:
Zitat... already defined, delete it first
Schau Dir mal den Befehl defmod an
Hi, vielen Dank. Das Problem ist für mich gelöst. Defmod habe ich mir angeschaut, inweit ich den EInbau werde ich prüfen.
Gruß und Danke