Zeitsteuerung - Neuesmodul zum Zufallszeit erzeugen randomtime

Begonnen von depe1999, 21 November 2014, 20:07:47

Vorheriges Thema - Nächstes Thema

Damian

Zitat von: Jack-Luck am 13 September 2018, 11:58:44
Hi,

ich habe das Problem, wenn die zeit nach 00:00 Uhr berechnet wird, das sich die Lampe nicht einschaltet.
Weil dann wahrscheinlich eigentlich ein on-till-overnight kommen müsste, wie habt ihr das Problem gelöst?


danke

Bei DOIF sollte es kein Problem sein, da ist die Funktion überflüssig.  Die Funktionalität lässt sich mit Boardmitteln erledigen:

das untere Beispiel z. B.

define rolladen_auf DOIF ([?Schicht_dummy:state] eq "Frueh" and [{randomtime("08,00,30")}|8]) ....

lässt sich genauso gut mit:

define rolladen_auf DOIF ([?Schicht_dummy:state] eq "Frueh" and [([08:00]+rand(1800))|8]) ....

definieren.

Auch

define rolladen_auf DOIF ([?Schicht_dummy:state] eq "Frueh" and [([00:00]+rand(1800))|8]) ....

sollte kein Thema sein.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Jack-Luck

Ich habe das mit einem "at" befehl:

define at_licht at *{sunset("REAL",0,"16:00","24:00")} set FS_Wohnzimmer on-till {randomtime("23,45,60")}

aber wie gesagt, wenn die Zeit nach 0 Uhr ist geht die Lampe nicht mal an.

MunichFan

#17
Hallo,

man kann die Funktion unter Verwendung von modulo (%) auch kürzer schreiben
sub
randomtime($)
{
  my ($MeH,$MeM,$MeB) = split(",", shift);
  my $T   = (int($MeH*3600 + $MeM*60 + rand($MeB*60+1)))%86400;
  # rand erzeugt eine floating point Zahl, int rundet nach unten
  return sprintf("%2.2d:%2.2d:%2.2d",$T/3600,($T/60)%60,$T%60);

und löst zugleich auch das Problem, dass die erzeugte Uhrzeit nicht größer als 23:59 wird.

Will man für den Zufallsbereich $MeB auch negative Werte in Minuten zulassen, kann man die elegante Sign-Funktion
SGN = $MeB <=> 0
verwenden, die 1 oder 0 oder -1 liefert, je nachdem ob $MeB gößer/gleich/kleiner als 0 ist

sub
randomtime2($)
{
  my ($MeH,$MeM,$MeB) = split(",", shift);
  my $SGN = ($MeB<=>0);
 
  my $T   = (int($MeH*3600 + $MeM*60 + ($MeB*60+$SGN)*rand()))%86400;
  # - rand erzeugt eine floating point Zahl, ist aber bei negativen Zahlen nicht eindeutig definiert,
  #   deshalb verwenden wir lieber -x*rand()
  # - int rundet in Richtung 0
  # - modulo sorgt auch bei neg. Zahlen dafür, dass das Ergebnis [0..86400] ist

  return sprintf("%2.2d:%2.2d:%2.2d",$T/3600,($T/60)%60,$T%60);



Yokurt

Ja, das verkürzt das Ganze!
Habe meine Version von randomtime_with_realtime danach umgebaut:
sub randomtime_with_realtime($;$)
{
  my ($MeH,$MeM,$MeS)=split(':',shift(@_));
  my $MeB=shift(@_);
  my $SGN = ($MeB<=>0);

  my $T   = (int($MeH*3600 + $MeM*60 + $MeS + ($MeB*60+$SGN)*rand()))%86400;
  # - rand erzeugt eine floating point Zahl, ist aber bei negativen Zahlen nicht eindeutig definiert,
  #   deshalb verwenden wir lieber -x*rand()
  # - int rundet in Richtung 0
  # - modulo sorgt auch bei neg. Zahlen dafür, dass das Ergebnis [0..86400] ist

  return sprintf("%2.2d:%2.2d:%2.2d",$T/3600,($T/60)%60,$T%60);

1;


:)