FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: bugster_de am 25 August 2013, 20:18:02

Titel: Zeitangaben in Strings
Beitrag von: bugster_de am 25 August 2013, 20:18:02
So, nun hat das eher schlechte Wetter eine massive Erweiterung des Könnens meiner FHEM Installation zur Folge. Als 'Nebenprodukt' sind dabei ein paar Funktionen abgefallen, die zum Umgang mit Strings dienen. Datei siehe im Anhang

Als erstes gibt es die:
# ------------------------------------------------------------------------
#  Function to fill the variables for the current time
#  Usage: ($success) = myUtils_Set_Timestruct( );
# ------------------------------------------------------------------------
sub TU_Set_Timestruct( );


Diese kann man immer aufrufen, sobald man die aktuelle Uhrzeit braucht. Sie füllt dann die globalen Variablen, auf die man dann direkt zugreifen kann. Die Bedeutung der einzelnen Variablen ist im Code erklärt.

Um einen Offset auf einen Zeitstempel auf zu addieren:
# ------------------------------------------------------------------------
#  Function to increment a time
#  Usage: ($success,$result) = TU_Get_Increment( "hh:mm:ss", "hh:mm:ss" );
# ------------------------------------------------------------------------
#  the success is false (failed) or true (success)
#  the $result is the resulting time string in case of success "hh:mm:ss"
#    empty in case of error
# ------------------------------------------------------------------------
sub TU_Get_Increment( $$ ) {


Hier kann man einen Zeitstempel (z.B. "20:10:15") angeben sowie einen Offset (z.B. "00:12:10"). Als Rückgabe erhält man im zweiten Parameter ($result) die neue Zeit hier: "20:22:25"
Falls irgendwas in den Übergabeparametern nicht stimmt, dann ist $success false und $result enthält nichts.

# ------------------------------------------------------------------------
#  Function to increment a time
#  Usage: ($success,$result) = TU_Get_Increment( "hh:mm:ss", "hh:mm:ss" );
# ------------------------------------------------------------------------
#  the success is false (failed) or true (success)
#  the $result is the resulting time string in case of success "hh:mm:ss"
#    empty in case of error
# ------------------------------------------------------------------------
sub TU_Get_Increment( $$ ) {

Naja, wer Increment verstanden hat, der weiß was diese Funktion macht :-)


# ------------------------------------------------------------------------
#  Function to calculate the difference in between two time stamps
#  Usage: ($success,$result) = TU_Get_Difference( "hh:mm:ss", "hh:mm:ss" );
# ------------------------------------------------------------------------
#  the success is false (failed) or true (success)
#  the $result is the resulting time string in case of success "hh:mm:ss"
#    empty in case of error
#  Please note, that first input string is the starting time and second
#    string is end time. So this is forward calculation
# ------------------------------------------------------------------------
sub TU_Get_Difference( $$ ) {

Der hier berechnet das Delta zwischen zwei Zeitstempeln. Der erste Übergabewert ist dabei der Startpunkt, der zweite der Endpunkt. Sinnvoll, wenn man z.B. die Laufzeit einer Pumpe berechnen möchte.


# ------------------------------------------------------------------------
#  Function to check and split a given time string
#  Usage: ($success,hour,min,sec) = TU_Get_SplitTimeString( "hh:mm:ss" );
# ------------------------------------------------------------------------
#  the success is false (failed) or true (success)
#  the hour, min, sec is the resulting time values as scalars
#    empty in case of error
# ------------------------------------------------------------------------
sub TU_Get_SplitTimeString( $ ) {

Und der hier zerlegt einen Zeitstempel in seine Bestandteile.


Viel Spass damit für diejenigen, die es brauchen können.

Titel: Aw: Zeitangaben in Strings
Beitrag von: bugster_de am 25 August 2013, 20:57:44
Und für alle, die sich fragen, für was man das braucht, hier mal ein paar Anwendungsfälle, die ich heute umgesetzt habe

- Poolpumpe
die Pumpe am Pool sollte min. 4 Stunden am Tag laufen. Wenn man badet läuft die Pumpe ja eh, also könnte man sich das Laufenlassen nachts sparen. Nun ermittle ich die Gesamtlaufzeit der Pumpe am Tag, wenn sie manuell geschaltet wird und lasse nachts nur noch die Restlaufzeit, die noch fehlt laufen

- Rolladen
Alle Rolläden fahren automatisch abend runter und morgens rauf. Morgens entscheidet FHEM an Hand der Wetter daten, ob die Rolläden ganz auf sollen oder ob man Beschattung macht. Je nachdem gehen die Rolläden dann zu einer bestimmten Uhrzeit (z.b. 08:30:00) in die gewünschte Position per at.
Wenn man nun aber länger schlafen möchte, dann habe ich eine Funktion mittels Intertechno Fernbedienung umgsetzt, die das öffen verzögert: wenn man einmal drückt, denn gehe sie eine Stunde später, wenn man 2 mal drückt 2 Stunden später usw.

-Rolläden
das Thema MISSING ACK bei Homematic ist ja bekannt. Es scheint am besten zu gehen, wenn man die Befehele an die Homematic Aktoren in einem Abstand von 2 Sek. per at sendet. Nun kann ich auf Basis einer vorgegebenen Startzeit einfach alle Rolläden schön im Abstand von 2 Sek. runterlaufen lassen.
Titel: Antw:Zeitangaben in Strings
Beitrag von: RoqueNublo am 16 Oktober 2013, 19:37:40
Hallo bugster_de,

da ich z.Zt. auf der Suche nach Codeschnipseln bin um meinem Floorplan eine möglichst dynamische Ablaufsteuerung zu geben, bin ich u.a. auf Dein Perlscript ,,Zeitangaben in Strings" gestoßen.
Auch die von Dir aufgezeigten Verwendungsbeispiele erscheinen mir zur Erreichung meines Vorhabens recht Interessant seinen.

Eine Bitte. Könntest Du einige Aufrufbeispiele (fhem.cfg) posten, z.B. zu den von Dir vaufgezeigten Verwendungsbeispielen.

Gruß RoqueNublo
Titel: Antw:Zeitangaben in Strings
Beitrag von: moonsorrox am 17 Oktober 2013, 12:00:23
das hört sich sehr interessant an, was man da mit den Rollläden machen kann, da ich mich gerade damit beschäftige wie ich das leidige Thema der Rollläden "Öffnen" am Morgen so machen kann das es bei Sonne nur 10%, 20% oder auch 30% beschattet wäre dies für mich auch gut an einem Beispiel zu sehen, da noch blutiger Anfänger
Titel: Antw:Zeitangaben in Strings
Beitrag von: bugster_de am 20 Oktober 2013, 20:42:14
Hi,

ZitatKönntest Du einige Aufrufbeispiele (fhem.cfg) posten
mit der fhem.cfg hat das nichts zu tun. Die Funktionen werden in den jeweiligen perl Skripten aufgerfufen. Diese kann man z.B. durch ein notify aufrufen.

Als Nutzungsbeispiele dann z.B. folgendes:

der Code addiert 5 Minuten zur Zeit 12:13:27 hinzu
my $res = true;
my $newtime = "";
($res, $newtime) = GU_Get_Increment( "12:13:27", "00:05:00" );
if( res == false ) {
    Log 1, "Fehler";
}

$newtime enthält jetzt einen String mit "12:18:27"

der hier holt erstmal die aktuelle Zeit und addiert dann 5 Min. hinzu und steuert einen Aktor mittels Timer an
# Rueckgabewerte definieren
my $res = true;
my $newtime = "";

# globale Zeitstrukturen definieren
TU_Set_TimeStruct( );

# auf die aktuelle Zeit 5 Min drauf addieren
($res, $newtime) = GU_Get_Increment( $str_hourminsec, "00:05:00" );
if( res == false ) {
    Log 1, "Fehler";
}

# und die neue Zeit in einem Timer nutzen
fhem( "define mytimer at " . $newtime . " set myactor on" );


das ganze funktioniert dann auch analog mit GU_Get_Decrement

Und hier die Berechnung einer Zeitdifferenz
my $res = true;
my $timediff = "";
($res, $timediff) = GU_Get_Difference( "12:13:27", "13:18:37" );
if( res == false ) {
    Log 1, "Fehler";
}

die Variable $timediff enthält nun den Wert "01:05:10"

Und die letzte Funktion nutzt man so:
my $res = false;
my $hour;
my $min;
my $sec;

($res, $hour, $min, $sec ) = GU_Get_SplitTimeString( "12:13:27" );

$hour ist jetzt 12
$min ist jetzt 13
$sec ist jetzt 27
Somit kann man diesen Skalaren entsprechend rechnen

Titel: Antw:Zeitangaben in Strings
Beitrag von: RoqueNublo am 21 Oktober 2013, 14:09:55
Hallo,

danke für die Rückmeldung. Da ich in perl nicht so fit bin, kannst Du mir vielleicht meine Fragen beantworten.

In den Beispielen werden die Funktionen mit GU_Get_.... aufgerufen. In Deiner Bibliothek heißen sie aber TU_Get_..., könnte es sein, dass hier ein Tipfehler vorliegt.

Eine weitere Syntax führt bei mir zu Fehlern. Die Anweisung ,,if ( res == false )" geht bei mir nur ohne Fehler durch, wenn ich sie wie folgt schreibe ,,if ( $res == false )". Woran liegt das?

Vorweg erst einmal Danke für Deine Unterstützung.

Gruß
Roque
Titel: Antw:Zeitangaben in Strings
Beitrag von: baukater am 04 November 2013, 19:03:48
Wenn ich die Funktionen kopieren möchte, dann erhalte ich nur den sichtbaren Teil. Fehlt der Rest. Die Funktionen für die Uhrzeitberechnungen
finde ich ganz nütztlich, um zeitversetzt Aktionen auszulösen.
Titel: Antw:Zeitangaben in Strings
Beitrag von: bugster_de am 07 November 2013, 09:32:28
stimmt, und deshalb ist der komplette Code ja als Datei im ersten Post angefügt. Datei runterladen --> ins FHEM/FHEM verzeichniss kopieren --> reload und los gehts
Titel: Antw:Zeitangaben in Strings
Beitrag von: UliM am 02 Februar 2014, 09:52:05
Hi,
magst Du das mal einchecken? M.E. am besten mit Rudi abstimmen und mit in 99_Utils.pm aufnehmen incl dortiger commandref-Doku .

Alternativ ins contrib einchecken.

Und vielleicht nen Wiki-Artikel dazu.

Wär doch schade wenn das hier versandet...

Gruß, Uli
Titel: Antw:Zeitangaben in Strings
Beitrag von: bugster_de am 06 Februar 2014, 11:59:46
Hi,

kann ich gerne machen, wird aber frühestens am Wochenende passieren.

Allerdings mal unter uns Perl-Programmierungspfarrertöchtern: diese Routinen funktionieren bei mir jetzt seit einem dreiviertel Jahr problemlos und haben somit im besten Ingenieurs-Sinne die Tauglichkeit bestanden. Allerdings sind sie nicht sehr robust gegen Fehlbedienung programmiert. Eine Uhrzeit wie "26:83:95" wird genauso akzeptiert wie "AM:X3:17". Ich habe eine Prüfung per RegExp wegen des hohen Rechenaufwandes mal gescheut.

Viele Grüße
Titel: Antw:Zeitangaben in Strings
Beitrag von: Rince am 13 Februar 2014, 10:16:39
It's not a bug, it's a feature:
Wenn fhem mal zur Steuerung von Mars Missionen eingesetzt wird, ist es schon mit Mars-Tagen kompatibel.

Ich würde mir daher diesbezüglich keine schlaflosen Nächte bereiten.
(auch wenn ich vermutlich da drüber stolpern werde ;) )
Titel: Antw:Zeitangaben in Strings
Beitrag von: prime1009 am 30 Mai 2014, 17:30:10
Hi,

habe die Datei ins Verzeichnis kopiert und reload gemacht. Bekomme beim Aufruf der Funktion allerdings immer die Meldung:

... return value: Undefined subroutine &main::TU_Set_TimeStruct called at ./FHEM/99_MyUtils.pm line 25

was könnte ich da noch falsch machen?

Gruß und Dank
Titel: Antw:Zeitangaben in Strings
Beitrag von: Kakaomonster am 17 Januar 2015, 13:27:42
Hallo zusammen,

auch wenn hier seit 120 Tagen nichts mehr geschrieben wurde, denke ich das es die möglichkeit ist nach der ich suche.

Was möchte ich:
Geräte, die eingeschaltet werden sollen überprüft werden, wie lange sie an sind (onlinezeit) innerhalb vom 01. - letzten Tag eines Monats.
Diese Zeit soll dann brechnet werden mit der Watt Zahl des jeweiligen Gerätes und danach mit dem Strompreis. Somit könnte man auch ohne zusätzliche Hardware die verbrauchskosten annähernd berechnen.

Ich glaube das sowas mit o.g. Code möglich wäre, komme aber auch nach langem suchen und testen damit nicht klr. hat vielleicht schon jemand soetwas oder interesse das zu basteln?

Also der Plan wäre dann ungefähr so:
Gerät on bis off in einen Dummy schreiben, nennen wir ihn "Dummy OnlineAktuell"
Diesen "Dummy Online Aktuell" hinzufügen (also addieren zu) "Dummy OnlineTag"
Diesen "Dummy OnlineTag" wiederum zu "Dummy OnlineMonat" addieren

Damit das alles am Ende vom Monat nicht verloren geht, sollte es dann noch den Dummy MonatJahr geben, indem jeweils das Monatsergebniss aufbewahrt undvielleicht ebenfalls ausgewertet werden kann.

Das alles in eine tabelle auslesen und man hat eine übersicht.

Ich habe lange gesucht und war eigentlich der Meinung das ich was ähnliches im Sommer letztes Jahr im Forum gefunden hatte, aber ich finde  es nicht mehr :-(

Grüßen und ein schönes Wochenende, auf das sich wenigstens jemnd meldet, Kakaomonster
Titel: Antw:Zeitangaben in Strings
Beitrag von: Spartacus am 17 Januar 2015, 17:19:44
Hallo,
spiele gerade auch mit der Funktion. Aber m.E. ist hier ein Fehler drin:
{TU_Get_Increment ("20:00:01", "10:00:00")}

Kommt 00:00:01 raus. Da müsste aber 06:00:01 rauskommen, oder?

Christian
Titel: Antw:Zeitangaben in Strings
Beitrag von: fiedel am 18 Januar 2015, 09:17:42
Hi,

ZitatWas möchte ich:
Geräte, die eingeschaltet werden sollen überprüft werden, wie lange sie an sind (onlinezeit) innerhalb vom 01. - letzten Tag eines Monats.
Diese Zeit soll dann brechnet werden mit der Watt Zahl des jeweiligen Gerätes und danach mit dem Strompreis. Somit könnte man auch ohne zusätzliche Hardware die verbrauchskosten annähernd berechnen.

Elektrolurch hat genau zu diesem Thema kürzlich ein Modul (http://forum.fhem.de/index.php/topic,30055.0.html) veröffenlicht.

Gruß

Frank
Titel: Antw:Zeitangaben in Strings
Beitrag von: Kakaomonster am 18 Januar 2015, 09:20:04
Hallo Fiedel,

habs gestern Abend gefunden, das ist genau was ich suchte. War nur so lange beschäftigt, dass ich es hier noch nicht nachtragen konnte. Danke erstmal.

Mein erstes Problem habe ich dort bereits gepostet.

Grüsse, Ralf
Titel: Antw:Zeitangaben in Strings
Beitrag von: Spartacus am 17 Februar 2015, 16:41:58
Hallo,
die TimeUtlis scheinen offiziell nicht von fhem unterstützt zu werden. Ich suche eine einfache Lösung um von einem Timestring Zeiten zu addieren oder abzuziehen. Diese Funktion hier scheint nicht korrekt zu arbeiten!
{TU_Get_Increment ("23:30:00", "01:45:00")}
Ergebnis: 00:15:00
{TU_Get_Increment ("23:30:00", "00:45:00")}
Ergebnis: 00:15:00


Weiß jemand ob es in fhem etwas ähnliches gibt, was man verwenden kann?
Christian
Titel: Antw:Zeitangaben in Strings
Beitrag von: Pf@nne am 27 Juli 2015, 23:30:41
Moin,

schönes Util......danke dafür!

Das inkrementieren lief nicht ganz sauber....
Ich habe mal die Stundenberechnung angepasst:
    if( ( $in_hh + $of_hh + $buf ) > 23 ) {
$out_hh = $in_hh + $of_hh + $buf - 24;
    } else {
$out_hh = $in_hh + $of_hh + $buf;
    }