PowerFlow [animiertes SVG, dummy, javascript]

Begonnen von schwatter, 20 Oktober 2024, 21:56:34

Vorheriges Thema - Nächstes Thema

schwatter

Super,

hier dann nochmal alles komplett.

Gruß schwatter

schwatter

Nabend,

Updates jetzt wieder im ersten Post. Habe die Infos auf das neue SVG + dummy angepasst.

Update:
- Code im dummy komprimiert
- Diesbezüglich 2 <tspan class="informId_ringSVG: im SVG angepasst.

Zum updaten bitte dummy Code und powergrid.svg erneuern.


Gruß schwatter

ergerd

Hallo schatter,

vielen Dank. Allerdings werden jetzt die unbenutzten Circles als leere Circles angezeigt.
Kann man das unterdrücken, so wie vorher?

Grüße
ergerd
FHEM auf RasPi 4, ZigBee, 1Wire2WLAN, DS2423, Buderus KM200, Button+, LaCrosseGateway, PCA301, ConBee III, LuftdatenInfo, OneWireGW, Div. ESPs u. Shellys

schwatter

#93
Morgen,

ich habe Circle 5 bis 9 mit n/a ausgeblendet und auch die Readings von Icon + Power gelöscht. Bei mir werden alle ausgeblendet, auch die Hidden_Buttons.
Hast du aus dem ersten Post Beide erneuert? Vielleicht nochmal ein STRG + F5.

Im Anhang mit Chrome Desktop + FireFox Desktop


Gruß schwatter

ergerd

Ah, man muss in das Feld Name "n/a" eingegeben, ok, habe ich wohl irgendwo überlesen.

Danke, funktioniert!

Grüße
erger
FHEM auf RasPi 4, ZigBee, 1Wire2WLAN, DS2423, Buderus KM200, Button+, LaCrosseGateway, PCA301, ConBee III, LuftdatenInfo, OneWireGW, Div. ESPs u. Shellys

schwatter

#95
Ich habe jetzt nochmal geschaut. Wenn ich z.B "deletereading powergrid cCircle4Name_s" oder "set powergrid cCircle4Name_s n/a" setze, wird bei Beiden der Ring
nach erneutem Laden der Seite ausgeblendet. Bedeutet, wenn jemand das Device neu anlegt, sollten auch keinen toten Ringe erscheinen. Vielleicht dein Browsercache?

Gruß schwatter

wicky

Hallo schwatter,

habe Dein powergrid Installiert und soweit funktioniert
Eigentlich alles, ein zwei Probleme habe ich dann doch mit
der Batterieanzeige für was ist batteryLink_s = ???,
battery_v  müsste ich über DOIF die Wattangabe In und Out
wie gerade der Zustand ist übergeben, gilt auch für
batteryState_v = houseUnload, solarLoad, usw.,
battery_p = Prozent Batterie ist für mich klar.
Die Berechnungen stimmen für mich nicht siehe Anhang
Werte rot markiert, werden die in der .svg berechnet oder
sollte man über ein Userreading rechnen und dann der DOIF
die fertigen Werte übergeben.

Gruß Hans

schwatter

#97
Hallo Hans,

- batteryLink_s = /fhem?detail=NameVonMeinemBatteryDevice. Kann man setzen, muss man nicht. Wenn du dann auf den
Batteryring klickst, landest du in dem Device. Da könnte auch www.google.de stehen.
- zu Werte stimmen nicht. Du hast recht, ist mir noch nicht aufgefallen. Da ich selber noch keinen Akku habe.
Richtig wäre:
  Grid -41 W
+ Solar 1551 W
- Battery 983 W
---------------
= House 527 W.

Im Moment wird im DOIF/notify nur stumpf der Wert Smartmeter + Solarinverter addiert. Bedeutet, die 983 W von deiner Battery
verstecken sich im House 1510 mit W. Müssten da aber abgezogen werden. Also ja, du müsstest deine Berechnung anpassen.

Wie ist das bei deinem Akku? Wenn du lädst, zeigt er positive Werte an (300w) und beim entladen negative Werte (-300w)?

Edit:
Zum testen habe ich mir einen Batterydummy angelegt und berücksichtige ihn so:
( set powergrid house_v {(ReadingsNum("Smartmeter_2E1F50","APOX_Power", 0, 1) + ReadingsNum("OpenDTU","total.Power.v", 0, 1) - ReadingsNum("batteryDummy","power", 0, 1) )} )
Gruß schwatter

wicky

Hallo schwatter,

ist kein Problem, Berechnungen mach ich erstmal in der DOIF.

ZitatWie ist das bei deinem Akku? Wenn du lädst, zeigt er positive Werte an (300w) und beim entladen negative Werte (-300w)?

Akku wird mit zwei Readings ausgeben data_out und data_in keine negativen
Werte sowie batteryState_v = houseUnload, solarLoad werde
ich dann auch gleich in der DOIF mit lösen.

Schönen Dank erstmal und wenn irgendwelche Fragen noch habe melde ich mich.

Gruß Hans
 

schwatter

Ok,

also 2 positive Werte für Battery in und out.
Damit der Hausring prozentual den Anteil der Battery farblich anzeigt,
ist auch ein positiver Wert + houseUnload erforderlich.
Dann passt das.

Gruß schwatter


Virsacer

Hi,

hab das hier gerade entdeckt und gleich mal ausprobiert - sieht echt toll aus 8)

Allerdings hab ich das Problem, dass ich erstmal nur den oberen Teil sehe (wie in Post #71) und bis 150% zoomen muss, damit alles sichtbar wird.
Ist das noch ein generelles Problem, oder sollte das inzwischen behoben sein und bei mir ist noch irgendwas anders?

Kann man auch das fossilfree ausblenden? Bei 0% läuft trotzdem ein Punkt

Gruß Virsacer

schwatter

Moin,

es ist kein generelles Problem. Woran es liegt, weiß ich noch nicht. Vielleicht können wir es bei dir eingrenzen?

- Welche Browser?
- Welche Betriebssysteme?
- Ein List von deinem Powerflowdevice bitte
- Welches Skin in Fhem
- Hast du eigenes CSS gesetzt unter Select style-->Additional CSS?

FossilFree ist im Moment dauerhaft eingeblendet. Das der Punkt auch bei 0 animiert ist, muss ich fixen.

Gruß schwatter

Virsacer

Hi,

- Firefox 141.0b6 auf Win 10
- FHEM läuft auf Debian 12
Internals:
   DEF       
   FUUID      68699b99-f33f-ed96-d8b0-27a10712ba26d046
   NAME       powergrid
   NR         367
   STATE      ???
   TYPE       dummy
   eventCount 2
   OLDREADINGS:
   READINGS:
     2025-07-06 00:38:49   grid_v          200
Attributes:
   alias      <span></span>
   devStateIcon {

    use URI::Escape;

    # Lese die Werte aus den Readings und setze Standardwerte
    my %values = map {
        my $default = ($_ =~ /Name_s|Link_s/ ? ($_ =~ /Link_s/ ? 'no link' : 'n/a') : 0);
        $_ => ReadingsVal($name, $_, $default)
    } qw(
        lowcarbon_i lowcarbon_v gridLink_s grid_v grid_in_v grid_out_v
        house_i house_v solar_i solarLink_s solar_v batteryLink_s battery_v
        battery_p batteryState_v cCircle1Icon_i cCircle1Link_s cCircle1Name_s cCircle1Power_v
        cCircle2Icon_i cCircle2Link_s cCircle2Name_s cCircle2Power_v cCircle3Icon_i
        cCircle3Link_s cCircle3Name_s cCircle3Power_v cCircle4Icon_i cCircle4Link_s
        cCircle4Name_s cCircle4Power_v cCircle5Icon_i cCircle5Link_s cCircle5Name_s
        cCircle5Power_v cCircle6Icon_i cCircle6Link_s cCircle6Name_s cCircle6Power_v
        cCircle7Icon_i cCircle7Link_s cCircle7Name_s cCircle7Power_v cCircle8Icon_i
        cCircle8Link_s cCircle8Name_s cCircle8Power_v cCircle9Icon_i cCircle9Link_s
        cCircle9Name_s cCircle9Power_v
    );

    # Hole das SVG als Template
    my $svg = FW_makeImage('powergrid');

    # Setze die Werte im SVG
    foreach my $key (keys %values) {
        $svg =~ s/(<tspan class="informId_ringSVG:$key">)(.*?)(<\/tspan>)/$1$values{$key}$3/;
    }

    # Bearbeite die SVG-Icons basierend auf der Art (intern oder extern)
    my @icons = (
        [$values{solar_i},     'solarCircleIcon',       '#FFE74B', 1],
        [$values{lowcarbon_i}, 'fossilfreeCircleIcon',  '#30FF24', 1],
        [$values{house_i},     'houseCircleIcon',       'yellow',  1],
        [$values{cCircle1Icon_i}, 'cCircle1Icon',        '#32AFFF', ($values{cCircle1Name_s} ne 'n/a')],
        [$values{cCircle2Icon_i}, 'cCircle2Icon',        '#32AFFF', ($values{cCircle2Name_s} ne 'n/a')],
        [$values{cCircle3Icon_i}, 'cCircle3Icon',        '#2AB5C7', ($values{cCircle3Name_s} ne 'n/a')],
        [$values{cCircle4Icon_i}, 'cCircle4Icon',        '#2AB5C7', ($values{cCircle4Name_s} ne 'n/a')],
        [$values{cCircle5Icon_i}, 'cCircle5Icon',        '#32AFFF', ($values{cCircle5Name_s} ne 'n/a')],
        [$values{cCircle6Icon_i}, 'cCircle6Icon',        '#32AFFF', ($values{cCircle6Name_s} ne 'n/a')],
        [$values{cCircle7Icon_i}, 'cCircle7Icon',        '#2AB5C7', ($values{cCircle7Name_s} ne 'n/a')],
        [$values{cCircle8Icon_i}, 'cCircle8Icon',        '#32AFFF', ($values{cCircle8Name_s} ne 'n/a')],
        [$values{cCircle9Icon_i}, 'cCircle9Icon',        '#2AB5C7', ($values{cCircle9Name_s} ne 'n/a')]
    );

    foreach my $entry (@icons) {
        my ($icon_raw, $id, $fill, $should_process) = @$entry;
        next unless $should_process && $icon_raw;

        my $raw = $icon_raw;
        my $icon;

        if ($raw =~ s/:fhem$//) {
            $icon = FW_makeImage("$raw\@$fill");
        } else {
            $icon = uri_unescape($raw);
            $icon =~ s/fill="[^"]*"/fill="$fill"/g;
            $icon =~ s/<path(?![^>]*fill)/<path fill="$fill"/g;
        }

        next unless defined $icon;

        $icon =~ s/\s*(width|height)="[^"]*"\s*/ /g;
        $icon =~ s/<svg([^>]*)/ <svg$1 width="25px" height="25px" /;

        $svg =~ s{<g id="$id"([^>]*)>}{<g id="informId_ringSVG:$id"$1>$icon };
    }

    # Weblink Links
    my @links = (
        [ "do_weblink", "/fhem?detail=powergrid", 55, 30, "Powerflow", "Click here for DeviceOverview" ],
        [ "gridLink", $values{gridLink_s}, 100, 250, "Grid", $values{gridLink_s} ],
        [ "solarLink", $values{solarLink_s}, 250, 100, "Solar", $values{solarLink_s} ],
        [ "batteryLink", $values{batteryLink_s}, 250, 400, "Battery", $values{batteryLink_s} ],
        [ "cCircle1Link", $values{cCircle1Link_s}, 400, 100, "Circle1", $values{cCircle1Link_s} ],
        [ "cCircle2Link", $values{cCircle2Link_s}, 400, 400, "Circle2", $values{cCircle2Link_s} ],
        [ "cCircle3Link", $values{cCircle3Link_s}, 550, 100, "Circle3", $values{cCircle3Link_s} ],
        [ "cCircle4Link", $values{cCircle4Link_s}, 550, 400, "Circle4", $values{cCircle4Link_s} ],
        [ "cCircle5Link", $values{cCircle5Link_s}, 700, 100, "Circle5", $values{cCircle5Link_s} ],
        [ "cCircle6Link", $values{cCircle6Link_s}, 700, 400, "Circle6", $values{cCircle6Link_s} ],
        [ "cCircle7Link", $values{cCircle7Link_s}, 850, 100, "Circle7", $values{cCircle7Link_s} ],
        [ "cCircle8Link", $values{cCircle8Link_s}, 850, 250, "Circle8", $values{cCircle8Link_s} ],
        [ "cCircle9Link", $values{cCircle9Link_s}, 850, 400, "Circle9", $values{cCircle9Link_s} ]
    );

    foreach my $link (@links) {
        my ($id, $href, $cx, $cy, $title, $tooltip) = @$link;

        my $weblink;
        if ($id eq 'do_weblink') {
            $weblink = qq(<a xlink:href="$href" target="_blank"><text x="$cx" y="$cy" font-size="24" fill="white" cursor="pointer">$title<title>$tooltip</title></text></a>);
        } else {
            $weblink = qq(<a xlink:href="$href" target="_blank"><circle cx="$cx" cy="$cy" r="45" style="fill:transparent;stroke:none;"/><title>$tooltip</title></a>);
        }

        $svg =~ s{<g id="$id"([^>]*)>}{<g id="$id"$1>$weblink};
    }

    # CSS hinzufügen
    my $extras = 'style="width: 90vw !important;height: auto !important;max-height: 700px;background-color: black !important;"';
    $svg =~ s/<svg([^>]*)\s*(style="[^"]*")?/<svg$1$extras/;

    return $svg;

}
   readingList battery_v battery_p batteryState_v batteryLink_s cCircle1Icon_i cCircle1Link_s cCircle1Name_s cCircle1Power_v cCircle2Icon_i cCircle2Link_s cCircle2Name_s cCircle2Power_v cCircle3Icon_i cCircle3Link_s cCircle3Name_s cCircle3Power_v cCircle4Icon_i cCircle4Link_s cCircle4Name_s cCircle4Power_v cCircle5Icon_i cCircle5Link_s cCircle5Name_s cCircle5Power_v cCircle6Icon_i cCircle6Link_s cCircle6Name_s cCircle6Power_v cCircle7Icon_i  cCircle7Link_s cCircle7Name_s cCircle7Power_v cCircle8Icon_i cCircle8Link_s cCircle8Name_s cCircle8Power_v cCircle9Icon_i cCircle9Link_s cCircle9Name_s cCircle9Power_v dryer_v grid_v grid_in_v grid_out_v gridLink_s house_i house_v lowcarbon_i lowcarbon_v solar_i solar_v solarLink_s
   room       Power
   setList    battery_v battery_p batteryState_v:select,stop,gridLoad,gridUnload,solarLoad,houseUnload batteryLink_s cCircle1Icon_i cCircle1Link_s cCircle1Name_s cCircle1Power_v cCircle2Icon_i cCircle2Link_s cCircle2Name_s cCircle2Power_v cCircle3Icon_i cCircle3Link_s cCircle3Name_s cCircle3Power_v cCircle4Icon_i cCircle4Link_s cCircle4Name_s cCircle4Power_v cCircle5Icon_i cCircle5Link_s cCircle5Name_s cCircle5Power_v cCircle6Icon_i cCircle6Link_s cCircle6Name_s cCircle6Power_v cCircle7Icon_i cCircle7Link_s cCircle7Name_s cCircle7Power_v cCircle8Icon_i cCircle8Link_s cCircle8Name_s cCircle8Power_v cCircle9Icon_i cCircle9Link_s cCircle9Name_s cCircle9Power_v grid_v grid_in_v grid_out_v gridLink_s house_i house_v lowcarbon_i lowcarbon_v solar_i solar_v solarLink_s
- Skin ist f18
- Additional CSS ist leer

Hier noch meine FHEMWEB Attribute, die relevant sein könnten:
   CssFiles   pgm2/WEB.css
   JavaScripts pgm2/WEB.js codemirror/fhem_codemirror.js
   codemirrorParam {"height":"auto","search":false}
   iconPath   custom:fhemSVG:openautomation
   longpoll   1
   plotEmbed  2
   plotfork   0
   styleData  {
 "f18": {
  "Pinned.menu": "true",
  "hidePin": "true",
  "cols.bg": "FFFFE7",
  "cols.fg": "000000",
  "cols.link": "0000ff",
  "cols.evenrow": "F8F8E0",
  "cols.oddrow": "F0F0D8",
  "cols.header": "E0E0C8",
  "cols.menu": "f8f8e0",
  "cols.sel": "f8f8e0",
  "cols.inpBack": "FFFFFF",
  "savePinChanges": true,
  "hideLogo": false,
  "hideTextInput": false,
  "hideMenu": false,
  "rightMenu": false,
  "hideInput": false,
  "fixedInput": false,
  "wrapcolumns": true
 }
}
   stylesheetPrefix f18
Ich hab meine "CssFiles" und "JavaScripts" Dateien auch mal umbenannt, aber das ändert nichts...

Dank & Gruß Virsacer

schwatter

#103
Ok,

konnte es nachstellen. Dein list vom Device hat geholfen. Es liegt an deiner Minimalconf.
Setzt mal

setreading powergrid cCircle1Name_s test
Dann sollte es wachsen. Ich muss weiter meine Hausaufgaben machen um das abzufangen. Versuch mal
das Dummybeispiel aus 1 zu setzen als Raw. Keine Readings löschen! und dann nach und nach Ringe ausblenden mit n/a.

edit:
Ah da hatte ich die Readings gelöscht. Moment, ich muss erstmal wieder selber alle anlegen :)

edit2:
So, hoffentlich ein funktionierendes Beispiel in Anhang in Post #1. Die Raw muss komplett angelegt werden.
Das Problem ist wohl, ist kein Customcircle sichtbar, dann bricht das SVG in sich zusammen. Da muss ich ansetzen.

Gruß schwatter

Virsacer

Ah ok :)

Bei der Ersteinrichtung hat man natürlich noch keine Daten drin...
Nach dem Setzen eines Namens für den Ring wird es korrekt angezeigt.

Gruß Virsacer