String formatieren, sprintf?

Begonnen von Gidiano, 20 März 2020, 12:31:10

Vorheriges Thema - Nächstes Thema

Gidiano

Hallo zusammen,

zunächst habe ich mir selbst einen abgebrochen und das Internet durchsucht, für diese Kopfnuss reicht es jedoch noch nicht bei mir.
Ich möchte den String in diesem Format
20.03.2020 10:36 20.03.2020 11:00

umwandeln in einen String, den ich an diese Funktion übergeben kann:
{Abwesend ("temp", "StartDatum", "StartZeit", "EndDatum" ,"EndZeit")}

Also so:
"18", "20.03.2020", "10:36", "20.03.2020", "11:00"

Mit einem abenteuerlichen Konstrukt aus split und join habe ich das schon bewerkstelligt, aber es sieht gruselig kompliziert aus.

Kann ich da nicht sprintf nehmen und meine "18", davorpappen?

Der String kommt mittels folgendem code aus einem Kalender:

Urlaubskalender:changed:.* {
my $uid= "$EVTPART1";;
my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Urlaub",uid=="'.$uid.'" limit:count=1 format:custom="$T1 $T2"');;
fhem("set Absent $mystring");;
}


Mein Ansatz wäre, $mystring vor der Übergabe an den Dummy final zu formatieren.

Ich kriegs echt nicht hin :o

Viele Grüße
Christian
Grüße,
Christian

CoolTux

my ($temp,$startDatum,$startZeit,$endDatum,$endZeit) = split ' ', $string;

Ich finde das jetzt nicht unbedingt kompliziert. Vorausgesetzt Dein String stimmt mit
20.03.2020 10:36 20.03.2020 11:00
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Gidiano

Danke für die schnellen Infos!
Bin halt nicht so der Experte.

Bei Deinem Beispiel weiß ich leider nicht, wie ich es implementieren soll.

Ich hatte es so probiert:
get Urlaubskalender events filter:field(categories)=~"Urlaub" format:custom={ substr(join('", "', split(/ /, " $T1 $T2"), " "),3, 44) }

Damit bekomme ich zumindest sowas:
"08.04.2020", "00:00", "14.04.2020", "00:00"

So wie oben angegeben klappt es, wenn ich es direkt in die Befehlszeile eingebe.
Wenn ich den part
... format:custom={ substr(join('", "', split(/ /, " $T1 $T2"), " "),3, 44) }

in das Def meines notify (wie in meinem ersten Post) eingebaut funktioniert es dann leider nicht.

Viele Grüße
Christian
Grüße,
Christian

CoolTux

Was steht denn im $mystring wenn Du im Notify das hier nur ein gibst
my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Urlaub",uid=="'.$uid.'" limit:count=1 format:custom="$T1 $T2"');;
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Gidiano

In $mystring steht dann (z. B)
20.03.2020 10:36 20.03.2020 11:00

D. h. ich bin damit dem Ziel schon nahe. Scheitert halt noch an dem Format-Umbau.

Viele Grüße
Christian
Grüße,
Christian

CoolTux

Und warum machst du es dann nicht wie ich oben geschrieben habe?
Machst halt jeden Schritt einzeln.


my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Urlaub",uid=="'.$uid.'" limit:count=1 format:custom="$T1 $T2"');

my ($temp,$startDatum,$startZeit,$endDatum,$endZeit) = split ' ', $mystring;


Und kannst dann die einzelnen variablen verwenden.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Macht Euch doch das Leben nicht so schwer...

Wenn man schon mit einem custom format arbeitet, packt man die 18 gleich dort mit rein


my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Urlaub",uid=="'.$uid.'" limit:count=1 format:custom="18 $T1 $T2"');;


und übergibt dann $mystring gesplittet an die gewünschte Funktion


{ Abwesend(split(" ",$mystring)) }

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

Gidiano

Die 18 gleich mit reinzunehmen ist natürlich super.

Aktuell tüftel ich aber noch damit den gesplitteten String richtig zusammenzubauen:
Ein " ganz vorn und eins am Ende. Aber die Leerzeichen darin werden mit ", " ersetzt.

Ich bin dran, geht halt bei mir nur im Schneckentempo...
Grüße,
Christian

Gidiano

Vielleicht ein Detail noch.
Der Befehl mit exakt wie in diesem Beispiel mit Anführungszeichen übergeben werden:
Abwesend ("18", "12.03.15", "14:00", "15.03.15" ,"12:00")

Den genau so hinzukriegen ist meine Herausforderung.
Grüße,
Christian

Gidiano

So, ich habs:
DEF
Urlaubskalender:changed:.* {
my $uid= "$EVTPART1";;
my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Urlaub",uid=="'.$uid.'" limit:count=1 format:custom="18 $T1 $T2"');;
my ($temp,$startDatum,$startZeit,$endDatum,$endZeit) = split ' ', $mystring;;
my $absence= substr(join('", "', split(/ /, " $mystring"), " "),3, 50);;
fhem("set Absent $absence");;
}


Rückgabe:
"18", "20.03.2020", "17:26", "20.03.2020", "17:44"

Kann man wahrscheinlich eleganter machen, aber da ich nicht so die Perl(e) bin ist das immer ganz gut, wenn ich das später mal wieder mehr oder minder nachvollziehen kann.

Vielen Dank euch beiden!
Grüße,
Christian

betateilchen

Um verstehen, was Du da machst, wäre es vielleicht hilfreich, wenn man den Inhalt der Funktion Abwesend() kennen würde.

Wozu um alles in der Welt brauchst Du die Anführungszeichen und wozu einen String, der Funktionswerte als Text enthält?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Gidiano

Ja, das hätte ich mitliefern sollen, da hast Du Recht.
Vor Jahren habe ich einmal diese Funktion (wahrscheinlich hier) "abgestaubt":
(hab den Post nicht wiedergefunden, sonst hätte ich drauf verlinkt)
my $Abwesend;
sub
Abwesend($$$$$)
  {
    #lokale Variablendeklaration
    my ($temp,$startDate,$startTime,$endDate,$endTime) = @_;

    # HM-CC-RT-DN akzeptiert nur Zeiten, die auf Minute 00 oder 30 enden.
    # Daher $startTime und $endTime abrunden
    $startTime =~ s/\:[0-2].$/:00/;
    $startTime =~ s/\:[3-5].$/:30/;
    $endTime =~ s/\:[0-2].$/:00/;
    $endTime =~ s/\:[3-5].$/:30/;

    #Sendebefehl für ein HM-CC-RT-DN
    #An die einzelnen Heizungen schicken
    {fhem ("set Heizung_SZ_Clima controlParty $temp $startDate $startTime $endDate $endTime")}
    {fhem ("set Heizung_GZ_Clima controlParty $temp $startDate $startTime $endDate $endTime")}
    {fhem ("set Heizung_WZ_Sued_Clima controlParty $temp $startDate $startTime $endDate $endTime")}
    {fhem ("set Heizung_WZ_Nord_Clima controlParty $temp $startDate $startTime $endDate $endTime")}
    #{fhem ("set Heizung_Bad_Clima controlParty $temp $startDate $startTime $endDate $endTime")}
   }


Manuell ging es gut zu bedienen, aber ich musste immer die ganze Befehlszeile manuell zusammenbauen. So wird sie nun aus dem Kalender gelesen.
Also eine Heizungssteuerung durch den Kalender.
Grüße,
Christian

betateilchen

dafür brauchst Du aber den ganzen Mist nicht, den Du da zusammenschraubst.

Wenn Du die Funktion so aufrufst, wie ich es in meinem Post oben geschrieben habe, sollte es auch funktionieren.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Außerdem geht eine Heizungssteuerung über einen Kalender sehr viel einfacher.

Schau mal in den angepinnten Beitrag im Unterforum für Kalender.

Direkter Link zum Thread: https://forum.fhem.de/index.php/topic,87895.0.html
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Gidiano

So, nach einer "kleinen" Unterbrechung habe ich hier mal weitergemacht.
Danke für Deinen Hinweis betateilchen, das schaue ich mir auch an.

Da fhem ja auch eine Spielwiese zum Ausprobieren diverser Dinge ist, darf es bei mir ruhig auch mal verknausulierten Code geben. Da ich nicht dauern dran arbeite, lässt sich das auch später von mir auch halbwegs wieder nachvollziehen:

Ich habe das jetzt mal so gemacht und es funktioniert seit heute:
Urlaubskalender:changed:.* {
my $uid= "$EVTPART1";;
my $mystring= fhem('get Urlaubskalender events filter:field(categories)=~"Homematic",uid=="'.$uid.'" limit:count=1 format:custom="$T1 $T2"');;
my $temp= 18;;
my ($startDatum,$startZeit,$endDatum,$endZeit) = split ' ', $mystring;;
$startZeit =~ s/\:[0-2].$/:00/;;
$startZeit =~ s/\:[3-5].$/:30/;;
$startDatum = substr(($startDatum),0,8);;
#-$endZeit =~ s/\:[0-2].$/:00/;;
#-$endZeit =~ s/\:[3-5].$/:30/;;
$endZeit = "04:00";;
$endDatum = substr(($endDatum),0,8);;
my $absence= join(" ", $startDatum,$startZeit,$endDatum,$endZeit);;
fhem("set Absent $absence");;
fhem ("set Heizung_SZ_Clima controlParty $temp $startDatum $startZeit $endDatum $endZeit");;
#--Weiterer Code zum Abstellen unnötiger Verbraucher hier--
}


Heraus kommen Daten, die so an den Thermostaten geschickt werden:

18 HH:MM DD:MM:YY HH:MM DD:MM:YY

Weil ich es eigentlich nicht brauche das Ende des Party-Modus der Homematic-Themostaten zu errechnen, setze ich den Wert statisch auf 04:00 Uhr.
Grüße,
Christian