Hauptmenü

Energy-Card

Begonnen von Damian, 01 April 2026, 23:06:56

Vorheriges Thema - Nächstes Thema

Damian

Mein erster Entwurf, zum Anschauen gif-Animation unten anklicken.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

schwatter

#1
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

Damian

#2
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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#3
Zweiter Entwurf mit Verlaufsdiagrammen

Du darfst diesen Dateianhang nicht ansehen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

appi

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

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Dr. Boris Neubert

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 anzeigen.
FHEM-Developer seit 2007, Mitgründer und Förder-Mitglied des FHEM e.V.
Bitte keine unaufgeforderten privaten Nachrichten!

Damian

#7
Ich habe nun die Energy_card fertiggestellt. Dafür wurde allerdings eine neue DOIF-Version erstellt (morgen per Update verfügbar oder direkt von hier ladbar https://svn.fhem.de/trac/browser/trunk/fhem/FHEM?desc=1&order=date). Diese erlaubt nun ohne Umwege Javascript auszuführen. Das war erforderlich damit ich per Änderung von CSS-Attributen den animierten Energiefluss besser 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 der Definition 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.


Du darfst diesen Dateianhang nicht ansehen.

defmod di_energy_card DOIF {}
attr di_energy_card uiTable {\
$ATTRIBUTESFIRST = 1;;\
\
## Energy_card kann über das Attribut zoom skaliert werden\
\
$TABLE = 'zoom: 1;; width: 473px;; height: 374px;; 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,$leftright)=@_;;\
my $dur;;\
if ($power == 0) {\
  $dur=0;;\
} else {\
  $power=$max if ($power>$max);;\
  $dur=int((6-abs(5*$power/$max))*10)/10;;\
}\
\
\
my $from;;\
my $to;;\
my $x1;;\
my $x2;;\
\
\
if ($leftright) {\
  $from="-1 -1";;\
  $to="1 1";;\
  $x1=0;;\
  $x2=100;;\
} else {\
  $from="1 1";;\
  $to="-1 -1";;\
  $x1=100;;\
  $x2=0;;\
}\
\
my $out='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 35" width="90" height="35" style="width:90px;; height:35px;; ">';;\
\
$out .= '<defs>\
<linearGradient id="flowGradient_'.$item.'" \
    x1="'.$x1.'%" y1="0%" \
    x2="'.$x2.'%" y2="0%" \
    >\
    <stop offset="0%" stop-color="white" stop-opacity="0.2"/>\
    <stop offset="95%" 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="3" />';;\
\
##$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.'%");;}'])\
}  ## end of flow\
\
sub grid_power {\
my ($power,$max)=@_;;\
return (move(110,149,flow("M 5 0 A 30 30 0 0 0 35 30 L 90 30","grid",$power,$max,($power  > 0 ? 0 : 1))));;\
} \
\
sub solar_power {\
my ($power,$max)=@_;;\
  return move(274,149,flow("M 85 0 A 30 30 0 0 1 55 30 L 0 30","solar",$power,$max,0));;\
} \
\
sub home_power {\
my ($power,$max)=@_;;  \
return move(110,185,flow("M 5 35 A 30 30 0 0 1 35 5 L 90 5","home",$power,$max,0));;\
}\
\
sub battery_power {\
my ($power,$max)=@_;;\
return move(274,185,flow("M 85 35 A 30 30 0 0 0 55 5 L 0 5","battery",$power,$max,($power < 0 ? 0:1)));;\
}\
\
sub grid {\
my ($power,$feed,$consum)=@_;;\
move(2,2,card($power,"Netz","scene_power_grid\@silver",-5,5,undef,undef,"kW",[(-1,20,-0.01,40,1,65,5,85)],"3","130,autoscaling,steps,footer,noycolor,ring,180","nogradient,,innerring,nopointer,negzeropos",undef, [[$feed,0,30,undef,undef,"Einsp.",[(10,65,30,85)]],[$consum,0,10,undef,undef,"Bezug",[(3,40,10,20)]]],0,10,undef,undef,["",""],undef,"1,,fill:silver, kWh"));;\
}\
\
\
sub self {\
my ($autark,$EVG)=@_;;\
move(200,151,ring2($autark,0,100,undef,undef,"Autarkie",120,[(33.3,40,66.6,65,100,85)],"0,,fill:silver, %",$EVG,0,100,undef,undef,"EVQ",[(33.3,40,66.6,65,100,85)],"0,,fill:silver, %",undef,undef,"nogradient,,innerring,nopointer"))\
}\
\
sub solar { \
my ($power,$energy)=@_;;  move(237,2,card($power,"PV","solar_icon\@silver",0,3.6,undef,undef,"kW",[(1.2,45,2.4,65,3.6,85)],"3,,,","130,autoscaling,steps,footer,noycolor,ring,180","nogradient,,innerring,nopointer",undef, [$energy],0,30,undef,undef,"",[(10,45,20,65,30,85)],"1,,, kWh"))\
}\
\
sub home {\
my ($power,$consum)=@_;;\
  move(2,222,card($power,"Haus ","fa_home\@silver",0,5,undef,undef,"kW",[(1,40,5,20)],"3","130,autoscaling,steps,footer,noycolor,ring,180","nogradient,,innerring,nopointer,negzeropos",undef, [[$consum]],0,10,undef,undef,[""],[(5,40,10,20)],"1,,, kWh"));;\
}\
\
sub battery {\
my ($power,$Cap)=@_;;\
    move(237,222,card($power,"Speicher","battery_100\@silver",-1000,1000,undef,undef,"Watt",[(-300,30,-0.01,40,300,190,1000,170)],"0,,,","130,fixedscaling,steps,footer,noycolor,ring,180","1,,1,0,negzeropos",undef,[$Cap],0,100,undef,undef,"",[(20,20,50,40,80,65,100,85)],"0,font-size:120%,, %"))\
}\
\
} ## end of perl area\
\
## Tabellendefinition\
## Hier auf eigene Readings anpassen\
\
grid([MQTT2_DVES_C58DCB:power_fc:144col1d],[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:144col1d],[di_counter_new:MQTT2_DVES_C58DCB.total_pv.day]).\
home ([MQTT2_DVES_C58DCB:power_consum:144col1d],[di_counter_new:MQTT2_DVES_C58DCB.total_consum.day]).\
battery([ecoflowStreamACpro:quota_powGetBpCms:144col1d],[ecoflowStreamACpro:quota_soc]).\
self([energy:autark],[energy:evg]).\
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_consum],3.6)

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Andere Frage: warum wird der Speicher bei 89% schon nicht mehr geladen?

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

appi

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?

Damian

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.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF