FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Damian am 01 April 2026, 23:06:56

Titel: Energy-Card
Beitrag von: Damian am 01 April 2026, 23:06:56
Edit:

Die aktuelle Version der Energie-Karte wurde ins Wiki übernommen:
https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Visualisierung:_Energiefluss_als_Energie-Karte

Hier der Link zu kompakten Energie-Karte:
https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Visualisierung:_Energiefluss_als_kompakte_Energie-Karte
Titel: Aw: Energy-Card
Beitrag von: schwatter am 02 April 2026, 08:40:44
Sehr schön das du dir jetzt die Zeit nimmst.
Sieht auch schon ansehnlich aus  :)

Edit:
Und sofort kommen Wünsche. Wenn möglich Mobile und Desktop berücksichtigen. Bzw. wenn möglich,
min 2 Größen über Settings ermöglichen.

Gruß schwatter
Titel: Aw: Energy-Card
Beitrag von: Damian am 02 April 2026, 11:57:11
Zitat von: schwatter am 02 April 2026, 08:40:44Und sofort kommen Wünsche. Wenn möglich Mobile und Desktop berücksichtigen. Bzw. wenn möglich,
min 2 Größen über Settings ermöglichen.


Es ist bisher nur über uitable definiert, also ein DOIF-Device. Die Berechnung der einzelnen Werte kommt von außerhalb. Eine Skalierbarkeit ist ein Muss, aber noch nicht realisiert. Ebenfalls müssen Animationen abschaltbar sein, sonst kostet es einfach zu viel Performance insb. über Remoteverbindung. Ebenfalls fehlt mir noch der Verlauf einzelner Werte mit statistischer Auswertung ala card. Ich denke, ich werde eine einfache Version machen und eine umfangreichere. Immerhin ist es recht effizient definiert/programmiert - es werden nur Sachen zum Browser übertragen, die sich ändern, also nicht bei jedem Trigger, und davon gibt es viele, die ganze Grafik.
Titel: Aw: Energy-Card
Beitrag von: Damian am 04 April 2026, 12:52:28
Zweiter Entwurf mit Verlaufsdiagrammen

Screenshot 2026-04-04 125018.png
Titel: Aw: Energy-Card
Beitrag von: appi am 05 April 2026, 17:41:54
Hallo Damian
sieht mega aus, super das du weiter machst mit FHEM.
Als ungeduldiger Mensch kommt natürlich die Frage..... wann wird die Energy-Card zum testen verfügbar werden.
gruss Remo
Titel: Aw: Energy-Card
Beitrag von: Damian am 05 April 2026, 21:45:21
Zitat von: appi am 05 April 2026, 17:41:54Hallo Damian
sieht mega aus, super das du weiter machst mit FHEM.
Als ungeduldiger Mensch kommt natürlich die Frage..... wann wird die Energy-Card zum testen verfügbar werden.
gruss Remo

Ich bin kurz vor der Vollendung. Problem bereitet mir noch die Animation. Diese wird unterbrochen und neu gestartet, wenn sich der Wert (hier: Leistung) ändert. Das sieht nicht gut aus, wenn die Werte sich in kurzen Abständen ändern. Da muss ich noch etwas rumexperimentieren. Bis dahin will ich noch nichts posten, solange es nicht rundläuft.

Was ich aber schon sagen kann:

-die komplette Definition steckt im uiTable-Attribut und kann beliebig angepasst werden, sie nutzt vorhandene uiTable-Funktionen
-die gesamte Karte lässt sich mit einem Zoomparameter beliebig skalieren
-alle dargestellten Werte müssen im FHEM-System vorhanden sein, sie werden nicht in der Karte erzeugt bzw. berechnet.

Sobald ich fertig bin, werde ich die Definition hier posten.
Titel: Aw: Energy-Card
Beitrag von: Dr. Boris Neubert am 07 April 2026, 20:27:18
Meine 240x240-Pixel-Variante muss mit weniger Informationen auskommen, damit sie auf dem GIFTV lesbar bleibt.

Ist off-topic, aber vielleicht hat das schon jemand von den Mitlesern hinbekommen: automatisch Fotos nach Amazon Photos hochschieben (analog zu push2giftv). Dann könnte der alte Echo Show mal was anderes als Amateur Foodporn (https://de.wikipedia.org/wiki/Foodporn) anzeigen.
Titel: Aw: Energy-Card
Beitrag von: Damian am 17 April 2026, 20:51:40
Ich habe nun die Energy_card fertiggestellt. Dafür wurde allerdings eine neue DOIF-Version erstellt. Diese erlaubt nun ohne Umwege Javascript auszuführen. Das war erforderlich damit ich per Änderung von CSS-Attributen den animierten Energiefluss abhängig von der Leistung dynamisch anpassen konnte.

Die Definition kann beliebig angepasst werden. Man könnte z. B. statt Haus sein E-Auto darstellen.

Im einfachsten Fall braucht man am Ende in der Tabellendefinition nur die Readings auf eigene anzupassen und jeweils die maximale Leistung entsprechend zu ändern.

Die Geschwindigkeit und die Richtung der Stromfluss-Animation wird abhängig der aktuellen Leistung visualisiert, siehe GIF-Animation im Anhang.

Aktuelle DOIF-Definition und weiter Features siehe erster Post: https://forum.fhem.de/index.php?topic=144357.msg1361012#msg1361012

Screenshot 2026-04-17 204832.png
Titel: Aw: Energy-Card
Beitrag von: Per am 17 April 2026, 22:02:15
Andere Frage: warum wird der Speicher bei 89% schon nicht mehr geladen?
Titel: Aw: Energy-Card
Beitrag von: Damian am 17 April 2026, 22:03:52
Zitat von: Per am 17 April 2026, 22:02:15Andere Frage: warum wird der Speicher bei 89% schon nicht mehr geladen?

Weil ich ihn auf 90 % begrenzt habe.
Titel: Aw: Energy-Card
Beitrag von: appi am 17 April 2026, 22:37:18
sieht ja super aus, bereits am laufen, allerdings kämpfe ich noch mit den Werten. Wo soll ich am besten W in KW umrechnen?
Direkt in der uiTable Reading definition?
Titel: Aw: Energy-Card
Beitrag von: Damian am 17 April 2026, 22:41:09
Zitat von: appi am 17 April 2026, 22:37:18sieht ja super aus, bereits am laufen, allerdings kämpfe ich noch mit den Werten. Wo soll ich am besten W in KW umrechnen?
Direkt in der uiTable Reading definition?
Entweder im ursprünglichen Device als userReading oder du definierst dir ein DOIF-Reading in der Energy_Card selbst, welches du in uiTable angibst.
Titel: Aw: Energy-Card
Beitrag von: Wzut am 18 April 2026, 09:08:41
Könntest bitte alle deine Readingsnamen nach Bedeutung  aufschlüsseln ?
Bei quota_powGetBpCms handelt es sich vermutlich um den aktuellen Ladestrom der Batterie und bei quota_soc um den aktuellen Ladezustand.
Aber der Rest ist doch sehr kryptisch, zumal einige Readings wohl nicht von einem Gerät direkt stammen sondern in einem anderen DOIF erst gebildet werden bsp total_f.day
Titel: Aw: Energy-Card
Beitrag von: Damian am 18 April 2026, 09:32:33
Zitat von: Wzut am 18 April 2026, 09:08:41Könntest bitte alle deine Readingsnamen nach Bedeutung  aufschlüsseln ?
Bei quota_powGetBpCms handelt es sich vermutlich um den aktuellen Ladestrom der Batterie und bei quota_soc um den aktuellen Ladezustand.
Aber der Rest ist doch sehr kryptisch, zumal einige Readings wohl nicht von einem Gerät direkt stammen sondern in einem anderen DOIF erst gebildet werden bsp total_f.day

Ich habe die Readingnamen angepasst und die Definition in den ersten Post verlagert. Später wird es dazu eine Wiki-Beschreibung geben.
Titel: Aw: Energy-Card
Beitrag von: Damian am 19 April 2026, 13:39:57
Hier mal eine kompakte mobile Version. Die Bedeutung der Readings kann man im ersten Post nachschauen.
Edit: kleine Code-Änderungen
defmod di_energy_card_min DOIF {}
attr di_energy_card_min uiTable {\
$ATTRIBUTESFIRST = 1;;\
\
## Energy_card kann über das Attribut zoom skalliert werden\
\
$TABLE = 'zoom: 1;; width: 212px;; height: 195px;; text-align: left;; vertical-align: top;; border-radius:0%;;  position:relative;; background: linear-gradient(to bottom, rgb(40,40,40), rgb(60, 60, 60));; ';;\
\
package ui_Table;;\
\
sub move {\
my ($left, $top, $content) = @_;;\
my $value;;\
if (ref($content) eq "ARRAY") {\
  $value = $content->[0];;\
} else {\
  $value =$content;;\
}\
\
my $out = '<div style="position:absolute;; left:'\
  . $left . 'px;; top:'\
  . $top . 'px;;">'\
  . $value .\
  '</div>';;\
  \
if (ref($content) eq "ARRAY") {\
  return ([$out,$content->[1]]);;\
} else {\
  return ($out);;\
}\
}## end of move\
\
sub flow {\
\
my ($d,$item,$power,$max,$direction)=@_;;\
my $dur;;\
if ($power == 0) {\
  $dur=0;;\
} else {\
  $power=$max if ($power>$max);;\
  $dur=6-abs(int(5*$power/$max));;\
}\
\
\
my ($from, $to, $x1, $x2, $y1, $y2);;\
\
if ($direction==0) {        # ↖ unten rechts -> oben links\
  ($from, $to, $x1, $x2, $y1, $y2)=("1 1","-1 -1",100,0,100,0);;\
} elsif ($direction==1) {   # ↘ oben links -> unten rechts\
  ($from, $to, $x1, $x2, $y1, $y2)=("-1 -1","1 1",0,100,0,100);;\
} elsif ($direction==2) {   # ↗ unten links -> oben rechts\
  ($from, $to, $x1, $x2, $y1, $y2)=("-1 1","1 -1",0,100,100,0);;\
} elsif ($direction==3) {   # ↙ oben rechts -> unten links\
  ($from, $to, $x1, $x2, $y1, $y2)=("1 -1","-1 1",100,0,0,100);;\
}\
\
my $out='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 35" width="40" height="35" style="width:40px;; height:35px;;">';;\
\
$out .= '<defs>\
<linearGradient id="flowGradient_'.$item.'" \
    x1="'.$x1.'%" y1="'.$y1.'%" \
    x2="'.$x2.'%" y2="'.$y2.'%" \
    >\
    <stop offset="0%" stop-color="white" stop-opacity="0.2"/>\
    <stop offset="80%" stop-color="white" stop-opacity="1"/>\
    <stop offset="100%" stop-color="white" stop-opacity="0.2"/>\
    <animateTransform \
        id="flowAnim_'.$item.'" \
        attributeName="gradientTransform" \
        type="translate" \
        from="'.$from.'" \
        to="'.$to.'" \
        dur="'.$dur.'s" \
        repeatCount="indefinite" \
        calcMode="linear"/>\
</linearGradient>\
</defs>\
<path d="'.$d.'" fill="none" stroke="url(#flowGradient_'.$item.')" stroke-width="5" />';;\
\
##$out .= '<defs> <linearGradient id="flowGradient_'.$item.'" x1="'.$x1.'%" y1="0%" x2="'.$x2.'%" y2="0%"> <stop offset="0%" stop-color="gray" stop-opacity="0.2"/> <stop offset="100%" stop-color="white" stop-opacity="1"/> <stop offset="0%" stop-color="gray" stop-opacity="0.2"/></defs><path d="'.$d.'" fill="none" stroke="gray" stroke-opacity="0.2" stroke-width="3"/><path d="'.$d.'" fill="none" stroke="url(#flowGradient_'.$item.')" stroke-width="2" stroke-dasharray="3 9"><animate id="flowAnim_'.$item.'" attributeName="stroke-dashoffset" from="'.$from.'" to="'.$to.'" dur="'.$dur.'s" repeatCount="indefinite"/></path>';;\
\
return ([$out,'var e=document.getElementById("flowAnim_'.$item.'");;if (e) {e.setAttribute("dur","'.$dur.'s");;e.setAttribute("from","'.$from.'");;e.setAttribute("to","'.$to.'");;};; var e=document.getElementById("flowGradient_'.$item.'");;if (e) {e.setAttribute("x1","'.$x1.'%");;e.setAttribute("x2","'.$x2.'%");;e.setAttribute("y1","'.$y1.'%");;e.setAttribute("y2","'.$y2.'%");;}'])\
}  ## end of flow\
\
sub grid_power {\
my ($power,$max)=@_;;\
return (move(30,64,flow("M 5 0 A 30 30 0 0 0 35 30","grid",$power,$max,($power  > 0 ? 0 : 1))));;\
} \
\
sub solar_power {\
my ($power,$max)=@_;;\
  return move(138,64,flow("M 35 0 A 30 30 0 0 1 5 30 L 5 30","solar",$power,$max,3));;\
} \
\
sub home_power {\
my ($power,$max)=@_;;  \
return move(30,94,flow("M 5 35 A 30 30 0 0 1 35 5","home",$power,$max,3));;\
}\
\
sub battery_power {\
my ($power,$max)=@_;;\
return move(138,94,flow("M 35 35 A 30 30 0 0 0 5 5 ","battery",$power,$max,($power < 0 ? 0:1)));;\
}\
\
sub grid {\
my ($power,$feed,$consum)=@_;;\
move(2,2,icon_ring2("scene_power_grid\@silver",$power,-5,5,0,90,"kW",110,undef,"2",$feed-$consum,-20,20,0,90,"kWh",undef,"1",undef,"nogradient,,innerring,nopointer,negzeropos"));;\
}\
\
sub self {\
my ($autark,$EVG)=@_;;\
move(64,60,ring2($autark,0,100,undef,undef,"Autarkie",130,[(33.3,40,66.6,65,100,85)],"0,,fill:silver, %",$EVG,0,100,190,170,"EVQ",undef,"0,,fill:silver, %",undef,undef,"nogradient,,innerring,nopointer")) # [(33.3,40,66.6,65,100,85)]\
}\
\
sub solar {\
my ($power,$energy)=@_;;\
move(140,2,icon_ring2("solar_icon\@silver",$power,0,3.6,30,90,"kW",110,undef,"2",$energy,0,30,30,90,"kWh",undef,"1",undef,"nogradient,,innerring,nopointer"));;\
}\
\
sub home {\
my ($power,$consum)=@_;;\
move(2,130,icon_ring2("fa_home\@silver",$power,0,3,60,10,"kW",110,undef,"2",$consum,0,10,60,10,"kWh",undef,"1",undef,"nogradient,,innerring,nopointer"));;\
}\
\
sub battery {\
my ($power,$cap)=@_;;\
move(140,130,icon_ring2("battery_100\@silver",$power/1000,-1,1,220,170,"kW",110,undef,"2",$cap,0,100,0,90,"%",undef,"0",undef,"nogradient,,noinnerring,nopointer,zeronegpos"));;\
}\
\
} ## end of perl area\
\
## Tabellendefinition\
## Hier eigene Readings anpassen\
\
grid([MQTT2_DVES_C58DCB:power_fc],[di_counter_new:MQTT2_DVES_C58DCB.total_f.day],[di_counter_new:MQTT2_DVES_C58DCB.total_c_positiv.day]).\
solar([MQTT2_DVES_C58DCB:power_pv],[di_counter_new:MQTT2_DVES_C58DCB.total_pv.day]).\
home ([MQTT2_DVES_C58DCB:power_home_c],[di_counter_new:MQTT2_DVES_C58DCB.total_home_c.day]).\
battery([ecoflowStreamACpro:quota_powGetBpCms],[ecoflowStreamACpro:quota_soc]).\
self(([di_counter_new:MQTT2_DVES_C58DCB.total_pv.day]-[di_counter_new:MQTT2_DVES_C58DCB.total_f.day])/[di_counter_new:MQTT2_DVES_C58DCB.total_consum.day]*100,(1-[di_counter_new:MQTT2_DVES_C58DCB.total_f.day]/[di_counter_new:MQTT2_DVES_C58DCB.total_pv.day])*100).\
grid_power([MQTT2_DVES_C58DCB:power_fc],3.6).\
solar_power([MQTT2_DVES_C58DCB:power_pv],3.6).\
battery_power([ecoflowStreamACpro:quota_powGetBpCms],1050).\
home_power([MQTT2_DVES_C58DCB:power_home_c],3.6)
Screenshot 2026-04-19 133239.png
Titel: Aw: Energy-Card
Beitrag von: jkriegl am 21 April 2026, 15:25:15
Sorry für meine Ungeduld.
Habe den code energy_card_min übernommen.
Da ich nur ein Balkon-KW und keine Batterie habe, habe ich Anpassungen vorgenommen.
Der Überschuss wird in battery angezeigt, sowie in den rings aktuelle Verbräuche/Erträge.
Sieht eigentlich schon sehr gut aus, aber
bei grid-Bezug läuft die Animation von self -> grid also falsch (Bei Einspeisung gar nichts, aber bei Überschuss korrekt von self -> battery).
Den 3. Parameter von grid "total_c_positiv.day" habe ich auf Null gesetzt, weil nicht verstanden (andere Werte verändern den Tagesbezug).
Auf dem Bild unten ist meine derzeitige Visualisierung (Auszug) mit enthalten.
Wie kann ich die Animation bei Einspeisung auf grid-> self ändern?
Kann man evtl. die Animation self -> battery entfernen, falls grid <-> self in beide Richtungen möglich ist?


Titel: Aw: Energy-Card
Beitrag von: Damian am 21 April 2026, 18:24:31
Die Aufrufe der jeweiligen Funktionen entsprechen denen aus dem ersten Post:

grid([Netz:Leistung_Einspeisung_Bezug],[Netz:Energie_des_Tages_Einspeisung],[Netz:Energie_des_Tages_Bezug]).\
solar([PV:Leistung],[PV:Energie_des_Tages]).\
home ([Haus:Leistung_Bezug],[Haus:Energie_des_Tages_Bezug]).\
battery([Speicher:Leistung_Laden_Entladen],[Speicher:Kapazität]).\
## Visualisierung von Autarkie und Eigenverbrauchsquote als Ring\
self([Energie:Autarkie],[Energie:Eigenverbrauchsquote]).\
## Visualisierung der Energieflüsse, der zweiter Parameter ist die maximale Leistung\
grid_power([Netz:Leistung_Einspeisung_Bezug],3.6).\
solar_power([PV:Leistung_PV],3.6).\
battery_power([Speicher:Leistung_Bat],1).\
home_power([Haus:Leistung_Bezug],3.6)

Jede Funktion bildet ein Element ab. Die mit "_power" am Ende sind für die Animation zuständig (zweiter Parameter ist die maximale Leistung). Die Animationen (bis auf home) sind für beide Richtungen ausgelegt, abhängig davon, ob der Leistungswert positiv oder negativ ist. Möchte man z. B. keine Batterie haben, löscht man die beiden Zeilen, die mit "battery" beginnen.

Ich bastle an eine Version, wo man nur seine Readings und seine maximalen Werte zentral definiert, ohne den Code anpacken zu müssen.
Titel: Aw: Energy-Card
Beitrag von: jkriegl am 22 April 2026, 13:21:53
Vielen Dank für die schnelle Antwort, funktioniert bestens. Das Problem lag an der Einstellung max. Leistung (bei mir W)
Titel: Aw: Energy-Card
Beitrag von: Per am 22 April 2026, 14:07:45
Zitat von: Damian am 21 April 2026, 18:24:31Möchte man z. B. keine Batterie haben, löscht man die beiden Zeilen, die mit "battery" beginnen.
Du kannst ja "wenn max XXX=0 dann XXX disableld" machen
Titel: Aw: Energy-Card
Beitrag von: Damian am 22 April 2026, 22:40:49
Ich habe einen Wiki-Beitrag mit neuem Code zu der kompakten Energie-Karte verfasst.

Ich habe jetzt die gesamte Definition der erforderlichen Perlfunktionen in den Definitionsbereich des DOIF-Devices gepackt (subs-Block). Dort sind zu Anfang aller erforderlichen Maximalwerte definiert und beschriftet. Alle erforderlichen Readings befinden sich jetzt im Attribut DOIF-Readings, haben selbsterklärende Namen und müssen nur noch dort angepasst werden. Das Attribut uiTable beinhaltet nur noch die Definition der Tabelle mit den Aufrufen der Perlfunktionen. Es muss nicht mehr angepasst werden, wenn man das Layout nicht verändern will.

Edit:
https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Visualisierung%3A_Energiefluss_als_kompakte_Energie-Karte
neue Seite: https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Visualisierung%3A_Energiefluss_als_kompakte_Energie-Karte


Aus irgendwelchen Gründen wird der Code nicht farblich hervorgehoben. Möglicherweise ist die Wiki-Seite inzwischen zu groß geworden. Vermutlich werde ich die Anwendungsbeispiele auf eine neue Wiki-Seite auslagern.

uiTable-Anwendungen wurde auf eine eigene Wiki-Seite ausgelagert, da die bisherige Wiki-Seite zu groß geworden war. Jetzt wird der Code wieder farblich hervorgehoben.
Titel: Aw: Energy-Card
Beitrag von: Damian am 23 April 2026, 18:57:12
Auch die Energie-Karte mit Werteverlauf ist jetzt im Wiki:

https://wiki.fhem.de/wiki/DOIF/uiTable_Anwendung#Visualisierung:_Energiefluss_als_Energie-Karte
Titel: Aw: Energy-Card
Beitrag von: Damian am 27 April 2026, 16:57:59
Falls jemand seine energy_card in einer anderen DOIF-Tabelle einbinden möchte siehe: https://forum.fhem.de/index.php?topic=144559.msg1362721#msg1362721