Zahlenstring in Zeit (Timespec) konvertieren?

Begonnen von MisterEltako, 24 Februar 2013, 09:48:41

Vorheriges Thema - Nächstes Thema

MisterEltako

Hi!

Ich habe das Problem:

Durch zusätzliche Einträge in der 59_Weather.pm liefert diese Sonnenaufgang und Sonnenuntergangszeiten von Yahoo-Wetter.de.

Abfragen kann man sie über ReadingsVal("Local_Weather","sunset", ""). Man erhält einen Textstring der Art: 17:55:00.

Trägt man das in ein at-define ein kommt: "wrong Timespec", da es ja ein String ist.

Gibt es in Perl daraus eine Möglichkeit ein richtiges Zeit (Timespec)-Format zu konvertieren?

MfG, MisterEltako
HMLAN-Konfigurations-Adapter, HM-Funkjalousieaktor/HM-Dimmaktor/HM-Schaltaktor f. Markenschalter, Jalousie-/Schaltaktor von Eltako, FT4 v. Eltako, TCM310

Dietmar63

Ich glaube nicht dass es damit zu tun hat, dass du einen String weitergibt. Der folgende code prüft deinen timespec und liefert ggf HH mm ss als einzelwerte zurück:
Ein Leerzeichen oder Punkt zuviel und er ist nicht mehr gültig. Zeile 2231 ist entscheidend.

Weiter unten (Zeile 2248) folgt deine Fehlermeldung: "wrong Timespec". Es müsste eigentlich dein übergebenen timespec in der Fehlermeldung folgen.



2224 # Parse a timespec: Either HH:MM:SS or HH:MM or { perfunc() }
2225 sub
2226 GetTimeSpec($)
2227 {
2228  my ($tspec) = @_;
2229  my ($hr, $min, $sec, $fn);
2230
2231  if($tspec =~ m/^([0-9]+):([0-5][0-9]):([0-5][0-9])$/) {
2232    ($hr, $min, $sec) = ($1, $2, $3);
2233  } elsif($tspec =~ m/^([0-9]+):([0-5][0-9])$/) {
2234    ($hr, $min, $sec) = ($1, $2, 0);
2235  } elsif($tspec =~ m/^{(.*)}$/) {
2236    $fn = $1;
2237    $tspec = AnalyzeCommand(undef, "{$fn}");
2238    if(!$@ && $tspec =~ m/^([0-9]+):([0-5][0-9]):([0-5][0-9])$/) {
2239      ($hr, $min, $sec) = ($1, $2, $3);
2240    } elsif(!$@ && $tspec =~ m/^([0-9]+):([0-5][0-9])$/) {
2241      ($hr, $min, $sec) = ($1, $2, 0);
2242    } else {
2243      $tspec = "<empty string>" if(!$tspec);
2244      return ("the at function \"$fn\" must return a timespec and not $tspec.",
2245                undef, undef, undef, undef);
2246    }
2247  } else {
2248    return ("Wrong timespec $tspec: either HH:MM:SS or {perlcode}",
2249                undef, undef, undef, undef);
2250  }
2251  return (undef, $hr, $min, $sec, $fn);
2252 }

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

Zitatdann kann man Sonnenaufgang verwenden z.B.:
define Sonnenaufgang at *(ReadingsVal('Local_Wetter', 'sunrise', '')) set Sonnen_dummy on

Wenn dies dein at ist, der Probleme macht, dann ersetzte die äußeren () durch {}. Dann interpretiert die Funktion GetTimeSpec($) den timespec als perfunc. Dann solltest du weiterkommen.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

MisterEltako

Hi!

define Sonne notify test {\
my $Zeitstring = ReadingsVal('Local_Wetter', 'sunrise', '');;\
fhem ("define Sonnenaufgang at *{$Zeitstring} set Sonnen on");;\
Log 3,"$Zeitstring";;\
}

Habe ich schon versucht, das liefert:

define Sonnenaufgang at *{07:04:59} set Sonnen on : the at function "07:04:59" must return a timespec and not syntax error at (eval 101)

MfG, MisterEltako.
HMLAN-Konfigurations-Adapter, HM-Funkjalousieaktor/HM-Dimmaktor/HM-Schaltaktor f. Markenschalter, Jalousie-/Schaltaktor von Eltako, FT4 v. Eltako, TCM310

UliM

Dann sind da wohl einmal geschwungene Klammern zuviel ->

define Sonne notify test {\
my $Zeitstring = ReadingsVal('Local_Wetter', 'sunrise', '');;\
fhem ("define Sonnenaufgang at *$Zeitstring set Sonnen on");;\
Log 3,"$Zeitstring";;\
}
RPi4/Raspbian, CUL V3 (ca. 30 HomeMatic-devices), LAN (HarmonyHub, alexa etc.).  Fördermitglied des FHEM e.V.

Dr. Boris Neubert

Zitat von: MisterEltako schrieb am So, 24 Februar 2013 12:58define Sonnenaufgang at *{07:04:59} set Sonnen on : the at function "07:04:59" must return a timespec and not syntax error at (eval 101)


Bist Du sicher, daß Du das Sternchen davor willst?

Warum nutzt Du nicht die sunrise()-Funktion, die in FHEM eingebaut ist?

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

MisterEltako

@Dr.Boris Neubert

Hi!

Das "*" braucht man da nicht? Das at-Define wird in meinem Orginalcode bei jedem Weather-Event gelöscht und mit neueingelesenem Sunrise/Sunset wieder angelegt. Ich hoffe die Änderung an der 59_Weather.pm ist gestattet!?

Ich habe die Codezeilen unter "Codschnipsel" gepostet.

Das Weather-Modul von dir ist graphisch einfach Klasse. Die Anzeige mit den Wettersymbolen hat mich gleich begeistert. Ich möchte aber nur ein Wettermodul haben. Twillight hatte ich schon ausprobiert. Sunset/Sunrise aus dem geänderten Yahoowetter steuern jetzt meine Rollläden. Funktioniert prima und Sonnenauf- und Sonnenuntergang werden jetzt auch im Floorplan angezeigt.
Leider hat das aktuelle Update die Änderungen wieder rückgängig gemacht, damit blieben heute die Rollläden oben... :o(

Gibt es eine einfache Möglichkeit die mit ReadingsVal ermittelte Zeit des "sunrise" mit einem Offset zu addieren???

MfG, MisterEltako.
HMLAN-Konfigurations-Adapter, HM-Funkjalousieaktor/HM-Dimmaktor/HM-Schaltaktor f. Markenschalter, Jalousie-/Schaltaktor von Eltako, FT4 v. Eltako, TCM310

LaLeLu

LaLeLu

Fhem Release: 5.6 auf RaspberryPI B (wheezy)
1xFB7390, 1xCUL, 1xHM-CFG-LAN, 4xFHT, 25xFS20 (inkl. PIRA), 18xCUL_HM, 5xCUL_WS, 2xSONOS-Player, calendar, floorplan

MisterEltako

Hi!

Ja, danke. Damit arbeite ich bereits und es funktioniert auch. Ich finde nur das dies ziemlich viele Codezeilen für eine Rechnung z.B. (17:00:00 + 00:05:00) sind.

Kann das nicht noch einfacher sein? ;o)

MfG, MisterEltako.
HMLAN-Konfigurations-Adapter, HM-Funkjalousieaktor/HM-Dimmaktor/HM-Schaltaktor f. Markenschalter, Jalousie-/Schaltaktor von Eltako, FT4 v. Eltako, TCM310

Reinerlein

Hi MisterEltako,

ich verwende in meinem Modul folgende Codezeilen, die ich dazu einfach in eine eigene Sub-Prozedur (z.B. in myUtils.pm) gepackt habe:
use Time::Local;
if($timeStr =~ m/^(\d{4})-(\d{2})-(\d{2}) ([0-2]\d):([0-5]\d):([0-5]\d)$/) {
return timelocal($6, $5, $4, $3, $2 - 1, $1 - 1900);
}
Damit erhältst du aus dem Sring (in diesem Fall ein komplettes Datum wie "2013-02-24 10:07:12") den Sekunden seit Epoche-Wert, mit dem man dann einfach wieder rechnen kann.

Zurück funktioniert das ganze einfach mit "localtime" oder mit der dafür von FHEM bereitgestellten Funktion "FmtDateTime()".

Ich benötige das, da ich manchmal mit dem "Zeitwert" eines Readings rechnen können muss, und diese ja nur als String in diesem Format hinterlegt sind.

Grüße Reinerlein

P.S.: Als komplette Prozedur sähe das dann so aus:sub GetTimeFromString($) {
my ($timeStr) = @_;

eval {
use Time::Local;
if($timeStr =~ m/^(\d{4})-(\d{2})-(\d{2}) ([0-2]\d):([0-5]\d):([0-5]\d)$/) {
return timelocal($6, $5, $4, $3, $2 - 1, $1 - 1900);
}
}
}
mit dem "eval"-Block wird sichergestellt, dass FHEM nicht aussteigt, wenn das Modul Time::Local nicht gefunden werden sollte. Es steigt dann vermutlich erst aus, wenn dein "undef"-Rückgabewert verarbeitet werden soll :-)

P.P.S.: ich habe irgendwo gesehen, das man Codeblöcke auch "einklappen" kann. Wie muss ich das denn angeben?