Ein eigentlich simples Thema, das mit Sicherheit schon häufig behandelt wurde, aber ich finde im Forum keine Lösung:
Mit at kann man zufällige Schaltzeiten in Verbindung mit Sonnenauf- und -untergang definieren.
define Lampe_abends_AN at *{sunset(+1500+int(rand(600)))} set Lampe on
schaltet die Lampe täglich 1500 Sekunden nach Sonnenuntergang zufällig innerhalb von 600 Sekunden ein. OK, das funktioniert.
Wenn ich nun die Lampe unabhängig vom Sonnenlauf täglich ab einer bestimmten Zeit (hier 8:00 Uhr) zufällig wieder ausschalten möchte, würde ich das mit versuchen mit
define Lampe_morgens_AUS at *{08:00:00+int(rand(600))} set Lampe off
Das funktioniert aber leider nicht. FHEM meldet:
the function "08:00:00+int(rand(600))" must return a timespec and not Illegal octal digit '8' at (eval 114122) line 1, at end of line
syntax error at (eval 114122) line 1, near "08:"
.
Auch ohne Perlcode mit
define Lampe_morgens_AUS at *08:00:00+int(rand(600)) set Lampe off
funktioniert es leider nicht. FHEM meldet:
Wrong timespec 08:00:00+int(rand(600)): either HH:MM:SS or {perlcode}
Dass man so etwas mit DOIF eleganter lösen kann, ist mir bekannt. Ich würde aber gerne beim at bleiben und kann mir aber kaum vorstellen, dass der "Erfinder" des at nicht auch an diesen Fall gedacht hat.
Was mache ich hier falsch? Wo steckt der Syntaxfehler? Gibt es eine einfache Lösung?
Hi,
die "einfache" Lösung steckt hier: https://wiki.fhem.de/wiki/Zeitangaben,_rechnen_mit
Dahinter steckt, das Du eine Zeitangabe brauchst, sunset macht das für Dich bei diesem Syntax.
Eine einfache Variante wäre aber auch: https://fhem.de/commandref_modular.html#sleep
define Lampe_morgens_AUS at *08:00:00 sleep 5;;set Lampe off
Funktioniert so direkt nicht mit einer Perlfunktion.
So funktioniert es:
define Lampe_morgens_AUS at *08:00:00 {my $val=int(rand(600));;fhem("sleep $val;;set Lampe off")}
Gruß Otto
Für zufälliges Ausschalten innerhalb eines definierten Zeitraums per at nutze ich eine Uraltlösung (https://forum.fhem.de/index.php?topic=9754.0).
In der 99_myUtils.pm eine Sub eintragen
######## TimeRnd Zeit Zufall von bis ##########
# Aufrufbeschreibung: TimeRnd("vzeit","bzeit")
# vzeit = Startzeitpunkt zB. "07:00:00" oder "07:00"
# bzeit = Endzeitpunkt zB. "07:10:00" oder "07:10"
# TimeRnd = keine 24 Stunden aufaddiert
#
sub TimeRnd($$) {
my ($h1,$m1,$s1) = split(":", shift);
my ($h2,$m2,$s2) = split(":", shift);
$s1 = 0 if(!$s1);
$s2 = 0 if(!$s2);
my $t1 = 3600*$h1+60*$m1+$s1;
my $t2 = 3600*$h2+60*$m2+$s2;
my $er = int(rand($t2-$t1)+$t1);
return sprintf("%02d:%02d:%02d", $er/3600, ($er/60)%60, $er%60) if($s1);
return sprintf("%02d:%02d", $er/3600, ($er/60)%60);
}
Für das zufällige Ausschalten (hier zwischen 23:10:00 und 23:59:59 ein at, etwa
define Licht_Twilight_aus at *{TimeRnd("23:10:00","23:59:59")} {
if (ReadingsVal("LED","state",0) eq "on")
{fhem ("set Licht off")}
}
LED ist eine einzelne Lampe, Licht eine Structure. Den Code muss ich mal bereinigen, das geht eleganter per Filter.
Sind dann eben 2 at, eines für das Einschalten über sunset oder in deinem Fall sunrise und ein anderes für das Ausschalten per Zufallstimer.
Wenn man Ein- und Ausschalten in ein Device packen will, schlucken auch sowohl WeekdayTimer wie RandomTimer diese Perlfunktionen von Brice als Zeitangaben. RandomTimer würde dann dazwischen noch (zufällig) Ein- und Ausschalten, wenn man es noch zufälliger haben will (ggf. ergänzt mit einer disable-Bedingung, so dass das z.B. automatisch nur abläuft, wenn man weg ist und ggf. endet, wenn man dazwischen wiederkommt)...
Das ist jetzt ein wenig zu hoch für mich, da komme ich nicht mit 8)
Ok, jetzt doch, es geht um das Ausschalten morgens. Mein Beispiel bezog sich auf das Ausschalten am Abend, und da ist mir mit dem WeekdayTimer nicht geholfen.
Hier läuft es z.B. so, dass das Licht Abends eingeschaltet wird, früher per twilight und jetzt per Lichtsensor der Wetterstation. Ausgeschaltet wird dann wenn der Fernseher vom Netz geht per on-for-timer x Sekunden. Ist immer eine andere Zeit, da ich nicht jeden Abend nach den Tagesthemen ins Bett gehe :).
Für den Fall, dass keiner Zuhause ist, geht das Licht an. Und muss irgendwann wieder ausgeschaltet werden, und zwar nicht zu einem immer gleichen Zeitpunkt. Mit dem WeekdayTimer würde ich eventuell im Dunkeln sitzen.
Klar, WeekdayTimer macht tendenziell immer zur selben Zeit aus bzw. berechnet die Ausschaltzeit einmalig zu Tagesbeginn (geht zwar neuerdings auch anders, aber das ist dann nicht einfacher, als mit einem notify ein neues at zu definieren oä.; eine andere Option ist, dort eine disableCondition zu hinterlegen wie "schalte nicht, solange der Fernseher läuft", das wird dann jede Minute geprüft...).
RandomTimer bildet eher den Fall ab, dass keiner zuhause ist, und auch der kann wie geschrieben nicht nur mit festen Zeiten, sondern auch mit zufälligen Perl-Zeitergebnissen umgehen (berechnet das aber auch zu Tagesbeginn). Solange man weg ist, kann man den RT auch weiterlaufen lassen, der schaltet dann auch wieder aus (wieder ggf. mit einer zu Tagesbeginn berechneten Endezeit).
Beim RT kann man (neuerdings) auch einstellen, was passieren soll, wenn man dazwischen heimkommt. Läßt man alles "as is", muß man dann halt selbst dafür sorgen, dass am Ende/zum richtigen Zeitpunkt alles aus ist, was aus sein soll.
Danke euch allen für die schnellen Antworten.
Meine einfache Frage hat (zumindest für mich) zu recht komplizierten Antworten geführt. Auf den ersten Blick gefällt mir die Lösung von Otto mit "sleep" am besten, weil sie so einfach aussieht. Ich werde das ´mal testen.
Eigentlich wollte ich nur meiner Lampe, die mit einem simplen "... at *08:00:00 set Lampe off" jeden morgen um Punkt 8 Uhr ausschaltet, innerhalb einiger Minuten nach 8 Uhr etwas Zufälligkeit verpassen. Nicht mehr und nicht weniger.
Ich hatte nicht damit gerechnet, dass ich so tief in die Materie einsteigen muss.
WeekdayTimer und RandomTimer kenne ich einigermaßen. Trotzdem wollte ich in diesem Fall beim "at" bleiben und hatte gehofft, dass ich nur einen Syntaxfehler in meiner define-Zeile habe. So einfach scheint es aber nicht zu sein.
Grüße aus Hessen von Gundermann
In der commandref steht auch:
ZitatNote: a sleep not followed by any command will block FHEM, is deprecated, and it issues a WARNING in the FHEM log.
Ich würde sleep nur dann verwenden, wenn mir absolut klar wäre, welche Auswirkungen es noch haben könnte. Da ich das nicht kann, lasse ich die Finger von solch einer Lösung, just my 2 cent.
Viele Grüße Gisbert
Es ist aber followed... Und ein FHEM-sleep, kein Perl-sleep. Die Perl-Varinte sollte man wirklich vermeiden, aber wie gesagt, das ist hier nicht das Thema...
wenn du keine andere lösung findest könntest du es auch mit einem MSwitch lösen, dort ist es letztendlich ein zweizeiler ( anhang ) .
gruss Byte09
Ich werde mich wohl von dem Gedanken verabschieden müssen, mit einem einfachen! "at" eine Lampe unabhängig vom Sonnenlauf zufällig zu schalten (egal ob morgens oder abends, vor oder nach den Tagesthemen, ob ich schlafe oder wach bin, zu Hause oder unterwegs ;)). Schade, dann eben mit DOIF oder RandomTimer.
Gruße aus Hessen von Gundermann
Zitat von: Gundermann am 03 Dezember 2019, 21:28:21
Ich werde mich wohl von dem Gedanken verabschieden müssen, mit einem einfachen! "at" eine Lampe unabhängig vom Sonnenlauf zufällig zu schalten (egal ob morgens oder abends, vor oder nach den Tagesthemen, ob ich schlafe oder wach bin, zu Hause oder unterwegs ;)). Schade, dann eben mit DOIF oder RandomTimer.
Gruße aus Hessen von Gundermann
Ich sehe das nicht als Nachteil. Es gibt inzwischen viele Module, die auf Zeitsteuerung spezialisiert sind. Es mag sein, dass at zur Grundausstattung gehört, aber es ist nicht der Normalfall, dass man eine Lampe nur einschalten will, meistens will man sie auch ausschalten und das nicht nur manuell. Hinzukommt, dass man eine Fallunterscheidung haben will Wochenende, Wochentage, Arbeitstage, Feiertage usw. All das kannst du sicherlich mit at realisieren, allerdings nicht mit einem. Dann kannst du dir auch gleich überlegen wie du dann deine at´s strukturierst, um den Überblick in deinem System zu behalten ;)
Zitat von: Gisbert am 03 Dezember 2019, 19:07:08
In der commandref steht auch:
Ich würde sleep nur dann verwenden, wenn mir absolut klar wäre, welche Auswirkungen es noch haben könnte. Da ich das nicht kann, lasse ich die Finger von solch einer Lösung, just my 2 cent.
Viele Grüße Gisbert
Steht doch aber klar :) sleep; Befehl ist simpel und funktioniert.
Warum wird eine einfache Lösung die auch noch exakt in der Doku beschrieben ist dermaßen zerredet?
BTW: ein FHEM sleep erzeugt ein relatives at mit dem Befehl dahinter im Ausführungsteil, nichts weiter. Da ist keine Magie, kein Modul, keine Eventualität.
Gruß Otto
@ Damian: Volle Zustimmung zu deinem Beitrag.
Trotz gewisser Vorbehalte habe ich mich in diesem speziellen Fall mit der sleep-Lösung von Otto noch einmal beschäftigt und sie (natürlich mit anderen Zeitwerten) getestet. Es geht mir mehr ums Experimentieren als um eine wirklich sinnvolle Anwendung. FHEM weckt eben auch den "Spieltrieb" ;)
Wenn ich define Lampe_morgens_AUS at *08:00:00 sleep {(int(rand(600)))};;set Lampe off in die Kommandozeile von FHEM eingebe wird das at erwartungsgemäß angelegt, allerdings fehlt jetzt in der Detailansicht das zweite Semikolon vor dem set (das ist mir eher zufällig aufgefallen). In der fhem.cfg ist das zweite Semikolon sichtbar. Aber die Lampe schaltet nicht. Weder um 8 Uhr noch in den 10 Minuten danach. Keine Meldung im Event monitor, kein Eintrag im Logfile. Natürlich habe ich die Lampe (eine IT-Funksteckdose, die mit einem "normalen" at tadellos funktioniert) vorher eingeschaltet.
Jetzt habe ich das fehlende Semikolon in der Detailansicht nachgetragen. Die Lampe schaltet noch immer nicht. Keine Meldung im Event monitor, jedoch im Logfile pünktlich (im Beispiel 08:00:00 Uhr) "Lampe_morgens_AUS: Last parameter must be quiet". Wer oder was bitte soll jetzt leise sein?
Grüße aus Hessen von Gundermann
Auf dieses Problem wirst du öfters stoßen. Es ist der FHEM-Syntax geschuldet - sie kennt keine Klammerhierarchie. Merke: In der Detailansicht ein Semikolon entspricht zwei in der Kommandozeile bzw. zwei in der cfg-Datei.
Hallo Gundermann,
das mit den Basics FHEM hat Damian ja schon erklärt, auch das findet man natürlich in der Doku. https://fhem.de/commandref_modular.html#command
Der Befehl sleep 5;; Befehl funktioniert wie dokumentiert. Mein Fehler: die Zahl aus einer Perlfunktion zu erzeugen, das funktioniert nicht. Wer liest ist klar im Vorteil: In der Doku steht sleep {Perlfunc} muss wieder einen TimeSpec zurückliefern und nicht eine Zahl in Sekunden.
Damit war meine Idee falsch. Es bleibt nur die Errechnung der Zeit als TimeSpec.
Tut mir leid.
Oder man macht alles in Perl. Ich habe meinen Beitrag #1 entsprechend richtig gestellt und ein Beispiel mit Perl Code eingestellt.
Man kann den Perlcode auch so direkt ohne at in der FHEM Kommandozeile testen.
{my $val=int(rand(600));;fhem("sleep $val;;set LichtWzLO on")}
Gruß Otto
Hallo Otto,
ZitatSteht doch aber klar :) sleep; Befehl ist simpel und funktioniert.
Warum wird eine einfache Lösung die auch noch exakt in der Doku beschrieben ist dermaßen zerredet?
Das war wohl ein Fehlschluss von mir, und in meinem Kleinhirn hat sich die Benutzung von Perl sleep als u.U. gefährlich verankert. Dass derselbe Befehl in Fhem sinnvoll angewendet werden kann, hab ich nicht vermutet, sorry :-X
Viele Grüße Gisbert
Um die Sache mit timespec und Zufallsberechnung noch abzurunden:
So erhält man das geforderte Format der aktuellen Zeit + 5 sec.
{(strftime("%H:%M:%S",localtime(time+5)))}
somit bekommt man damit eine zufällige Zeit in der Zukunft für die Verwendung mit at
{(strftime("%H:%M:%S",localtime(time+int(rand(600)))))}
Für die Verwendung in sleep müsste man es so machen (FHEM Kommandozeile):
sleep {(strftime("%H:%M:%S",gmtime(int(rand(20)))))};set LichtWzLO off
Hab ich jetzt mehr Verwirrung gestiftet als geholfen? :)
Doku zum nachlesen: https://perldoc.perl.org/functions/localtime.html
@ Otto123:
ZitatHab ich jetzt mehr Verwirrung gestiftet als geholfen?
Irgendwie schon.
Du merkst sicher, dass mir einiges an Grundwissen fehlt. Da habe ich noch Nachholbedarf und lebe deshalb bei irgendwelchen Problemen meist von konkreten Beispielen aus dem Forum oder sonstigen Quellen (nicht selten auch von Otto123 ;)), die ich dann anpasse.
Deshalb bitte noch einmal "zurück auf Anfang":
define Lampe_morgens_AUS at *08:00:00 sleep {(int(rand(600)))};;set Lampe off funktioniert also nicht, weil die Zahl aus einer Perlfunktion erzeugt wird. OK.
Wie müsste denn nun die Zeile korrekt lauten, die in die FHEM-Kommandozeile einzugeben ist, damit täglich z.B. zwischen 8:00 und 08:10 meine Lampe zufällig schaltet?
Was bitte meinst du mit deinem
Beitrag #1?
Übrigens: {my $val=int(rand(600));;fhem("sleep $val;;set Lampe off")} in die Kommandozeile eingegeben schaltet die Lampe zufällig innerhalb von 10 Minuten. Jetzt muss sie das nur noch täglich ab einer gewünschten Uhrzeit tun.
Sorry, wenn ich nerve und immer noch "auf dem Schlauch stehe".
Grüße aus Hessen von Gundermann
Zitat von: Otto123 am 03 Dezember 2019, 13:36:06
....
So funktioniert es:
define Lampe_morgens_AUS at *08:00:00 {my $val=int(rand(600));;fhem("sleep $val;;set Lampe off")}
Was ist damit?
ZitatWas ist damit?
Sorry, das hatte ich bei der Vielzahl der Infos übersehen. Gerade getestet und scheint zu funktionieren.
Danke an alle, die sich beteiligt haben, für das rege Interesse.
Grüße aus Hessen von Gundermann
Zitat von: Gundermann am 04 Dezember 2019, 15:01:10
Was bitte meinst du mit deinem Beitrag #1?
Schau doch mal in die Kopfzeilen der Beiträge - Beispiel ;)
« Antwort
#18 am: Heute um 15:01:10 »
Zitat von: Gundermann am 04 Dezember 2019, 15:01:10
@ Otto123:
Irgendwie schon.
Naja ich habe versucht es umfangreich zu beschreiben. Lies alles in Ruhe durch, probiere alles aus (in der Kommandozeile) schau parallel immer in die Doku (FHEM commandref) und in die Perl Doku.
Das wird schon mit der Zeit :)
Gruß Otto
Danke nochmal an alle. Jetzt habe ich mein "at", das zufällig unabhängig vom Sonnenlauf schaltet.
@ Otto123: Ich hoffe, dass ich dir nicht zu sehr auf die Nerven gegangen bin und gelobe Besserung.
@ Byte09: MSwitch könnte die "eierlegende Wollmilchsau" für mich werden. Ich werde mich damit beschäftigen.
@ Beta-User, Damian, Brice, Gisbert, rabehd: Danke für die Unterstützung.
Ich denke das Thema kann jetzt geschlossen werden.