Sekunden in hh:mm:ss umwandeln

Begonnen von Joachim2112, 28 Juni 2020, 12:48:36

Vorheriges Thema - Nächstes Thema

Joachim2112

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 :-)

xenos1984


rudolfkoenig

Alternativ: FmtTime($mystartzeit2)

Joachim2112

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.

Joachim2112

#4
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???

betateilchen

#5
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.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Joachim2112

SEHR Geil (sorry)

Funktioniert wunderbar  :D

Vielen Dank.

betateilchen

#7
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'}



.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Joachim2112

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....


betateilchen

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)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

TWART016

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]);
}

rudolfkoenig

ReadingsNum liefert kein Feld (array) zurueck, sondern nur ein Wert, damit ist nur $t[0] gefuellt.
Versuchs mal mit FmtTime(ReadingsNum($NAME,"pulseTimeIncrement",0));

TWART016

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

jkriegl

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.
Rpi 3, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

jhohmann

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
Raspberry Pi 4 - bookworm / EnOcean - Rollo+Licht, deCONZ - Licht+Sensoren, ZWave - CO Messung, HMCCU mit piVCCU - Heizung+Rollo
plus dovecot, minidlna