[Gelöst] Reading Uptime aus Tasmota: Umwandlung in Sekunden ?

Begonnen von Gisbert, 27 Januar 2019, 07:34:14

Vorheriges Thema - Nächstes Thema

Gisbert

Hallo,

Tasmota liefert u.a. das folgende Reading:
Uptime    38T17:31:16
Wie kann ich diesen String in eine berechenbare Größe in der Einheit z.B. Sekunden oder Minuten umwandeln?
Ich hab's mit der Perlfunktion time_str2num probiert. Da kommt aber nichts sinnvolles heraus, da sie wohl nur für das komplette Datumsformat anwendbar ist.

Viele​ Grüße​ Gisbert​
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Waldmensch

Da wirst Du wohl selbst eine Funktion schreiben müssen.
Erst bei T splitten und array[0] * 86400
Dann array[1] nach : splitten und
(arr[0] * 3600) + (arr[1]*60) + (arr[2])


Gesendet von iPhone mit Tapatalk

Gisbert

Hallo Waldmensch,

ich befürchte, dass du Recht hast, denn ich hab nichts fertiges gefunden.
Danke für deinen Hinweis, im Moment sind es aber noch böhmische Dörfer für mich. Könntest du diese Funktion schreiben oder mich anleiten?

Viele​ Grüße​ Gisbert​
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

RaspiLED

Raspberry Pi mit FHEM, CUL, Signalduino, MySensors, HomeBridge, Presence, WifiLight2, Bravia, ...

Waldmensch

Kopier das in deine 99_myutils.pl

#############ddThh:mm:ss to sec#########
sub
formattedUptime2sec
{
my(@arr) = split /[T:]/, $_[0];
return (@arr[0] * 86400) + (@arr[1] * 3600) + (@arr[2] * 60) + @arr[3];
}


reload das Modul und dann kannst Du es verwenden mit

{formattedUptime2sec("38T17:31:16")}

Ergebnis in Sekunden: 3346276

Gisbert

Hallo Waldmensch,

funktioniert super, vielen Dank.
Das userReadings sieht dann so aus, mit Einheiten in Minuten:
attr Heizung userReadings System.Info {sprintf('%.0f',(formattedUptime2sec(ReadingsVal($name,'Uptime','')))/60)}

Hallo Arnd,

vielen Dank für den Hinweis zu Perl split. Ob ich das aber umgesetzt bekommen hätte, ist aber fraglich. Das sieht ja nicht ganz einfach aus.
Trotzdem vielen Dank für den Hinweis.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Waldmensch

Die Funktion crasht aber, wenn das xxT fehlt. Da bitte aufpassen. Wenn Tasmota auch 00T23:24:25 liefert ist alles okay. Wenn unter einem Tag nur 23:24:25 geliefert wird, macht es peng, weil das Array dann nur 3 statt 4 Elemente enthält. Ist halt nur quick'n dirty.


Gesendet von iPhone mit Tapatalk

Gisbert

Hallo Waldmensch,

danke für diesen wichtigen Hinweis.
Tatsächlich macht Tasmota folgendes: 0T23:24:25 oder z.B. 3T:01:25:10 (als Beispiel), d.h. bei Tagen unter 10 wird nur eine Stelle angegeben.
Kommt dein Code damit zurecht?
Die Antwort ist wahrscheinlich ja, denn ich hab ein Device, was vor 3 Stunden rebootet hat, mit folgendem Eintrag:
Uptime   0T03:08:15
und umgerechneten 188 Minuten, d.h. es sollte immer funktionieren.

Kannst du "crashen" näher definieren?

  • die Funktion liefert nur etwas unsinniges, Fhem wird nicht blockiert
  • Fhem steigt aus bzw. ist blockiert
  • Fhem steigt aus, RPi legt sich schlafen, es geht nichts mehr
  • ich muss mir einen neuen RPi und SD-Karte kaufen

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Waldmensch

#8
Ich habe es nochmal modifiziert. Akzeptiert wird jetzt ddThh:mm:ss und hh:mm:ss. Trenner sind "T" und ":". Wenn bei der Trennung vier Elemente rauskommen, wird mit Tag gerechnet, wenn nur 3 Elemente rauskommen, wird ohne Tag gerechnet. Wenn eine andere Anzahl an Elementen beim Split rauskommt, wird 0 zurückgeliefert. Das sollte robust genug sein. Wenn 0 rauskommt, ist was faul und du musst prüfen, mit was die Funktion gefüttert wird. Es kann zumindest keinen "Index out of Range" Error geben, wie es im vorigen Ansatz war.

#############ddThh:mm:ss to sec#########
sub
formattedUptime2sec
{
my(@arr) = split /[T:]/, $_[0];
if (@arr == 3){
return (@arr[0] * 3600) + (@arr[1] * 60) + @arr[2];
} elsif (@arr == 4) {
return (@arr[0] * 86400) + (@arr[1] * 3600) + (@arr[2] * 60) + @arr[3];
} else {
#something went wrong
return 0;
}
}

Gisbert

#9
Hallo Waldmensch,

das sieht gut aus, läuft ohne Probleme, bei 2 Devices habe ich explizit nachgeschaut.
Nochmals vielen Dank, ohne deine Hilfe hätte ich das nicht hinbekommen.

Doch noch eine weitere Frage, eher eine Anmerkung.
Bei der Anzahl von Tagen über 99, also >= 100 funktioniert deine Funktion ebenfalls, d.h. das Format kann auch dddThh:mm:ss bzw. auch dThh:mm:ss bei Tagen < 10.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Waldmensch

Sollte kein Problem sein, solange jedes Element nach dem Split eine Zahl ist. Die Automatische Typumwandlung bei Perl sollte clever genug sein auch 00 als 0 und 01 als 1 zu erkennen. Ich bin aber da nicht so der Perl Fux.
Wenn allerdings Tasmota 1J200T21:22:23 liefert, wird es schiefgehen, da dann versucht wird mit 1J200 zu rechnen ;)


Gesendet von iPhone mit Tapatalk

Waldmensch

Du kannst die Funktion in der FHEM Eingabezeile testen, so wie ich es im ersten snippet unten gepostet hab. Nur geschweifte Klammern, damit der Perl Mode erkannt wird und deinen Wert in Anführungszeichen setzen, damit er als String gewertet wird.


Gesendet von iPhone mit Tapatalk

Gisbert

#12
Zitat von: Waldmensch am 27 Januar 2019, 10:25:16Wenn allerdings Tasmota 1J200T21:22:23 liefert, wird es schiefgehen, da dann versucht wird mit 1J200 zu rechnen ;)

Guter Hinweis, d.h. wenn die Jahresgrenze überschritten ist, dann muss ich schauen, was Tasmota bei Uptime zurückliefert.
Das ganze ist aber eher theoretischer Natur, da entweder das Device bis dahin neu (von selbst) gebootet hat, oder irgendjemand den FI-Schalter absichtlich oder aus nachvollziehbaren Gründen ausgelöst hat.
Ich werde in ca. knapp 11 Monaten berichten ;) , was Tasmota ausgespuckt hat.

Das Testen der Funktion in der Kommandozeile war mir schon bekannt.
Was Tasmota dann in einem Jahr auspuckt, ist derzeit aber noch unbekannt, es kann bei Tagen bleiben, ein "J" sein oder auch "Y", wer weiß.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

Waldmensch

Ich fänd es allgemein schöner, wenn Tasmota gleich Sekunden liefern würde. Generell sollten Werte erst bei der Ausgabe am jeweiligen Endgerät formatiert werden. So wie es jetzt ist, ist es Verschwendung von Rechenzeit.
- Tasmota wandelt die Sekunden in ein Format
- FHEM wandelt das Format wieder in Sekunden

Effizienter, weniger fehleranfällig und billiger wäre, Tasmota liefert die Rohdaten (Sekunden) und der Client wandelt bei Bedarf in ein human readable Format.

Da ist aber scheinbar momentan eine Entwicklergeneration am Werk, die bezüglich Rechenleistung und Ressourcen aus dem vollen schöpfen können. Ich habe das noch anders gelernt, als CPU cycles Geld kosteten.


Gesendet von iPhone mit Tapatalk

Gisbert

Hallo Waldmensch,

Fhem schreibt neuerdings (seit wann, kann ich nicht genau sagen), folgende Zeilen nach einem restart in den Logfile:
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[0] better written as $arr[0] at .//FHEM/99_myUtils.pm line 145.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[1] better written as $arr[1] at .//FHEM/99_myUtils.pm line 145.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[2] better written as $arr[2] at .//FHEM/99_myUtils.pm line 145.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[3] better written as $arr[3] at .//FHEM/99_myUtils.pm line 145.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[0] better written as $arr[0] at .//FHEM/99_myUtils.pm line 159.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[0] better written as $arr[0] at .//FHEM/99_myUtils.pm line 173.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[1] better written as $arr[1] at .//FHEM/99_myUtils.pm line 173.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[1] better written as $arr[1] at .//FHEM/99_myUtils.pm line 187.
2019.03.15 22:54:43 1: PERL WARNING: Scalar value @arr[2] better written as $arr[2] at .//FHEM/99_myUtils.pm line 187.

usw. (nur ein Auszug)

Dieser Code steht in den entsprechenden Zeilen in 99_myUtils.pm, den ich ja von dir hatte:
sub
formatUptime2sec
{
my(@arr) = split /[T:]/, $_[0];
if (@arr == 3){
return (@arr[0] * 3600) + (@arr[1] * 60) + @arr[2];
} elsif (@arr == 4) {
return (@arr[0] * 86400) + (@arr[1] * 3600) + (@arr[2] * 60) + @arr[3];
} else {
#something went wrong
return 0;
}
}

sub
formatUptime2day
{
my(@arr) = split /[T:]/, $_[0];
if (@arr == 3){
return 0;
} elsif (@arr == 4) {
return @arr[0];
} else {
#something went wrong
return 0;
}
}

sub
formatUptime2hour
{
my(@arr) = split /[T:]/, $_[0];
if (@arr == 3){
return @arr[0];
} elsif (@arr == 4) {
return @arr[1];
} else {
#something went wrong
return 0;
}
}

sub
formatUptime2minute
{
my(@arr) = split /[T:]/, $_[0];
if (@arr == 3){
return @arr[1];
} elsif (@arr == 4) {
return @arr[2];
} else {
#something went wrong
return 0;
}
}


Kann ich das @-Zeichen einfach durch das $-Zeichen ersetzen?
Wieso gab es zu Anfang kein Gemecker im Logfile, ich kann mich zumindest nicht daran erinnern.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY