Hallo,
für mein Bewässerungsprojekt möchte ich für eine @-Anweisung die Zeit von s (z.B. 600) in das für die at Anweisung benötigte Format hh:mm:ss (in dem Beispiel 00:10:00) umwandeln.
Mit
fhem("set testdummy2 +00:".int($mystartzeit2/60).":".int($mystartzeit2-int($mystartzeit2/60)*60)."");;\
komme ich schon mal zum richtigen Ergebnis, habe jedoch folgendes Problem:
Bei Zeiten kleiner 10s bzw. 10min kommt z.B. 00:21:6 (statt 00:21:06)
Fhem akzeptiert jedoch nur die zweistellige Angabe.
Ich habe schon etliches getestet und probiert und komme zu keiner Lösung.
Wer kann helfen?
Vielen Dank
PS: Stunden sitzen in dem Beispiel immer au 0h :-)
http://perldoc.perl.org/functions/sprintf.html
sprintf("%02d:%02d:%02d", $h, $m, $s);
Alternativ: FmtTime($mystartzeit2)
Hallo und sorry, irgendwie kann ich machen was ich will, es klappt nicht.
Hier mein Code:
define act_on_Bewaesserungssequenz1 notify Bewaesserungssequenz1:on {\
fhem("set Bewaesserungsregler off;;set Bewaesserung2_gpio_17 off;;set Bewaesserung3_gpio_18 off;;set Bewaesserung4_gpio_27 off;;set Bewaesserung5_gpio_22 off;;set Bewaesserung6_gpio_23 off;;set Bewaesserung7_gpio_24 off;; set RUNNING run;;set myTelegramBot message Sequenz 1 on");;\
my $myzeit1 = ReadingsVal("zeit1","state",0);;\
my $mystartzeit1 = $myzeit1 + 10;;\
my $mystartzeit2 = 2 * $myzeit1 + 10;;\
my $mystartzeit1_min = int($mystartzeit1/60);;\
$mystartzeit1_min = sprintf("%02d",$mystartzeit1_min);;\
my $mystartzeit1_sec = int($mystartzeit1-int($mystartzeit1/60)*60);;\
$mystartzeit1_sec = sprintf("%02d",mystartzeit1_sec);;\
fhem("set testdummy1 +00:".($mystartzeit1_min).":".($mystartzeit1_sec)."");;\
fhem("set testdummy2 +00:".int($mystartzeit2/60).":".int($mystartzeit2-int($mystartzeit2/60)*60)."");;\
}
testdummy1 liefert jetzt gar kein Ergebnis mehr (mit Fehlermeldung im Log: ": Bareword "mystartzeit1_sec" not allowed while "strict subs" in use at (eval 763267) line 12.")
testdummy2 funktioniert wie schon beschrieben, aber nicht "zweistellig"
Könnt ihr mir noch mal auf die Sprünge helfen?
----------------
Mit FmtTime bekomme ich zwar die aktuelle Zeit, aber ich suche ja eine Zeit mit +00:10:00 (bei 600 sekunden)
Vielen Dank.
Korrektur von meiner FALSCHEN Behauptung oben:
Habe gerade noch was raus gefunden, was ich nicht verstehe:
FmtTime(0) liefert 01:00:00 ????
Hat das was mit der Sommerzeit zu tun oder MEZ???
Das kommt daher, dass FmtTime() intern mit localtime() arbeitet, anstatt mit gmtime(). Deshalb hängt das Ergebnis davon ab, in welcher konfigurierten Zeitzone deine FHEM Plattform konfiguriert ist.
Bau Dir doch einen Zweizeiler in Deine 99_myUtils.pm
sub sec2hms{
my @t = gmtime(shift);
return sprintf("+%02d:%02d:%02d", $t[2], $t[1], $t[0]);
}
dann bekommst Du mit
sec2hms(600)
korrekt +00:10:00 als Ergebnis.
SEHR Geil (sorry)
Funktioniert wunderbar :D
Vielen Dank.
Es geht noch viel geiler... 8)
Warum machst Du Dir überhaupt die komplett überflüssige Mühe, das selbst zu formatieren, wo es doch für das at gar nicht notwendig ist?
Angenommen, es ist jetzt 17:07 Uhr, das ergibt als Timestamp 1593356878
Wenn ich davon ausgehend jetzt in einer Stunde etwas ausführen will, addiere ich darauf 3600 Sekunden, das ergibt 1593360478
(mathematisch in perl time()+3600)
Und mit diesem Timestamp lege ich dann ein at an:
define test_at at 1593360478 {'mache irgendwas in einer Stunde'}
und oh Wunder...
COMMAND {'mache irgendwas in einer Stunde'}
DEF 2020-06-28T18:07:58 {'mache irgendwas in einer Stunde'}
FUUID 5ef8b2f4-f33f-22e2-89f8-ccc3d3499c66686e
NAME test_at
NR 67
PERIODIC no
RELATIVE no
STATE Next: 2020-06-28 18:07:58
TIMESPEC 1593360478
TRIGGERTIME 1593360478
TRIGGERTIME_FMT 2020-06-28 18:07:58
Das ist eine Funktionalität von "at" die immer mal gerne vergessen wird, die aber in der commandref durchaus erwähnt ist 8)
Ein at kommt übrigens auch mit sowas klar:
define test_at2 at 2020-06-28T18:17:58 {'mach nochmal was'}
.
Auch toll :-)
Aber der Zweizeiler in der 99_myUtils.pm tut wunderbar seinen Dienst und ist nun "drin".
Vielen Dank allen für die Ideen und Anregungen....
PS
Leider stehe ich etwas mit Perl auf Kriegsfuß mit den ', ", "., ....... und irgendwas in meiner "alten" Anweisung des sprintfs mit %02d war wohl falsch....
Zitat von: Joachim2112 am 28 Juni 2020, 19:44:08
Leider stehe ich etwas mit Perl auf Kriegsfuß mit den ', ", ".
". ist kein eigenständiges Konstrukt.
Den Unterschied zwischen ' und " kann man an einem Beispiel erklären.
Pack mal folgenden Code in Deine 99_myUtils.pm und rufe dann in der FHEM Befehlszeile die Funktion mit {beispiel} auf.
sub beispiel {
my $xText = "ich bin ein X";
Debug "1. Beispiel mit doppelten Anführungszeichen: $xText";
Debug '2. Beispiel mit einfachen Anführungszeichen: $xText';
Debug "3. Beispiel mit doppelt und Verkettung: ".$xText;
Debug '4. Beispiel mit einfach und Verkettung: '.$xText;
}
Danach ins Logfile schauen und die Unterschiede erkennen.
2020.06.28 20:04:42 1: DEBUG>1. Beispiel mit doppelten Anführungszeichen: ich bin ein X
2020.06.28 20:04:42 1: DEBUG>2. Beispiel mit einfachen Anführungszeichen: $xText
2020.06.28 20:04:42 1: DEBUG>3. Beispiel mit doppelt und Verkettung: ich bin ein X
2020.06.28 20:04:42 1: DEBUG>4. Beispiel mit einfach und Verkettung: ich bin ein X
Vereinfacht gesagt:
- immer dann, wenn innerhalb eines Strings noch etwas ausgewertet werden soll, z.B. eine Variable, musst Du doppelte Anführungszeichen verwenden.
- Text in einfachen Anführungszeichen wird so wiedergegeben, wie er geschrieben wurde.
- Das Verketten (Anhängen) von Text mittels eines Punktes funktioniert in beiden Fällen, weil der Punkt in diesem Fall ein Operator ist, der mit zwei Einzelteilen etwas tut (zwei Strings verbinden)
Wie kann sec2hms in einem userReading verwendet werden?
Wir wird bei $t[0] nur die Gesamtsekunden zurückgegeben:
test_sec2hms {
my @t = ReadingsNum($NAME,"pulseTimeIncrement",0);
return sprintf("%02d:%02d:%02d", $t[2], $t[1], $t[0]);
}
ReadingsNum liefert kein Feld (array) zurueck, sondern nur ein Wert, damit ist nur $t[0] gefuellt.
Versuchs mal mit FmtTime(ReadingsNum($NAME,"pulseTimeIncrement",0));
Zitat von: rudolfkoenig am 28 Juli 2020, 09:02:24
ReadingsNum liefert kein Feld (array) zurueck, sondern nur ein Wert, damit ist nur $t[0] gefuellt.
Versuchs mal mit FmtTime(ReadingsNum($NAME,"pulseTimeIncrement",0));
Damit ist t[0] die Stundenanzahl:
setstate test_HourCounter 2020-07-28 09:38:00 test_sec2hms 00:00:09
pulseTimeIncrement ist derzeit 31476
Mit return("@words");
bekommt man aus einem userReadings ein array zurück.
@words muss natürlich nach Wunsch zusammengebaut werden. Verwende das in einem stack mit Vortageswerten.
Ich habe mal irgendwo hier im Forum die 99_TimeUtils.pm gefunden.
Damit kann man wunderbar mit Zeitangaben rechnen (Jetzt plus 3 Sekunden, Minuten, Stunden):
my $hms = sprintf("%02d:%02d:%02d", $hour, $min, $sec);
Log3 "Dummy",2,"startzeit : ".$hms."/".TU_Get_Increment($hms,"00:00:03");
Hier ein Link https://forum.fhem.de/index.php/topic,19586.msg132313.html#msg132313 (https://forum.fhem.de/index.php/topic,19586.msg132313.html#msg132313)
Zitat von: jkriegl am 28 Juli 2020, 12:51:18
Mit return("@words");
bekommt man aus einem userReadings ein array zurück.
@words muss natürlich nach Wunsch zusammengebaut werden. Verwende das in einem stack mit Vortageswerten.
Damit ist die Stunde eins zu viel
test_sec2hms {
my @t = FmtTime(ReadingsNum($NAME,"pulseTimeIncrement",0));
return("@t");
}
Habe es nun so hinbekommen:
pulseTimeIncrement_HHMMSS {
my @t = gmtime(ReadingsNum($NAME,"pulseTimeIncrement",0));
return sprintf("%02d:%02d:%02d", $t[2], $t[1], $t[0]);
},