Dashboard: Doppelungen zusammengelegt, Lade- und Renderlast gesenkt

Zusammenlegung
- Die sechs Endpunkte getConsData_/getProdData_{month,year,decade}.php sind
  ajax/energyHistory.php?series=&range= gewichen, der gemeinsame Aufbau der
  Chart-Daten steht in ajax/chartData.php. Die erzeugte SQL wurde gegen alle
  sechs Originale abgeglichen.
- Die 13 Raeume der Home-Ansicht stehen nur noch in restricted/rooms.php.
  home.php rendert die SVG-Kacheln daraus, homeMQTT.js bekommt dieselbe
  Tabelle als JSON (346 -> 222 bzw. 428 -> 197 Zeilen).
- Gemeinsame JS-Helfer in js/solar/common.js; geteilte Bausteine fuer
  Wetterkacheln, Chart-Skripte und das Formular der Ladesteuerung.
- Seitenvorlagen sind jetzt .php und werden eingebunden, statt per
  file_get_contents zusammengesetzt zu werden.

Fehlerbehebungen
- ?action=weather fuehrte auf eine leere Seite, es gibt jetzt weather.php.
- homeMQTT.js griff auf ein #meteogram zu, das home.php nie hatte, und brach
  damit den readystatechange-Handler ab.
- Die Heizungsseite abonnierte weatherStation/#, zeigte die Werte aber nie an.

Ladelast
- Chart.js, MQTT und Meteogramm werden nur noch auf den Seiten geladen, die
  sie brauchen; die Seitentabelle dafuer steht in index.php.
- mqtt.js durch die minifizierte Fassung ersetzt (859 -> 359 KB). MQTT.js
  5.14.1, byte-identisch mit dem signierten npm-Tarball.
- Rund 3,1 MB ungenutzte Vendor-Reste und AdminLTE-Demobilder entfernt.
- Solar 1796 -> 1240 KB, Home 1796 -> 873 KB, Historie 1796 -> 843 KB.

Speicher im Browser
- Chart.defaults.devicePixelRatio auf 1.5 gedeckelt. Die Zeichenpuffer der
  Diagramme waren mit 20-45 MB der groesste Posten der Seite.
- Das Meteogramm-iframe laedt erst beim Hinscrollen.

Realtime-SVG
- Filterbereiche auf das noetige Mass verkleinert und den wirkungslosen
  feOffset-Durchgang entfernt: 60 % weniger gerasterte Filterflaeche bei
  pixelgleichem Ergebnis.
- Die Fluss-Animation laeuft ueber transform statt stroke-dashoffset, mit
  Punkten statt Strichmuster; sie ruht, wo kein Fluss anliegt.
- Der Wertupdate schreibt nur noch bei echter Aenderung und benutzt
  textContent statt innerHTML: 9 statt 86 Elemente pro Update, davon keines
  mit Filter. describeArc rundet auf volle Grad.
- waterInfo auf scale(0.90) wie die uebrigen Info-Gruppen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-26 22:54:28 +02:00
co-authored by Claude Opus 5
parent 29f752eafe
commit 6b8556567b
68 changed files with 1555 additions and 60085 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

-475
View File
@@ -1,475 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="-100 -100 1600 950" width="100%" height="100%" id="realtimeSvgAni">
<defs>
<filter id="shadow" x="-0.5" y="-0.5" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="0.7" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="0.5" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
<filter id="shadowMiddle" x="-1.0" y="-1.0" width="300%" height="300%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="1" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
<filter id="shadowBig" x="-1" y="-1" width="300%" height="300%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
<feGaussianBlur result="offOut" in="offOut" stdDeviation="2" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
<g id="circGrid">
<line x2='27.7' y2='76.5' x1='-18.9' y1='61.4' style='stroke-width:4px' />
<line x2='16.5' y2='115.9' x1='-8.1' y1='120.6' style='stroke:#222;stroke-width:2;' />
<line x2='34.5' y2='154.2' x1='15.2' y1='170.1' style='stroke:#222;stroke-width:2;' />
<line x2='68.7' y2='179' x1='59.5' y1='202.3' style='stroke:#222;stroke-width:2;' />
<line x2='110.7' y2='184.3' x1='113.8' y1='209.1' style='stroke:#222;stroke-width:2;' />
<line x2='150' y2='168.8' x1='164.7' y1='189' style='stroke:#222;stroke-width:2;' />
<line x2='176.9' y2='136.2' x1='199.5' y1='146.8' style='stroke:#222;stroke-width:2;' />
<line x2='184.8' y2='94.7' x1='209.8' y1='93.1' style='stroke:#222;stroke-width:2;' />
<line x2='171.8' y2='54.5' x1='192.9' y1='41.1' style='stroke:#222;stroke-width:2;' />
<line x2='140.9' y2='25.5' x1='153' y1='3.6' style='stroke:#222;stroke-width:2;' />
<line x2='100' y2='24' x1='100' y1='-24' style='stroke-width:4px' />
</g>
<g id="circGrid6kW">
<line x2='27.7' y2='76.5' x1='-18.9' y1='61.4' style='stroke-width:4px' />
<line x2='26.4' y2='142.5' x1='4.7' y1='155' style='stroke:#222;stroke-width:2;' />
<line x2='82.3' y2='183.1' x1='77.1' y1='207.6' style='stroke:#555;stroke-width:4px;' />
<line x2='149.9' y2='168.8' x1='164.6' y1='189.0' style='stroke:#222;stroke-width:2;' />
<line x2='184.5' y2='108.9' x1='209.4' y1='111.5' style='stroke:#555;stroke-width:4px;' />
<line x2='163.2' y2='43.1' x1='181.7' y1='26.4' style='stroke:#222;stroke-width:2;' />
<line x2='100' y2='24' x1='100' y1='-24' style='stroke-width:4px' />
</g>
<linearGradient id="gradient1" x1="0" x2="0" y1="0" y2="1">
<stop id="tmpH" offset="0%" stop-color="#2389BA" stop-opacity="0.7" />
<stop id="tmpM" offset="50%" stop-color="#2389BA" stop-opacity="0.7" />
<stop id="tmpL" offset="100%" stop-color="#2389BA" stop-opacity="0.7" />
</linearGradient>
<filter id="fillpartialEV" primitiveUnits="objectBoundingBox" x="-5%" y="-5%" width="110%"
height="110%">
<feFlood flood-color="#1f5a66" />
<feComposite id="evChargeState" y="100%" operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
<filter id="fillpartialHeat" primitiveUnits="objectBoundingBox" x="-5%" y="-5%" width="110%"
height="110%">
<feFlood flood-color="#5E2B21" />
<feComposite id="heatChargeState" y="100%" operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
<filter id="fillpartialBat" primitiveUnits="objectBoundingBox" x="-5%" y="-5%" width="110%"
height="110%">
<feFlood flood-color="#25481C" />
<feComposite id="batChargeState" y="100%" operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
<filter id="fillpartialWater" primitiveUnits="objectBoundingBox" x="-5%" y="-5%" width="110%"
height="110%">
<feFlood flood-color="#182C43" />
<feComposite id="waterState" y="50%" operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
<g id="heater" transform="rotate(-90),scale(0.07,0.07)">
<path
d="M485.924,134.508c14.381,0,26.076-11.669,26.076-26.017v-17.39c0-14.348-11.695-26.017-26.076-26.017H468.61v-8.737
c0-23.89-19.466-43.331-43.39-43.331s-43.39,19.441-43.39,43.331v8.737h-26.034v-8.737c0-23.89-19.466-43.331-43.39-43.331
c-23.924,0-43.39,19.441-43.39,43.331v8.737h-26.034v-8.737c0-23.89-19.466-43.331-43.39-43.331
c-23.924,0-43.39,19.441-43.39,43.331v8.737h-26.034v-8.737c0-23.89-19.466-43.331-43.39-43.331S43.39,32.458,43.39,56.348v8.737
H17.356V39.051H0v34.712v52.068v34.712h17.356v-26.034H43.39v269.017H8.678c-4.797,0-8.678,3.881-8.678,8.678v34.712
c0,4.797,3.881,8.678,8.678,8.678c4.797,0,8.678-3.881,8.678-8.678v-26.034H43.39v34.78c0,23.89,19.466,43.322,43.39,43.322
s43.39-19.432,43.39-43.322v-0.068h26.034v0.068c0,23.89,19.466,43.322,43.39,43.322c23.924,0,43.39-19.432,43.39-43.322v-0.068
h26.034v0.068c0,23.89,19.466,43.322,43.39,43.322c23.924,0,43.39-19.432,43.39-43.322v-0.068h26.034v0.068
c0,23.89,19.466,43.322,43.39,43.322s43.39-19.432,43.39-43.322v-0.068h17.314c14.381,0,26.076-11.669,26.076-26.017v-17.39
c0-14.347-11.695-26.017-26.076-26.017H468.61V134.508H485.924z M468.61,82.441h17.314c4.805,0,8.72,3.881,8.72,8.661v17.39
c0,4.78-3.915,8.661-8.72,8.661H468.61V82.441z M43.39,117.153H17.356V82.441H43.39V117.153z M112.814,73.763v52.068v269.017
v52.068v8.746c0,14.313-11.678,25.966-26.034,25.966s-26.034-11.653-26.034-25.966V125.831V73.763V56.348
c0-14.322,11.678-25.975,26.034-25.975s26.034,11.653,26.034,25.975V73.763z M156.203,438.237h-26.034v-34.712h26.034V438.237z
M156.203,386.169h-26.034V134.508h26.034V386.169z M156.203,117.153h-26.034V82.441h26.034V117.153z M225.627,73.763v52.068
v269.017v52.068v8.746c0,14.313-11.678,25.966-26.034,25.966s-26.034-11.653-26.034-25.966v-8.746v-52.068V125.831V73.763V56.348
c0-14.322,11.678-25.975,26.034-25.975s26.034,11.653,26.034,25.975V73.763z M269.017,438.237h-26.034v-34.712h26.034V438.237z
M269.017,386.169h-26.034V134.508h26.034V386.169z M269.017,117.153h-26.034V82.441h26.034V117.153z M338.441,73.763v52.068
v269.017v52.068v8.746c0,14.313-11.678,25.966-26.034,25.966s-26.034-11.653-26.034-25.966v-8.746v-52.068V125.831V73.763V56.348
c0-14.322,11.678-25.975,26.034-25.975s26.034,11.653,26.034,25.975V73.763z M381.831,438.237h-26.034v-34.712h26.034V438.237z
M381.831,386.169h-26.034V134.508h26.034V386.169z M381.831,117.153h-26.034V82.441h26.034V117.153z M451.254,73.763v52.068
v269.017v52.068v8.746c0,14.313-11.678,25.966-26.034,25.966s-26.034-11.653-26.034-25.966v-8.746v-52.068V125.831V73.763V56.348
c0-14.322,11.678-25.975,26.034-25.975s26.034,11.653,26.034,25.975V73.763z M485.924,403.525c4.805,0,8.72,3.881,8.72,8.661
v17.39c0,4.78-3.915,8.661-8.72,8.661H468.61v-34.712H485.924z" />
</g>
<g id="gas">
<path fill-opacity="1" stroke-width="0.2" stroke-linejoin="round"
d="M 42.75,19L 42.75,31.4977C 44.5834,31.378 48.9184,32.7881 48.2917,49.0833C 49.0833,53.8333 54.625,53.8333 55.8125,47.5C 57,42.75 53.8333,42.75 52.25,28.5C 52.25,26.9167 52.25,22.1667 45.9167,19L 45.9167,17.4167C 52.25,17.4167 57,25.3333 57,26.9167C 57,28.5 55.4167,28.5 55.4167,28.5C 55.4167,28.5 55.8125,38 57.3958,39.5833C 58.9792,41.1667 58.5833,45.9167 58.5833,49.0833C 58.5833,52.25 53.8333,55.4167 52.25,55.4167C 50.6667,55.4167 45.9167,55.4167 45.9167,50.6667C 45.9167,46.3403 45.2599,36.7598 42.75,35.0854L 42.75,55.4167C 43.6244,55.4167 44.3333,56.1255 44.3333,57L 44.3333,60.1667L 19,60.1667L 19,57C 19,56.1255 19.7089,55.4167 20.5833,55.4167L 20.5833,19C 20.5833,17.2511 22.0011,15.8333 23.75,15.8333L 39.5833,15.8333C 41.3322,15.8333 42.75,17.2511 42.75,19 Z M 25.7291,33.2501L 37.6041,33.25C 38.4786,33.25 39.5833,32.1453 39.5833,31.2709L 39.5833,20.9792C 39.5833,20.1048 38.4786,19 37.6041,19L 25.7292,19C 24.8547,19 23.75,20.1048 23.75,20.9792L 23.75,31.2709C 23.75,32.1453 24.8547,33.2501 25.7291,33.2501 Z " />
</g>
<g id="water">
<path
d="M283.897,92.846c-36.582-49.345-73.688-89.267-74.061-89.664C207.944,1.153,205.296,0,202.523,0
c-2.774,0-5.423,1.152-7.314,3.182c-0.371,0.397-37.478,40.319-74.06,89.664c-49.971,67.403-75.308,119.726-75.308,155.513
c0,86.396,70.287,156.688,156.682,156.688c86.396,0,156.683-70.29,156.683-156.688C359.206,212.572,333.868,160.25,283.897,92.846z
M218.171,354.342c-8.213,1.941-16.68,2.926-25.162,2.926c-60.294,0-109.347-49.055-109.347-109.35
c0-8.312,2.559-23.373,14.75-47.914c1.225-2.467,4.046-3.691,6.687-2.908c2.639,0.785,4.33,3.357,4.007,6.091
c-0.28,2.361-0.421,4.584-0.421,6.607c0,64.629,45.966,120.77,109.298,133.484c2.607,0.525,4.5,2.795,4.545,5.455
C222.575,351.396,220.761,353.729,218.171,354.342z" />
</g>
<g id="voltage">
<path stroke="#212529" stroke-width="0.2px" d="M11.46,18V13.58H9.86L12.54,8v3.89h1.6Z" />
</g>
<path id="powerTextPath" d="M 100, 100 m -87, 0 a 87,87 0 1,1 174,0 a 87,87 0 1,1 -174,0"></path>
<path id="infoTextPath" d="M 100, 100 m -105, 0 a 105,105 0 1,0 210,0 a 105,105 0 1,0 -210,0"></path>
<g id="pvPlate" fill="none" stroke-width="4" stroke="#f7c000">
<rect width="70" height="40" x="0" y="0" rx="5" ry="5" />
</g>
<g id="ElementBG">
<path fill="#212529" stroke-width="1.5"
d="M 99.80277789465349 -12.999827891201505 A 113 113 0 1 0 100 -13" />
<path fill="none" stroke-width="4"
d="M 99.86386438745993 22.00011880076356 A 78 78 0 1 0 100 22" />
</g>
<g id="plugIcon" filter="url(#shadow)" transform="translate(30,27),scale(6,6)" fill="#71afcd">
<path d="M15.21,6.73V2.63A.72.72,0,0,0,14.4,2h0a.71.71,0,0,0-.75.66V6.73Z" />
<path d="M10.39,6.73V2.62A.7.7,0,0,0,9.6,2h0a.73.73,0,0,0-.78.66V6.73Z" />
<path
d="M6.71,7.23C6.37,7.22,6,8,6,8.8V10c0,2.48.57,4.62,1.63,5.28S9,16,10.35,16.77V22h3.3V16.77c1.38-.8,1.66-.85,2.72-1.51S18,12.46,18,10V8.8c0-.78-.37-1.58-.71-1.57Z" />
</g>
<g id="ogIcon" filter="url(#shadow)" transform="translate(52,45),scale(4,4)">
<polygon fill="#70CCBB"
points="12.01 1.5 2 10.32 3.11 10.32 3.11 21.5 5.12 21.5 5.12 10.32 12 4.13 18.89 10.32 18.89 21.5 20.89 21.5 20.89 10.32 22 10.32 12.01 1.5" />
<path fill="#70CCBB"
d="M8.55,12.65v3.49a2.12,2.12,0,0,0,2.13,2.09h.67s0,3.23,0,3.27h1.49s0-3.24,0-3.28h.77a1.82,1.82,0,0,0,1.8-1.85l0-3.73" />
<path fill="#70CCBB" d="M10.76,11.41v-1.3c0-.45-.17-.67-.52-.68s-.54.22-.54.69v1.67h1.06Z" />
<path fill="#70CCBB"
d="M14.3,11.41c0-.44,0-.88,0-1.3s-.17-.67-.51-.68-.55.22-.55.69v1.67H14.3Z" />
<path fill="#212529"
d="M9.86,13.86h4.28a0,0,0,0,1,0,0v2a1,1,0,0,1-1,1H10.86a1,1,0,0,1-1-1v-2A0,0,0,0,1,9.86,13.86Z" />
</g>
<g id="heatIcon" filter="url(#shadow)" transform="translate(52,70),scale(4,4)" fill="#C2614E">
<path clip-path="M-22 2.24h42V22h-42z"
d="M16.543 8.028c-.023 1.503-.523 3.538-2.867 4.327.734-1.746.846-3.417.326-4.979-.695-2.097-3.014-3.735-4.557-4.627-.527-.306-1.203.074-1.193.683.02 1.112-.318 2.737-1.959 4.378C4.107 9.994 3 12.251 3 14.517 3 17.362 5 21 9 21c-4.041-4.041-1-7.483-1-7.483C8.846 19.431 12.988 21 15 21c1.711 0 5-1.25 5-6.448 0-3.133-1.332-5.511-2.385-6.899-.347-.458-1.064-.198-1.072.375" />
</g>
<g id="ugIcon" filter="url(#shadow)" transform="translate(52,50),scale(4,4)">
<rect stroke="#70CC9C" stroke-width="2" fill="none" x="3" y="3" width="18" height="18" rx="2" />
<path fill="#70CC9C"
d="M8.55,9.2v3.47a2.11,2.11,0,0,0,2.13,2.08h.67s0,3.22,0,3.26h1.49s0-3.22,0-3.26h.77a1.81,1.81,0,0,0,1.8-1.84l0-3.71" />
<path fill="#70CC9C" d="M10.76,8V6.67c0-.45-.17-.66-.52-.67s-.54.22-.54.68V8.34h1.06Z" />
<path fill="#70CC9C" d="M14.3,8c0-.44,0-.87,0-1.3S14.12,6,13.78,6s-.55.22-.55.68V8.34H14.3Z" />
<path fill="#212529"
d="M9.86,10.41h4.28a0,0,0,0,1,0,0v2a1,1,0,0,1-1,1H10.86a1,1,0,0,1-1-1v-2A0,0,0,0,1,9.86,10.41Z" />
</g>
<g id="carIcon" filter="url(#shadow)" transform="translate(45,45),scale(4.8,4.8)"
fill="#212529" stroke-linecap="round">
<path d="M16.22,15.37l-9.3-.16L3,15,.88,14.47.75,10.39A2.78,2.78,0,0,1,1.31,9.2L2.55,7.63" />
<path
d="M.78,7.46,7,7l.87,0L11.37,7a5.57,5.57,0,0,1,1.06.23,9.43,9.43,0,0,1,2.16,1L17.23,9.9l4.22.7a1.73,1.73,0,0,1,1.21.93l.26.49a2.84,2.84,0,0,1,.32,1.6l0,.23A1.52,1.52,0,0,1,22.53,15h0a1.53,1.53,0,0,1-.56.21l-.89.15H15.59" />
<path fill="#888888" stroke="none"
d="M16.06,11c-1.85.11-3.7.14-5.55.16a13.36,13.36,0,0,1-2.82,0,2.62,2.62,0,0,1-.87-.4,1.28,1.28,0,0,1-.53-1.05,1.4,1.4,0,0,1,.09-.51,2.67,2.67,0,0,1,.22-.35,2.79,2.79,0,0,1,.5-.58s.09,0,.11,0a.06.06,0,0,1,0,.05h0c0,.25,0,.49,0,.71s0,.23,0,.31a.75.75,0,0,0,.08.18c.07.09.17.14.17.08a1.81,1.81,0,0,0,.43.05,14.41,14.41,0,0,1,2.68.33c1.82.26,3.64.53,5.46.88a.08.08,0,0,1,.06.09A.07.07,0,0,1,16.06,11Z" />
<circle cx="4.94" cy="15.08" r="1.98" />
<circle cx="19.19" cy="15.08" r="1.98" />
</g>
<g id="plugCordIcon" transform="scale(0.08,0.08),rotate(340),translate(-350,1200)">
<path
d="M489.8,280.92c0-13.9-11.3-25.2-25.2-25.2h-74.1c-62.1,0-112.4,50.2-112.7,112.2c-0.1,32.3-23,61-55,65
c-38.4,4.8-71.2-25.2-71.2-62.6v-56.4c57.6-11.7,101-62.6,101-123.7v-64c0-9.1-7.3-16.4-16.4-16.4h-31.3v-79.1
c0-12.4-9-23.4-21.3-24.6c-14.1-1.4-26,9.7-26,23.6v80.1H95.2v-79.1c0-12.4-9-23.4-21.4-24.6c-14.1-1.3-26,9.7-26,23.6v80.1H16.4
c-9.1,0-16.4,7.3-16.4,16.4v64c0,61.1,43.4,112,101,123.7v53.5c0,61.5,47.7,114,109.2,116.3c64.6,2.4,118-49.4,118-113.5v-0.9
c0-34.9,28.3-63.1,63.1-63.1h73.2C478.5,306.12,489.8,294.82,489.8,280.92L489.8,280.92z" />
</g>
<g id="lockIcon" transform="translate(80,130),scale(0.11,0.11)" style="">
<path
d="M65,330h200c8.284,0,15-6.716,15-15V145c0-8.284-6.716-15-15-15h-15V85c0-46.869-38.131-85-85-85
S80,38.131,80,85v45H65c-8.284,0-15,6.716-15,15v170C50,323.284,56.716,330,65,330z M207.481,219.356l-42.5,42.5
c-2.929,2.929-6.768,4.394-10.606,4.394s-7.678-1.465-10.606-4.394l-21.25-21.25c-5.858-5.858-5.858-15.354,0-21.213
c5.857-5.858,15.355-5.858,21.213,0l10.644,10.643l31.894-31.893c5.857-5.858,15.355-5.858,21.213,0
C213.34,204.002,213.34,213.498,207.481,219.356z M110,85c0-30.327,24.673-55,55-55s55,24.673,55,55v45H110V85z"
style="stroke-width:15px;stroke:rgb(30,30,40);fill:#778;" />
</g>
<g filter="url(#shadow)" id="clock" style="fill:#cc0;"
transform="translate(80,32),scale(0.07,0.07)">
<path
d="m256,51.8c-112.6,0-204.2,91.6-204.2,204.2s91.6,204.2 204.2,204.2 204.2-91.6 204.2-204.2-91.6-204.2-204.2-204.2v-1.42109e-14zm0,449.2c-135.1,0-245-109.9-245-245s109.9-245 245-245 245,109.9 245,245-109.9,245-245,245z" />
<path
d="m327.9,276.4h-71.9c-11.3,0-20.4-9.1-20.4-20.4v-132.2c0-11.3 9.1-20.4 20.4-20.4 11.3,0 20.4,9.1 20.4,20.4v111.8h51.5c11.3,0 20.4,9.1 20.4,20.4s-9.1,20.4-20.4,20.4z" />
</g>
<g id="sunIcon" filter="url(#shadow)" transform="translate(30,27),scale(6,6)"
style="stroke:#f7c000;stroke-width:2;stroke-linecap:round;">
<path id="Pfad_7565" data-name="Pfad 7565" fill="#f7c002" stroke-width="0"
d="M12,8a4,4,0,1,0,4,4A4,4,0,0,0,12,8Z" />
<line x1="12" y1="3" x2="12" y2="5" />
<line x1="12" y1="19" x2="12" y2="21" />
<line x1="19" y1="12" x2="21" y2="12" />
<line x1="3" y1="12" x2="5" y2="12" />
<line x1="5.7" y1="18.5" x2="7" y2="17" />
<line x1="5.7" y1="5.7" x2="7" y2="7" />
<line x1="18.5" y1="18.5" x2="16.7" y2="17" />
<line x1="18.5" y1="5.7" x2="16.7" y2="7" />
</g>
<g id="battIcon" filter="url(#shadow)" transform="translate(30,25),scale(6,6)">
<g>
<rect fill="#6cbe58" x="9.25" y="3" width="5.5" height="4" rx="1" ry="1" />
<path fill="#6cbe58"
d="M16.28,5H7.72A1.21,1.21,0,0,0,6.5,6.2V19.73A1.28,1.28,0,0,0,7.72,21h8.56a1.28,1.28,0,0,0,1.22-1.27V6.2A1.21,1.21,0,0,0,16.28,5Z" />
<rect id="discharged" fill="#212529" rx="1" ry="1" x="8" y="6.5" width="8"
height="13" />
<use id="charge" fill="#cccc00" href="#voltage" />
</g>
</g>
<g id="gridIcon" filter="url(#shadow)" transform="translate(30,27),scale(6,6)">
<path fill="#808090"
d="M13.38,8.54V6.63H18.3V8.06h.95V5.7l-6.35-1L12,2l-1,2.8-6.25.9V8.07H5.6V6.63h4.84V8.54l-7.59,1.9v2.84H3.8V11.76H9.87L6.93,22H9.11l.57-2.46h4.59L14.8,22h2.27L14.13,11.76H20.2v1.52h.95V10.44Zm-3.32,8.81L12,11.11l1.91,6.24Z" />
</g>
<g id="inverterIcon" filter="url(#shadowBig)" fill="#b2b2b2" stroke-width="2px" stroke="#666"
transform="translate(43,43),scale(1.6,1.6)">
<rect stroke-width="2px" x="5.65" y="3" width="58.7" height="64" rx="6.8" />
<circle cx="35.03" cy="29.61" r="11" />
<circle cx="15" cy="40" r="4" />
<path
d="M40.19,52H36.73a2,2,0,0,0-3.46,0H29.81a1.08,1.08,0,1,0,0,2.15h3.46a2,2,0,0,0,3.46,0h3.46a1.08,1.08,0,1,0,0-2.15Z" />
<path fill="#e2001a"
d="M34.89,61.87c-3.24,0-5.87-.73-5.87-1.62s2.63-1.64,5.87-1.64,5.87.74,5.87,1.64S38.13,61.87,34.89,61.87Z" />
<line x1="5.07" y1="53.08" x2="28.73" y2="53.08" />
<line x1="41.27" y1="53.08" x2="64.93" y2="53.08" />
</g>
<g id="northIcon" fill="#808090">
<path
d="M42.066 0v20h3.752V6.957L53.881 20h4.053V0h-3.752v13.355L45.996 0zm5.57 26.688l-25.77 69.949c-.823 2.238 1.658 4.248 3.677 2.978L50 84.195l24.455 15.42c2.02 1.273 4.504-.738 3.68-2.978l-25.79-70c-.472-1.096-1.283-1.632-2.384-1.635c-1.1-.003-2.017.856-2.324 1.686zm-.136 14.83V79.86L29.1 91.463z"></path>
</g>
<g filter="url(#shadow)" id="ecoIcon" transform="translate(60,12)">
<path style="stroke:#6cbe58;fill:rgb(30,30,40);" stroke-width="3" stroke-linejoin="round"
d="M 57,22.1667C 49.0833,28.5 52.25,31.6667 50.6667,36.4167C 49.0833,41.1667 50.6667,42.75 44.3333,47.5C 36.2227,53.583 29.2917,49.875 29.2917,49.875C 27.7083,51.4583 21.7708,54.2292 21.7708,54.2292L 20.0143,50.7285C 26.3476,49.1452 27.7083,47.1042 27.7083,47.1042C 26.125,43.9375 23.75,38 28.5,30.0833C 33.25,22.1667 57,22.1667 57,22.1667 Z M 30.0833,44.3333L 31.6667,45.9167C 31.6667,45.9167 34.8333,44.3333 36.4167,39.5833C 38,34.8333 45.9167,26.9167 45.9167,26.9167C 42.75,28.5 36.4167,34.8333 34.8333,39.5833C 33.25,44.3333 30.0833,44.3333 30.0833,44.3333 Z " />
</g>
<g filter="url(#shadow)" id="alertIcon" fill="#aa0" transform="translate(34,28),scale(2.2,2.2)">
<path
d="M214.413,746a4.455,4.455,0,0,1-3.84-2.166,4.249,4.249,0,0,1,0-4.334l25.572-43.331a4.483,4.483,0,0,1,7.679,0L269.4,739.5a4.249,4.249,0,0,1,0,4.334,4.452,4.452,0,0,1-3.84,2.166H214.413ZM240,706a4,4,0,0,0-4,4v16a4,4,0,0,0,8,0V710A4,4,0,0,0,240,706Zm0,36a4,4,0,1,0-4-4A4,4,0,0,0,240,742Z"
id="attention" transform="translate(-209.969 -694)" />
</g>
</defs>
<g id="pvDetail" opacity="1" transform="scale(1,1)">
<g id="pvInfo" transform="translate(80,30)" class="clickable" onclick="displayOverlay('realtime')">
<!--<g
filter="url(#glow)">-->
<use href="#ElementBG" stroke="#574400" />
<use href="#sunIcon" />
<path id="pvArc" fill="none" stroke="#f7c000" stroke-width="30" />
<path id="pv2Arc" fill="none" stroke="#f78d00" stroke-width="30" />
<path id="pv3Arc" fill="none" stroke="#f72300" stroke-width="30" />
<use href="#circGrid" style="stroke:#574400;" />
<!--</g>-->
<text filter="url(#shadowMiddle)" class="powerTextClass">
<textPath id="pvText" href="#powerTextPath" startOffset="15%">--.-- kW</textPath>
<textPath id="pv3txt" href="#infoTextPath" startOffset="12%">--.-- kW</textPath>
<textPath id="pv2txt" href="#infoTextPath" startOffset="35%">--.-- kW</textPath>
<textPath id="pv1txt" href="#infoTextPath" startOffset="55%">--W</textPath>
</text>
</g>
<animate begin="openDetails.begin" attributetype="CSS" attributeName="opacity" from="0"
to="1.0"
dur="0.7s" repeatCount="1" calcMode="spline" keyTimes="0;1" keySplines=".1,0,.27,1"
fill="freeze" />
<animateTransform attributeName="transform"
type="scale"
from="0.1,0.1"
to="1,1"
begin="openDetails.begin"
dur="0.3s" repeatCount="1" fill="freeze" />
<animate begin="closeDetails.click" attributetype="CSS" attributeName="opacity" from="1.0"
to="0"
dur="0.4s" repeatCount="1" calcMode="spline" keyTimes="0;1" keySplines=".1,0,.27,1"
fill="freeze" />
<animateTransform attributeName="transform"
type="scale"
from="1,1"
to="0.1,0.1"
begin="closeDetails.click"
dur="0.7s" repeatCount="1" fill="freeze" />
<use href="#northIcon" transform="translate(1200,10),rotate(10)" />
<polygon points="370 0, 1300 0, 1300 700, 0 700, 0 250, 370 250" fill="rgb(24, 27, 31)" />
<polygon points="560,80 720,80 720,300 1160,300 1160,370 560,370" stroke-linejoin="round"
fill="#f7c002" stroke-width="30" stroke="#f7c002" opacity="0.1" />
<use href="#pvPlate" transform="translate(600,80), rotate(90)" />
<use href="#pvPlate" transform="translate(600,150), rotate(90)" />
<use href="#pvPlate" transform="translate(600,220), rotate(90)" />
<use href="#pvPlate" transform="translate(600,290), rotate(90)" />
<use href="#pvPlate" transform="translate(640,80), rotate(90)" />
<use href="#pvPlate" transform="translate(640,150), rotate(90)" />
<use href="#pvPlate" transform="translate(640,220), rotate(90)" />
<use href="#pvPlate" transform="translate(640,290), rotate(90)" />
<use href="#pvPlate" transform="translate(680,80), rotate(90)" />
<use href="#pvPlate" transform="translate(680,150), rotate(90)" />
<use href="#pvPlate" transform="translate(680,220), rotate(90)" />
<use href="#pvPlate" transform="translate(680,290), rotate(90)" />
<use href="#pvPlate" transform="translate(720,80), rotate(90)" />
<use href="#pvPlate" transform="translate(720,150), rotate(90)" />
<use href="#pvPlate" transform="translate(720,220), rotate(90)" />
<use href="#pvPlate" transform="translate(790,290)" />
<use href="#pvPlate" transform="translate(720,330)" />
<use href="#pvPlate" transform="translate(790,330)" />
<use href="#pvPlate" transform="translate(870,290)" />
<use href="#pvPlate" transform="translate(870,330)" />
<use href="#pvPlate" transform="translate(940,330)" />
<use href="#pvPlate" transform="translate(1160,300), rotate(90)" />
<use href="#pvPlate" transform="translate(1120,300), rotate(90)" />
<use href="#pvPlate" transform="translate(1080,300), rotate(90)" />
<text id="det_pv0P" filter="url(#shadowBig)" class="infoTextClass" dx="55" dy="30"
transform="translate(560, 150), scale(1.5,1.5)">-.-- kW</text>
<polygon points="980,60 1160,60 1160,265 980,265" stroke-linejoin="round" fill="#F76D00"
stroke-width="30" stroke="#F76D00" opacity="0.1" />
<use href="#pvPlate" transform="translate(1160,200), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1115,200), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1070,200), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1160,130), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1115,130), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1070,130), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1025,130), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1160,60), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1115,60), rotate(90), scale(1,1.125)" />
<use href="#pvPlate" transform="translate(1070,60), rotate(90), scale(1,1.125)" />
<text id="det_pv1P" filter="url(#shadowBig)" class="infoTextClass" dx="55" dy="30"
transform="translate(990, 140), scale(1.5,1.5)">-.-- kW</text>
<use href="#pvPlate" x="200" y="680" />
<text id="det_pv33P" filter="url(#shadowMiddle)" class="infoTextClass" x="200" y="680"
dx="36"
dy="26">#19</text>
<use href="#pvPlate" x="380" y="550" />
<text id="det_pv32P" filter="url(#shadowMiddle)" class="infoTextClass" x="380" y="550"
dx="36"
dy="26">#19</text>
<use href="#pvPlate" x="380" y="590" />
<text id="det_pv31P" filter="url(#shadowMiddle)" class="infoTextClass" x="380" y="590"
dx="36"
dy="26">#18</text>
<use href="#pvPlate" x="380" y="630" />
<text id="det_pv30P" filter="url(#shadowMiddle)" class="infoTextClass" x="380" y="630"
dx="36"
dy="26">#17</text>
<use href="#pvPlate" x="310" y="510" />
<text id="det_pv29P" filter="url(#shadowMiddle)" class="infoTextClass" x="310" y="510"
dx="36"
dy="26">#16</text>
<use href="#pvPlate" x="310" y="550" />
<text id="det_pv28P" filter="url(#shadowMiddle)" class="infoTextClass" x="310" y="550"
dx="36"
dy="26">#15</text>
<use href="#pvPlate" x="310" y="590" />
<text id="det_pv27P" filter="url(#shadowMiddle)" class="infoTextClass" x="310" y="590"
dx="36"
dy="26">#14</text>
<use href="#pvPlate" x="310" y="630" />
<text id="det_pv26P" filter="url(#shadowMiddle)" class="infoTextClass" x="310" y="630"
dx="36"
dy="26">#13</text>
<use href="#pvPlate" x="240" y="510" />
<text id="det_pv25P" filter="url(#shadowMiddle)" class="infoTextClass" x="240" y="510"
dx="36"
dy="26">#12</text>
<use href="#pvPlate" x="240" y="550" />
<text id="det_pv24P" filter="url(#shadowMiddle)" class="infoTextClass" x="240" y="550"
dx="36"
dy="26">#11</text>
<use href="#pvPlate" x="240" y="590" />
<text id="det_pv23P" filter="url(#shadowMiddle)" class="infoTextClass" x="240" y="590"
dx="36"
dy="26">#10</text>
<use href="#pvPlate" x="240" y="630" />
<text id="det_pv22P" filter="url(#shadowMiddle)" class="infoTextClass" x="240" y="630"
dx="36"
dy="26">#9</text>
<use href="#pvPlate" x="170" y="510" />
<text id="det_pv21P" filter="url(#shadowMiddle)" class="infoTextClass" x="170" y="510"
dx="36"
dy="26">#8</text>
<use href="#pvPlate" x="170" y="550" />
<text id="det_pv20P" filter="url(#shadowMiddle)" class="infoTextClass" x="170" y="550"
dx="36"
dy="26">#7</text>
<use href="#pvPlate" x="170" y="590" />
<text id="det_pv19P" filter="url(#shadowMiddle)" class="infoTextClass" x="170" y="590"
dx="36"
dy="26">#6</text>
<use href="#pvPlate" x="170" y="630" />
<text id="det_pv18P" filter="url(#shadowMiddle)" class="infoTextClass" x="170" y="630"
dx="36"
dy="26">#5</text>
<use href="#pvPlate" x="100" y="510" />
<text id="det_pv14P" filter="url(#shadowMiddle)" class="infoTextClass" x="100" y="510"
dx="36"
dy="26">#1</text>
<use href="#pvPlate" x="100" y="550" />
<text id="det_pv15P" filter="url(#shadowMiddle)" class="infoTextClass" x="100" y="550"
dx="36"
dy="26">#2</text>
<use href="#pvPlate" x="100" y="590" />
<text id="det_pv16P" filter="url(#shadowMiddle)" class="infoTextClass" x="100" y="590"
dx="36"
dy="26">#3</text>
<use href="#pvPlate" x="100" y="630" />
<text id="det_pv17P" filter="url(#shadowMiddle)" class="infoTextClass" x="100" y="630"
dx="36"
dy="26">#4</text>
<use href="#pvPlate" transform="translate(600,500)" />
<text id="det_pv13P" filter="url(#shadowMiddle)" class="infoTextClass" x="600" y="500"
dx="36"
dy="26">- W</text>
<use href="#pvPlate" transform="translate(500,500)" />
<text id="det_pv12P" filter="url(#shadowMiddle)" class="infoTextClass" x="500" y="500"
dx="36"
dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,120), rotate(-90)" />
<text id="det_pv5P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,120), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,190), rotate(-90)" />
<text id="det_pv4P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,190), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,270), rotate(-90)" />
<text id="det_pv9P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,270), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,340), rotate(-90)" />
<text id="det_pv8P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,340), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,420), rotate(-90)" />
<text id="det_pv11P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,420), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(460,490), rotate(-90)" />
<text id="det_pv10P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(460,490), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(400,120), rotate(-90)" />
<text id="det_pv7P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(400,120), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(400,190), rotate(-90)" />
<text id="det_pv6P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(400,190), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(400,270), rotate(-90)" />
<text id="det_pv3P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(400,270), rotate(-90)" dx="36" dy="26">- W</text>
<use href="#pvPlate" transform="translate(400,340), rotate(-90)" />
<text id="det_pv2P" filter="url(#shadowMiddle)" class="infoTextClass"
transform="translate(400,340), rotate(-90)" dx="36" dy="26">- W</text>
<text id="invList" filter="url(#shadowMiddle)" class="tooltipTextClass"
transform="translate(80,255)"></text>
<rect width="305" height="210" x="70" y="250" rx="5" ry="5" fill="none" stroke-width="4px"
stroke="#f7c000" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 33 KiB

+50 -44
View File
@@ -1,21 +1,30 @@
<style>
.stream{
animation: stream 2s steps(40) infinite;
/* Fluss-Animation als transform statt stroke-dashoffset.
stroke-dashoffset ist nicht kompositierbar - jede Stufe kostete einen
Neuzeichenvorgang auf dem Hauptthread. Ein transform kann der Compositor
dagegen selbst verschieben.
Die Punkte laufen eine Periode (111 Einheiten) weit, danach steht der
naechste an derselben Stelle - der Zyklus schliesst nahtlos.
--dx/--dy stehen pro Linie im style-Attribut, --w setzt setFlowWidth().
steps(40) = 20 Bewegungen pro Sekunde, wie in der urspruenglichen
Fassung. Das deckelt die Neuzeichnungen fuer den Fall, dass der Browser
das transform doch nicht kompositiert; auf dem Compositor kostet die
Stufung nichts. Fuer volle Fluessigkeit: linear statt steps(40). */
.stream, .stream-rev {
animation: flow 2s steps(40) infinite;
}
@keyframes stream {
100%{
stroke-dashoffset: -110;
.stream-rev {
animation-direction: reverse;
}
}
.stream-rev{
animation: stream-rev 2s steps(40) infinite;
@keyframes flow {
to { transform: translate(var(--dx), var(--dy)); }
}
@keyframes stream-rev {
100%{
stroke-dashoffset: 110;
.stream circle, .stream-rev circle {
r: calc(var(--w, 0px) / 2);
fill: gray;
}
}
.powerTextClass {
.powerTextClass {
font-size: 27px;
font-family: sans-serif;
text-anchor: middle;
@@ -63,6 +72,16 @@
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<clipPath id="clip_consOGani"><rect x="-30" y="-30" width="404.4" height="60" transform="translate(770.0,380.0) rotate(-64.1790)"/></clipPath>
<clipPath id="clip_consAni"><rect x="-30" y="-30" width="400.0" height="60" transform="translate(430.0,380.0) rotate(0.0000)"/></clipPath>
<clipPath id="clip_consEGani"><rect x="-30" y="-30" width="386.5" height="60" transform="translate(770.0,380.0) rotate(62.6501)"/></clipPath>
<clipPath id="clip_consUGani"><rect x="-30" y="-30" width="396.2" height="60" transform="translate(770.0,380.0) rotate(120.3791)"/></clipPath>
<clipPath id="clip_consHeatAni"><rect x="-30" y="-30" width="410.0" height="60" transform="translate(770.0,380.0) rotate(0.0000)"/></clipPath>
<clipPath id="clip_consEVani"><rect x="-30" y="-30" width="360.0" height="60" transform="translate(920.0,670.0) rotate(0.0000)"/></clipPath>
<clipPath id="clip_consEVOGani"><rect x="-30" y="-30" width="360.0" height="60" transform="translate(920.0,70.0) rotate(0.0000)"/></clipPath>
<clipPath id="clip_consGridani"><rect x="-30" y="-30" width="390.0" height="60" transform="translate(100.0,380.0) rotate(0.0000)"/></clipPath>
<clipPath id="clip_pvani"><rect x="-30" y="-30" width="413.6" height="60" transform="translate(180.0,130.0) rotate(45.0000)"/></clipPath>
<clipPath id="clip_battani"><rect x="-30" y="-30" width="413.6" height="60" transform="translate(180.0,630.0) rotate(-45.0000)"/></clipPath>
</defs>
<g opacity="0">
<animate begin="lastInitAni.end" attributetype="CSS" attributeName="opacity" from="0.0" to="1.0"
@@ -81,44 +100,34 @@
+500 -300 (center +90 in x und y)
-->
<line x1="770" y1="380" x2="920" y2="70" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consOGani" class="stream" x1="770" y1="380" x2="920" y2="70" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consOGani)"><g id="consOGani" class="stream" style="--dx:48.347px;--dy:-99.918px"><circle cx="721.7" cy="479.9"/><circle cx="770.0" cy="380.0"/><circle cx="818.3" cy="280.1"/><circle cx="866.7" cy="180.2"/><circle cx="915.0" cy="80.2"/><circle cx="963.4" cy="-19.7"/></g></g>
<line x1="430" y1="380" x2="770" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consAni" class="stream" x1="430" y1="380" x2="770" y2="380" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consAni)"><g id="consAni" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="319.0" cy="380.0"/><circle cx="430.0" cy="380.0"/><circle cx="541.0" cy="380.0"/><circle cx="652.0" cy="380.0"/><circle cx="763.0" cy="380.0"/><circle cx="874.0" cy="380.0"/></g></g>
<line x1="770" y1="380" x2="920" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consEGani" class="stream" x1="770" y1="380" x2="920" y2="670" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consEGani)"><g id="consEGani" class="stream" style="--dx:50.996px;--dy:98.592px"><circle cx="719.0" cy="281.4"/><circle cx="770.0" cy="380.0"/><circle cx="821.0" cy="478.6"/><circle cx="872.0" cy="577.2"/><circle cx="923.0" cy="675.8"/></g></g>
<line x1="770" y1="380" x2="600" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consUGani" class="stream" x1="770" y1="380" x2="600" y2="670" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consUGani)"><g id="consUGani" class="stream" style="--dx:-56.135px;--dy:95.759px"><circle cx="826.1" cy="284.2"/><circle cx="770.0" cy="380.0"/><circle cx="713.9" cy="475.8"/><circle cx="657.7" cy="571.5"/><circle cx="601.6" cy="667.3"/><circle cx="545.5" cy="763.0"/></g></g>
<line x1="770" y1="380" x2="1120" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consHeatAni" class="stream" x1="770" y1="380" x2="1120" y2="380" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consHeatAni)"><g id="consHeatAni" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="659.0" cy="380.0"/><circle cx="770.0" cy="380.0"/><circle cx="881.0" cy="380.0"/><circle cx="992.0" cy="380.0"/><circle cx="1103.0" cy="380.0"/><circle cx="1214.0" cy="380.0"/></g></g>
<line x1="920" y1="670" x2="1220" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consEVani" class="stream" x1="920" y1="670" x2="1220" y2="670" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consEVani)"><g id="consEVani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="809.0" cy="670.0"/><circle cx="920.0" cy="670.0"/><circle cx="1031.0" cy="670.0"/><circle cx="1142.0" cy="670.0"/><circle cx="1253.0" cy="670.0"/></g></g>
<line x1="920" y1="70" x2="1220" y2="70" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consEVOGani" class="stream" x1="920" y1="70" x2="1220" y2="70" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consEVOGani)"><g id="consEVOGani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="809.0" cy="70.0"/><circle cx="920.0" cy="70.0"/><circle cx="1031.0" cy="70.0"/><circle cx="1142.0" cy="70.0"/><circle cx="1253.0" cy="70.0"/></g></g>
<line x1="100" y1="380" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="consGridani" class="stream" x1="100" y1="380" x2="430" y2="380" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_consGridani)"><g id="consGridani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="-11.0" cy="380.0"/><circle cx="100.0" cy="380.0"/><circle cx="211.0" cy="380.0"/><circle cx="322.0" cy="380.0"/><circle cx="433.0" cy="380.0"/></g></g>
<line x1="180" y1="130" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="pvani" class="stream" x1="180" y1="130" x2="430" y2="380" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_pvani)"><g id="pvani" class="stream" style="--dx:78.489px;--dy:78.489px"><circle cx="101.5" cy="51.5"/><circle cx="180.0" cy="130.0"/><circle cx="258.5" cy="208.5"/><circle cx="337.0" cy="287.0"/><circle cx="415.5" cy="365.5"/><circle cx="494.0" cy="444.0"/></g></g>
<line x1="180" y1="630" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
<line id="battani" class="stream" x1="180" y1="630" x2="430" y2="380" stroke-linecap="round"
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
<g clip-path="url(#clip_battani)"><g id="battani" class="stream" style="--dx:78.489px;--dy:-78.489px"><circle cx="101.5" cy="708.5"/><circle cx="180.0" cy="630.0"/><circle cx="258.5" cy="551.5"/><circle cx="337.0" cy="473.0"/><circle cx="415.5" cy="394.5"/><circle cx="494.0" cy="316.0"/></g></g>
</g>
</svg>
@@ -127,21 +136,18 @@
style="position:absolute;top:0;"
viewBox="-100 -100 1600 950" width="100%" height="100%" id="realtimeSvg">
<defs>
<filter id="shadow" x="-0.5" y="-0.5" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="0.7" />
<filter id="shadow" x="-0.3" y="-0.3" width="160%" height="160%">
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="0.7" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="0.5" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
<filter id="shadowMiddle" x="-1.0" y="-1.0" width="300%" height="300%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
<filter id="shadowMiddle" x="-0.4" y="-0.4" width="180%" height="180%">
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="3" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="1" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
<filter id="shadowBig" x="-1" y="-1" width="300%" height="300%">
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
<filter id="shadowBig" x="-0.45" y="-0.45" width="190%" height="190%">
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="3" />
<feGaussianBlur result="offOut" in="offOut" stdDeviation="2" />
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
</filter>
@@ -581,7 +587,7 @@
style='display:none;mix-blend-mode: difference;fill:#70CCBB;' href="#heater" />
</g>
<g transform="translate(330,280), scale(0.70,0.70)" id="waterInfo" class="clickable" onclick="openModal('watering')">
<g transform="translate(330,280), scale(0.90,0.90)" id="waterInfo" class="clickable" onclick="openModal('watering')">
<animateMotion begin="0.5s" dur=".7s" repeatCount="1" calcMode="spline" keyTimes="0;1"
keySplines=".1,0,.27,1" path="M0 0 L340 0" fill="freeze" />
<animateMotion begin="1.2s" dur=".7s" repeatCount="1" calcMode="spline" keyTimes="0;1"
@@ -591,7 +597,7 @@
d="M 99.863863 22.00012 A 78 78 0 1 0 100 22" />
<use href="#water" transform="translate(60,55), scale(0.20,0.20)" fill="#3A6292" />
<!-- Wasserstand und Temperatur werden von der Bewässerungssteuerung nicht unterstützt.
<text id="waterText" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="55">--.- cm</text>
<text id="waterText" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="55">-.- cm</text>
<text id="waterTemp" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="88">-.- °C</text>
-->
<use id="wateringFrontIcon" href="#gardenPlantIcon" transform="translate(152,162),rotate(310),scale(1.3)" fill="#6c757d" color="#6c757d">