Hi all,
um eine Anwesenheitssimulation etwas Abwechslungsreicher zu gestallten suche ich noch nach einer Funktion, die zufällig (Pseudozufall reicht) den Wert 0/1 oder irgendwelche Wertefelder die ich mit "<" ">" leicht auswerten kann liefert.
Ziel ist es Licht ab xy Uhr anzumachen, aber nicht JEDEN Tag.
Vorschläge?
Da ich bisher DOIF nicht verwende (arbeite viel mit perl-if Konstrukten), sind Vorschläge die ohne DOIF auskommen für mich aktuell schneller zu verwenden.
Da könnte die Funktion rand helfen.
Danke, aber ... könntest du 3 Sätze spezifischer sein? Welche Funktion? perl?
Ich kenne auch den FHEM-Befehl "RandomTimer", der aber nicht ganz das macht was ich haben will (wenn ich die realtiv kryptisch gehaltene commandRef überhaupt richtig verstehe)
Wie wär's mit suchen gewesen? ;)
Z.B. rand perl -> https://perldoc.perl.org/functions/rand
Gibt bestimmt noch mehr/bessere/andere Treffer...
Gruß, Joachim
Ja, die Standardantwort im Forum: "Schön das du fragst, such selber." Immer gern genommen und ermutigend. ;D
Im Ernst:
Ich wusste ja nicht, ob perl gemeint ist, ich hatte eben die Idee, dass es was einfacheres gibt, irgendeine Helfermodul oder FHEM Attribut oder so, dass ich übersehen habe.
Trotzdem Danke, dann werde ich mal die nächsten 12 Stunden probieren, dass irgendwie hinzubekommen. Wid bestimmt ganz leicht, wenn man bedenkt, dass ich der perl-loser bin und froh, dass ich gerade mal die if/elsif Konstrukte hinbekomme. :D
Wusste ich auch nicht...
...also dass es perl ist. ;)
Aber vermutet (wie du)...
...und halt einfach mal probiert -> geklappt :)
Und nein nicht Standard-Antwort aber ein wenig Eigeninitiative darf man schon erwarten, wenn doch schon ein Hinweis gegeben wurde...
Viel Erfolg, Joachim
Hm, schon mal hier nachgeschaut: https://wiki.fhem.de/wiki/Anwesenheitssimulation
Grüße Jörg
Ups, bei Gelegenheit müßte die Seite ggf. mal aktualisiert werden (über Pi kann man noch streiten, aber CUL, IT...?!? sind nicht mehr auf der Höhe der Zeit, und es ist zumindest mir auch überhaupt nicht klar, warum dazu überhaupt an der Stelle was steht),
Zitat von: Zrrronggg! am 25 Oktober 2020, 20:05:49
Ich kenne auch den FHEM-Befehl "RandomTimer", der aber nicht ganz das macht was ich haben will (wenn ich die realtiv kryptisch gehaltene commandRef überhaupt richtig verstehe)
Du darfst gerne Verbesserungsvorschläge zur cref machen. Grundsätzlich sollte aber auch der RandomTimer das können, was du erreichen willst.
Entweder eine rand-Funktion in disableCond einbauen (dann wird der RandomTimer ggf. am Tagesanfang für diesen ganzen Tag deaktiviert, falls ihn niemand nochmal versucht zu aktivieren), oder eben die Einschalt-Wahrscheinlichkeit passend verringern und die Einschaltdauer entsprechend lange wählen, dass wirklich nur 1x geschaltet werden kann.
Grundsätzlich kann man via RT m.E. eigentlich alles "verzufallen": Das "ob" überhaupt für den fraglichen Tag (s.o.), die Einschalt- und Ausschalt-Wahrscheinlichkeiten (switchmode) getrennt für ein und aus, die erste Einschaltzeit sowie die (minimale) Einschaltdauer (variations iVm. timeToSwitch).
Meine Empfehlung wäre, einfach mal einen dummy und einen RT zusammenzuschalten und dann beide in ein logfile zu packen. Dann siehst du ggf., welche Einstellmöglichkeit (in etwa, es ist zufällig...) welche Auswirkung hat...
Falls Wünsche offenbleiben: Gerne melden ;) .
Ja, danke. Ich habe ehrlich gesagt den ganze Commandref zu RandomTimer nur halb verstanden. Ich versuche mal zu erläutern warum:
So wie ich die commandref lesen ist das in erster Linie ein Timer. Mir ist aber unklar wie der sich im Detail verhält.
Man gibt einen Zeitpunkt an, dann wird eingeschaltet, und das gegebenenfalls mehrmals, und nach Zeit t wird nicht mehr eingeschaltet (schon das nach Zeit t im Normafall ausgeschaltet wird, geht für mich zunächst aus der Beschreibung nicht hervor, steht erst reicht weit unten bei den Atributes). Das lässt sich idR. alles mit einem recht übersichtlich normalen defines auch machen, insbesondere wenn der Aktor "for Timer" beherrscht. Daher hatte ich schon nicht verstanden - mal abgesehen von der 10% Varianz - welches Problem das Modul löst.
Konkret
"Every (timeToSwitch seconds +-10%) it trys to switch device on/off. The switching period stops when the next time to switch is greater than timespec_stop."
Was genau meint insbesondere
Zitatswitch device on/off
?
Toggle alle 500 Sekunden? Alle 500 Sekunden: Switch off if on and on if off?
Switch on alle 500 Sekunden und off am Ende des Timers?
Und wieso "trys" ? Das Modul
versucht zu schalten?
Z.B. folgendes Beispiel in der CommandRef:
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500
Zitatdefines a timer that starts at sunset an ends 3 hous later. The timer trys to switch every 500 seconds(+-10%).
Soll den Aktor ab Sonnenuntergang bis 3 Stunden danach alle 500 Sekunden einschalten? (Und dann aus?)
Oder meint das, dass die Lampe 500 Sekunden an ist und dann 500 Sekunden aus und dann wieder 500 Sekunden an?
Was macht das Modul mit dem Beispiel konkret?
In jedem Fall könnten die Verhalten mit relativ simplen normalen define gelöst werden, insbesondere wenn der Aktor "on for timer" kann.
Gut, abgesehen von den 10% natürlich.
Kurzum: Ich kapier nicht ganz, was das Ding macht, aber habe den Verdacht, das liegt ggf an der Beschreibung, die ich nicht richtig verstehe oder die vielleicht auch unglücklich formuliert ist.
Interessant wird es sicher mit dem Parameter
Variations. Aber auch hier ist die Commandref ... irgendwie .. unklar.
"VAR_DURATION will turn timeToSwitch to a minimum value with some random seconds between zero and VAR_DURATION will be added."
Äh... was? Ich bin sicher, das meint irgendwie, dass timeToSwitch zu einem Intervall einer bestimmten Zeitdauer erweitert werden kann.
Aber irgendwie ist das komisch formuliert oder ... jedenfalls kapier ich es nicht; "will turn timeToSwitch to a minimum value"?
Der
minimum Value eines Parameters der eine Zeitdauer in Sekunden angibt ist 0. Das ist doch bestimmt nicht gemeint.
Meint das Ganze vielleicht schlicht:
"VAR_DURATION will add a random time period between zero and VAR_DURATION seconds to timeToSwitch"?
Ferner hat laut commandref das Modul diese Aufrufparamter:
define <name> RandomTimer <timespec_start> <device> <timespec_stop> <timeToSwitch>
Da kommt Variation" nicht vor, und später heisst es nur: syntax is [VAR_DURATION][:VAR_START]
Damit ist für mich schon nicht klar, wie die genaue Schreibeweise eines RandomTimer mit Variation sein muss.
Auch die Beispiel erhellen da nur bedingt.
Kurzum: Mir ist die genau Funktion und die Syntax nicht klar. Das magan mir liegen, aber ggf gibt es da trotzdem noch Potential in der Beschreibung.
Mein Ziel war
a) Bestimmte Lampen abends mit etwas Zeitversatz von sagen wir mal +/- 20 Minuten an und aus zu schalten. Ich verstehe, dass man das vermutlich dem RandomTimer hinbekommt - wenn ich die Syntax und genau Funktion mal verstanden habe.
Wichtiger aber noch:
b) nicht jeden Tag, sondern z.b. nur "jeden Tag mit der Wahrscheinlichkeit 1:3" (oder ähnlich, eigentlich "mit jeder Ausführung des Defines mit einer Wahrscheinlichkeit X). Das ginge wohl hilfsweise, indem man z.b. die VAR_START Zeiten länger macht als die normale Timerdauer. Vielleicht.
ZitatMeine Empfehlung wäre, einfach mal einen dummy und einen RT zusammenzuschalten und dann beide in ein logfile zu packen.
Ah, Funktionsforensik.
Ja, kann man machen. Mein Hoffnung war, das es jemand
weiß.Gerne mache ich Formulierungsvorschläge für die CommandRef, sobald ich mal verstanden habe, was das Modul genau macht und wie die richtige Syntax ist. Hab aber keine Ahnung wer Maintainer ist. Den Wikiartikel könnte ich sowieso ändern.
Zitat von: JoWiemann am 25 Oktober 2020, 21:19:57
Hm, schon mal hier nachgeschaut: https://wiki.fhem.de/wiki/Anwesenheitssimulation
Grüße Jörg
Klar. Da wird im Wesentlichen auf RandomTimer verwiesen, den ich schon nicht ganz kapiere (siehe mein Post oben) und der direkt keine Option für zufällige Tagesauswahl bietet.
Der Rest des Artikels ist auf dem Niveau: "Sie brauchen eine Lampe ..." ;D
Ich sag mal so: Etwas weiter bin ich schon. 8)
Etwas vereinfacht: Man gibt einen Zeitpunkt an, dann wird _vielleicht_ eingeschaltet. Nach Ablauf der ca.-Zeit wird _vielleicht_ wieder ausgeschaltet (oder _vielleicht_ ein, falls noch nicht eingeschaltet sein sollte). Usw. usf. Solange, bis eben der späteste Ausschaltzeitpunkt kommt, da wird dann sicher ausgeschaltet.
Das _vielleicht_ ist mit "try" gemeint. Es wird einfach immer ein neuer (variabler) Timer gesetzt, nach dessen Ablauf wieder ein Zufallswert ermittelt, anhand dem dann letztendlich entschieden wird, ob denn jetzt was passieren soll oder eben nicht. Danach wird der nächste Timer aktiviert.
Bisher war ich mit Eingriffen in die commandref eher sparsam unterwegs, aber das mit "variations" hätte ich im define schon erwähnen können, hole ich bei Gelegenheit nach.
Wie gesagt: am klarsten wird es, wenn man mitloggt und sich rückwärts betrachtet, was da eigentlich passiert ist...
Um mal zu versuchen, dein konkretes Problem zu lösen, nennen wir eine deiner fraglichen Lampen also SehtlampeTisch und bleiben bei dem Beispiel:
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500
Es wird also ab sunset_abs() "versucht", ob eingeschaltet werden soll. Das passiert mit einer Wahrscheinlichkeit von 80%. Alle 450-550 Sekunden wird dann erneut "versucht", irgendwas zu machen. War die Lampe nach Ablauf dieser 8-9 Minuten noch aus, wird sie dann mit derselben Wahrscheinlichkeit eingeschaltet, ist sie an, geht sie mit 20% Wahrscheinlichkeit aus... Usw., bis eben die 3h um sind. Es kann also durchaus passieren, dass die Lampe an einem Abend 10x an- und wieder ausgeht.
Du willst jetzt 3 Modifikationen an diesem Modell:
a) Es soll wenn, dann nur einmal eingeschaltet werden. Ergo muss die Dauer deutlich länger sein, um ganz sicher zu sein, müßte man es auf 3h+10% setzen, um da für Klarheit zu sorgen => 3*60*60*1,1
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 12000
b) Dann soll das ganze mit einer Wahrscheinlichkeit von 1:3 passieren, was "250" als Einschaltwahrscheinlichkeit entspricht:
attr ZufallsTimerTisch switchmode 250/200
c) zu guter Letzt soll es nicht genau zu sunset_abs() sein, sondern eben +/-20 Min drumrum. Da hast du jetzt mehrere Möglichkeiten: Entweder direkt den sunset_abs-Ausdruch "randomisieren:
{sunset_abs("CIVIL",int(rand(40*60))-20*60,"00:00","23:59")}
Oder eben den 20 Min offset angeben und dann den VAR_START setzen
define ZufallsTimerTisch RandomTimer *{sunset_abs("CIVIL",-20*60,"00:00","23:59")} StehlampeTisch +03:00:00 12000 :2400
Oder anders gelöst: Du könntest auch die Wahrscheinlichkeiten noch deutlich geringer setzen, dafür aber die kürzeren Zeitscheiben (in etwa) beibehalten und mit einer "Zeitscheiben"-dauer von 500-1500 arbeiten
define ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500 1000
attr ZufallsTimerTisch switchmode 20/50
Führt dazu, dass nur etwa jede 50. Zeitscheibe tatsächlich eingeschaltet wird, und wenn eingeschaltet ist, nur in jedem 20. Fall auch wieder irgendwann zwischendurch "vorzeitig" ausgeschaltet wird...
Jetzt klarer?
Wenn man hier im Forum nach "Zufallszeit" sucht, findet man eine ganze Menge Codeschnipsel, zu der Thematik.
Am interessantesten finde ich das hier:
https://forum.fhem.de/index.php/topic,95513.0.html
Zitat von: betateilchen am 26 Oktober 2020, 17:50:30
Wenn man hier im Forum nach "Zufallszeit" sucht, findet man eine ganze Menge Codeschnipsel, zu der Thematik.
Am interessantesten finde ich das hier:
https://forum.fhem.de/index.php/topic,95513.0.html (https://forum.fhem.de/index.php/topic,95513.0.html)
Ist auch ein interessanter Ansatz. Wenn es "nur" darum geht, einmalig "irgendwann" was einzuschalten, ist RT schon ein wenig "overdone" - wobei das eben auch geht...
Grundsätzlich hatte ich übrigens auch mal ähnliche Verständnisschwierigkeiten mit dem Modul wie der TE, und v.a. den Umstand fand ich irritierend, dass der Einschaltzeitpunkt relativ starr war. War dann Anlaß für das Ding mit "variations"...
Ein paar der heutigen Punkte habe ich mal versucht, etwas anders in der cref darzulegen, hoffe, das hilft...
@Beta-User:
Klärt sich ein wenig. Darf ich anmerken, dass ich schon auf
ZitatMan gibt einen Zeitpunkt an, dann wird _vielleicht_ eingeschaltet.
nach lesen der CommandRef nie gekommen wäre? Das mit "try" zu beschreiben ist ... äh ... eigenwillig.
Zitatdefine ZufallsTimerTisch RandomTimer *{sunset_abs()} StehlampeTisch +03:00:00 500
Es wird also ab sunset_abs() "versucht", ob eingeschaltet werden soll. Das passiert mit einer Wahrscheinlichkeit von 80%. Alle 450-550 Sekunden wird dann erneut "versucht", irgendwas zu machen. War die Lampe nach Ablauf dieser 8-9 Minuten noch aus, wird sie dann mit derselben Wahrscheinlichkeit eingeschaltet, ist sie an, geht sie mit 20% Wahrscheinlichkeit aus... Usw., bis eben die 3h um sind. Es kann also durchaus passieren, dass die Lampe an einem Abend 10x an- und wieder ausgeht.
Dieses ganze Verhalten - auch die 80:20 - gehen aus der Commandref nicht hervor. bzw ich hätte das der Beschreibung nicht entnehmen können. D.H. die Grundfunktionalität des Moduls ist im CommandRef wenn man mich fragt überhaupt nicht beschrieben! ;D
Und ich habe auch noch nicht verstanden wieso
ZitatWahrscheinlichkeit von 1:3 passieren, was "250" als Einschaltwahrscheinlichkeit
entspricht.
Aber Danke für die Erläuterungen und Beispiel, das hilft mir etwas weiter, auch wenn ich die Parameter damit immer noch nicht ganz verstanden habe. Da komm ich dann hoffentlich mit etwas rumprobieren drauf.
Ich denke aber echt, dass die CommandRef optimiert werden könnte. Ich sehe dass du schon 2.3 Dinge gemacht hast, aber die ist noch Luft ... wenn ich das sagen darf.
Das man das Verhalten eines Moduls nicht aus der Commandref erschliessen kann, sondern durch ausprobieren ermitteln muss, ist ja nicht so günstig, besonders wenn es sich um ein Zufallsmodul handelt, was die Rückschlüsse von Ereignissen auf Regeln ja erschwert bzw. sehr viele Durchläufe erfordert.
Falls ich mal hinreichend sicher verstanden habe, wie das Dingen sich genau verhält, werde ich wenigstens mal die Wikiartikel anpassen.
Gerne würde ich auch bei der Commandref helfen, wenn gewünscht.
@betateilchen:
Ja, hast recht, danke. Allerdings ist den meisten Lösungen gemein (genauer: allen die ich gefunden habe), dass damit was ich gerne machen würde letzlich nicht trivial lösbar ist.
Es geht da nämlich immer um variable Zeitfenster,
wann eingeschaltet wird, nicht darum,
ob überhaupt mit Aufruf der Funktion geschaltet wird.
D.H. man sagt: "randomirgendwas schalte zum Zeitpunkt X ein" und dann wird mithilfe sub/modul/Lösung
randomirgendwas der Zeitpunkt X zu einem Interval gemacht, der Einschaltzeitpunkt variiert dann z.b. +/- Y Sekunden um X.
Ich suchte vor allem eine Lösung, die "randomirgendwas schalte zum Zeitpunkt X ein" nur mit einer bestimmten Wahrscheinlichkeit überhaupt ausführt., weil ich will, dass das Licht nicht jeden Tag angeht, sondern heute vielleicht ... oder auch nicht. Morgen wieder: Vielleicht ... oder nicht.
Das ist auch bei depe1999s Lösung so, auch die hebt auf einen Intervall ab.
Übrigens weisen in dem Thread auch andere darauf hin, dass sie die "Anleitung"/ CommandRef von RandomTimer nicht verstanden haben: "weil ich keinen sinn erkannt habe innerhalb einer gewissen zeit mehrfach zu schalten." Der Nutzer ist also in exakt das gleiche Verständnisproblem gelaufen wir ich.
So oder so: Trotz meiner beschiedenen perl Kenntnisse ist depe1999s sub für mich ggf schneller angepasst als mit Logfile-Untersuchungen die Funktion von RandomTimer zu erforschen. ???
Vielleicht nochmal zum Thema commandref@RandomTimer:
Zitat von: Beta-User am 28 November 2019, 09:19:30
@FunkOdyssey:
Das Modul verstehen würde ich auch gerne, aber leider finde ich nirgends mehr das Handbuch zu der konkreten Hardware, die das Modul nachbildet (FS20 ZSU) ;D . Bisher habe ich das aber nur eher im Zusammenhang mit längerfristigen Abwesenheiten genutzt, da war das nicht sooo wichtig. (Und zum "Mit-Maintainer" bin ich nur geworden, weil ich die Abhängigkeiten von Twilight bei WDT und RT "in einem Rutsch" beseitigt hatte... ;D ;D ;D ).
Von daher wäre mir auch geholfen, wenn wir am Ende eine verständlichere commandref hätten, ohne dass man Logfiles analysieren muß...
Was die "250" angeht: Eine "Wahrscheinlichkeit von 1:3" interpretiere ich als "in einem Fall soll 'an' das Ergebnis sein, in 3 Fällen 'aus'", also in 25% aller Fälle soll das Ergebnis 'an' sein; in der RT-Sprache sind es eben Promille statt Prozent. Falls 1:3 als "in 33,3% aller Fälle" zu lesen sein soll, wäre es eben "333" ;) .
Betr. das "nicht an jedem Tag" gab es hier auch noch einen Vorschlag:
Zitat von: Beta-User am 26 Oktober 2020, 13:42:01
Entweder eine rand-Funktion in disableCond einbauen (dann wird der RandomTimer ggf. am Tagesanfang für diesen ganzen Tag deaktiviert, falls ihn niemand nochmal versucht zu aktivieren),
Das sähe dann konkret so aus:
defmod testRT RandomTimer *{sunrise_abs()} shellydevice +03:00:00 500
attr testRT disableCond int(rand(100))<75
Und wenn man es austestet, kommt von ganz allein ein weiteres Attribut dazu, das scheint also wichtig zu sein...