Hallo
kann mir bitte jemand helfen
Ich möchte den Inhalt der dummy Variable Tagesverbrauch formatiert ausgeben.
attr Tagesverbrauch stateFormat {sprintf("%.2f kWh")} gibt natürlich nur 0.00 kWh aus. Wie muss ich die Zeile schreiben, dass der Inhalt der Variablen genommen wird?
LG
Reinhard
Hallo,
stateFormat {sprintf("%.2f"." W",ReadingsVal("Laptop_Lader_Mess","power",0))}
Grüße
danke!
Nur zum Verständnis, d.h. ich kann die Formatierung nur beim Einlesen vom Gerät (SO Zähler), bei mir in einem Modul in der 99_myUtils.pm machen. Die dummy Vatiable habe ich ja in der cfg definiert. Das Modul wird immer um Mitternacht gestartet. Da gibt es keine Möglichkeit die Formatierung in der cfg zu machen? state wird immer richtig aktualisiert, nur halt mit zig Kommastellen.
Wie meinst Du das? Welche Möglichkeit fehlt Dir noch? Du kannst ja alles in stateFormat machen... Ist doch "in cfg"...
Danke für die Antwort
ich habe folgendes in der cfg definiert:
# Ermittlung Strom Tagesverbrauch
define DailyPowerDiff dummy
attr DailyPowerDiff room hidden
define Tagesverbrauch dummy
attr Tagesverbrauch room Flur
# attr Tagesverbrauch stateFormat {sprintf("%.2f kWh")...............} hier möchte ich die Formatierung machen
define Tagesverbrauch_Haushalt at *23:59 {prg_Daily_Stat}
LG
Reinhard
Verstehe nicht ganz, was das tun soll...
Hast Du eine Funktion, die die Werte liefert und per AT in ein DUMMY schreibt? Und diesen möchtest Du noch formatieren? Warum dann nicht gleich in der Funktion selbst? Und auch wenn so, dann wo liegt noch das Problem? Bei Deinem sprintf fehlt natürlich noch der eigentliche Wert... etwas so:
...stateFormat {sprintf("%.2f kWh", ReadingsVal($name,"wasweissich",0))}
danke habs verstanden. Ich wollte es nicht in der Funktion machen, sondern direkt beim dummy, das wird ja ausgegeben, und wollte wissen wie es geht. Dachte es ist so eleganter.
Entschuldigt, habs doch noch nicht verstanden.
in der cfg steht folgendes:
# Ermittlung Strom Tagesverbrauch
define DailyPowerDiff dummy
attr DailyPowerDiff room hidden
define DailyPower dummy
attr DailyPower room Flur
define Tagesverbrauch_Haushalt at *23:59 {prg_Daily_Stat}
in der 99_myUtils.pm folgendes:
sub
prg_Daily_Stat()
{
#
# Zunächst Differenz aktueller Wert - Wert von Gestern berechnen
$data{DPval} = ReadingsVal("Counter","counters.A",0)/1000.0 - Value("DailyPowerDiff");
# Tagesverbrauch in DailyPower speichern
fhem ("set DailyPower $data{DPval}");
# Aktuellen Wert speichern
$data{DPval} = ReadingsVal("Counter","counters.A",0)/1000.0;
fhem ("set DailyPowerDiff $data{DPval}");
}
Das Ganze funktioniert, aber ich bekomme die Formatierung nicht hin. Wo und wie schreibe ich das stateFormat hin, Kann ich das in der cfg machen, oder nur im Unterprogram.
Vielen Dank
Reinhard
stateFormat ist ein Attribut an dem Device, dessen Reading Du umformatieren möchtest. Du kannst das Ganze in der Weboberfläche erzeugen.
Das wäre dann Config. Aber auch eine Formatierung im Code ist genauso möglich. Beantwortet das Deine Frage, oder habe ich Dich nicht richtig verstanden?
vielen Dank, die Theorie war mir schon klar, aber am wie scheitere ich noch. Ich habs über die Weboberfläche versucht, also in der config, bekomme dann aber keinen Wert mehr ausgegeben, sondern 0,00 kWh. Ich mache also was falsch?
Das es so nicht passt ist mir schon klar:
attr DailyPower stateFormat {sprintf("%.2f kWh",ReadingsVal($name,"DailyPower","?"))}
aber wie schreibe ich das Ganze, wenn ich den Inhalt der Dummy Variablen formatiert ausgeben möchte?
viele Grüße
Reinhard
Ich glaube, ich fange an, das Problem zu verstehen ;)
ReadingsVal liest in Deinem Fall ein Reading namens 'DailyPower' aud dem Dummy 'DailyPower'. Das Reading gibt es dort gar nicht. Also entweder Du setzt in Deinem Perl-Code ein entsprechendes Reading (mit setreading), oder, wenn Du Reading 'state' nutzt (mit set), dann benutze das:
attr DailyPower stateFormat {sprintf("%.2f kWh",ReadingsVal($name,"state","?"))}
Das setzt den internen Wert STATE (ist nicht ganz das gleiche wie Reading 'state') auf den formatierten String.
Hallo Hexenmeister,
vielen Dank, so funktioniert es. Jetzt hab ich es dank deiner Hilfe verstanden.
LG
Reinhard
Hallo,
Beiträge bitte nicht schließen.
Ein gelöst vor dem Titel genügt - siehe die anderen Beiträge.
Danke.
Grüße
Ok, sorry wusste ich nicht, bin ja neu hier
LG
Reinhard
Hallo,
ist kein Problem.
Dann hast du das http://forum.fhem.de/index.php/topic,16311.0.html (http://forum.fhem.de/index.php/topic,16311.0.html) ja gesehen ;)
Grüße
Wie kann ich eine Ausgabe einkürzen?
Ich habe als stateFormat für meinen Abfall Kalender folgendes: "next_text am next_date (next_weekday)".
Aber: in "next_date" steht auch die Uhrzeit am Ende, wie kann ich das auf die ersten 6 Zeichen einkürzen?
https://perldoc.perl.org/functions/substr.html
Und wie genau?
Wenn ich jetzt "next_text am {substr next_date, 4, 5;} (next_weekday)" eingebe klappt es nicht, er gibt es komplett so aus.
commandref/stateFormat:
Zitat
If the value of this attribute is enclused in {}, then it is evaluated.
Der komplette Wert (value) des Attributs muss ein gültiger Perlausdruck sein, nicht nur ein Teil davon. Wie zB. im 2. Beitrag dieses Threads gezeigt.
Ich komme nicht weiter...
SO läuft es jetzt: stateFormat {sprintf(ReadingsVal("Muelltonnen","next_date",0), ReadingsVal("Muelltonnen","next_weekday",0))}
Aber dann bekomme ich das substr nicht eingebunden.
ZitatIch komme nicht weiter...
Kann ich Dich mit Links zu Perlgrundlagen unterstützen?
Sorry, aber um 1x ein Problem zu lösen macht es m.M. nach wenig Sinn.
Wäre das selbe als wenn ich 1x in meinem Leben in einem besteimmten Land drei wochen Urlaub mache und dann die ganze Sprache lerne.
Mir geht es zwar im Hinblick auf dieses Problem (siehe Link) eigentlich genauso, wäre u.U. aber trotzdem an Links interessiert; zumindest mehr als daran, dass in diesem Thema seit 120 Tagen nichts mehr geschrieben wurde. ;D
Wenn ich mir Perl Grundlagen anschaue und diese mit dem einzeiligen funktionierenden Code (siehe Link) vergleich, verstehe ich z.B. gleich zu Beginn nicht, warum diese eine Zeile (siehe Link) funktioniert, obwohl die darin enthaltenen Befehle nicht mit ";" abgeschlossen werden. Bitte keine aufs Dach haun fürs Crossposting. Ich such mir nur nen Wolf für mein Problem und find selbst in den tiefsten Tiefen des Forums nix Passendes. :(
Gruß Chris
Link: https://forum.fhem.de/index.php/topic,98357.msg917562.html#msg917562 (https://forum.fhem.de/index.php/topic,98357.msg917562.html#msg917562)
Hi Chris,
irgendwie versteh ich deine Frage nicht!?
Perl Befehle müssen "im Block" von einander mit ; getrennt werden. Ob die in mehreren oder einer Zeile stehen spielt keine Rolle.
Beispiel: 2 Befehle in einem Perl Script (am Ende der Große Block aussen herum)
my $s = "The black cat climbed the green tree";
my $color = substr $s, 4, 5;
In deinem Link ist ein Befehl mit einzelnen Perlblöcken {}:
{if(Bedingung) {Perlbefehl} else {Perl Befehl}}
Bei meheren Befehlen im Block sähe es so aus.
{if(Bedingung) {Perlbefehl1;Befehl2;Befehl3} else {Perlbefehl1;Befehl2;Befehl3;Befehl4}}
Ein Zitat aus perldoc.perl.org
ZitatBut generally, a block is delimited by curly brackets, also known as braces. We will call this syntactic construct a BLOCK.
The following compound statements may be used to control flow:
if (EXPR) BLOCK
if (EXPR) BLOCK else BLOCK
if (EXPR) BLOCK elsif (EXPR) BLOCK ...
if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
...
Gruß Otto
Aber hier finden doch z.B. ganz viele Dinge völlig unabhängig in einem Block statt, ohne dass auch nur ein einziges ";" gesetzt ist:
{"Wind: ".round(ReadingsVal("Wetterstation","wind_speed",0),0).
" Böen: ".round(ReadingsVal("Wetterstation","wind_gust",0),0).
"<br>UVR: ".round(ReadingsVal("Wetterstation","UVR",0),1).
" LF: ".round(ReadingsVal("Wetterstation","humidity",0),0)."%"}
Da findet wohl eine Trennung durch Punkte statt. Mache ich dann aber das hier..
{"Wind: ".round(ReadingsVal("Wetterstation","wind_speed",0),0).
" Böen: ".round(ReadingsVal("Wetterstation","wind_gust",0),0).
"<br>UVR: ".round(ReadingsVal("Wetterstation","UVR",0),1).
" Hum: ".round(ReadingsVal("Wetterstation","humidity",0),0).
if(ReadingsVal("Wetterstation","UVR",0)>=10) {round(ReadingsVal("Wetterstation","UVR",0),0)} else {round(ReadingsVal("Wetterstation","UVR",0),1)}
..kommt eine Fehlermeldung. :-\
Weil der "." kein ";" ist, sondern Strings verbindet ....
Auch fehlt mir eigentlich ein print o.Ä.
Zitat von: Wernieman am 11 März 2019, 14:37:50
Weil der "." kein ";" ist, sondern Strings verbindet ....
Auch fehlt mir eigentlich ein print o.Ä.
Hmm, na ja, "an sich" funktioniert das schon, aber dann müssen m.E. die einzelnen Anweisungen unmittelbar Ergebnisse liefern. Deswegen funktioniert der erste code vermutlich, der zweite nicht (vielleicht aber doch, wenn man eine Klammer um die if-Geschichte macht).
(Unterstellt, der erste geht wirklich,) müßte eigentlich sowas hier auch gehen:
{my $uvr = round(ReadingsVal("Wetterstation","UVR",0),1); $uvr = round(ReadingsVal("Wetterstation","UVR",0),0) if(ReadingsVal("Wetterstation","UVR",0)>=10);
"Wind: ".round(ReadingsVal("Wetterstation","wind_speed",0),0).
" Böen: ".round(ReadingsVal("Wetterstation","wind_gust",0),0).
"<br>UVR: ".$uvr.
" Hum: ".round(ReadingsVal("Wetterstation","humidity",0),0)}
Aber m.E. ist es übersichtlicher, erst ein paar Variablen zu definieren und dann hinterher nur den Gesamtausdruck zusammenzusetzen.
Auch möglich: den Rückgabewert erst zu initialisieren (my $ret;) und dann jeweils
$ret .= "Wind: ".round(ReadingsVal("Wetterstation","wind_speed",0),0);
Und am Ende dann $ret zurückgeben.
Ich musste im Rahmen meines FHEM-Systems bisher noch keine Variablen selber definieren, von daher hatte ich mich bisher noch nicht damit beschäftigt. Ich werde mich da aber mal reinlesen. Der Code funktioniert jedenfalls astrein, Beta-User. Vielen Dank!
Gruß Chris
Danke für die Rückmeldung.
Habe erst nach dem "Schreiben" noch eine kleine Optimierungsmöglichkeit gesehen:
$uvr = round($uvr,0) if($uvr>=10);
(Statt der wiederholten Rückgriffe auf das Reading).
@Chris Noch zur Erklärung:
Was Du da in #24 hast ist von der Sache her kein Block mit Perl Befehlen die nacheinander abgearbeitet werden sondern ein String, der aus mehreren Ergebnissen von Perl Befehlen zusammengesetzt wird -> concatenation falls Du nachlesen willst. Die concatenation passiert mit dem Punkt zwischen den Strings.
{"Wind: ".Befehl1(Befehl2(),0).
" Böen: ".Befehl3(Befehl4(),0).
"<br>UVR: ".Befehl5.
" LF: ".Befehl6."%"}
Jeder Befehl könnte aber auch wieder ein Perl Block sein, ist es aber in deinem Fall nicht. Ein Befehl ruft den anderen als Sub auf, da braucht es kein Semikolon.
Bei dem Code von Beta User ist das dann genau der Fall: Er baut vornan einen Befehlsblock am Ende wird dann wieder der String zusammen getackert.
Gruß Otto