Die Raeder hatten fast halbrunde Enden (rx 11 bei 25 Einheiten Breite) und
sahen dadurch aus wie Kapseln. Von oben ist eine Lauffläche ein Rechteck mit
leicht gebrochenen Ecken - rx 5.
Der Klimaknopf sass in der Mitte der Windschutzscheibe und damit dicht ueber
der Prozentzahl des Ladestands; beide lasen sich als ein Block. Er sitzt
jetzt im oberen Drittel der Scheibe (cy 206 statt 220). Die Zahl bleibt, wo
sie ist: sie steht auf dem Goldenen Schnitt der Akkuplatte (108 + 270 * 0,618
= 275), und das war Absicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Sachen, alle aus dem Vergleich mit der Seitenansicht:
Die Raeder waren ein Viertel zu klein: gezeichnet 58 auf 21 Einheiten, am
Fahrzeug sind es 235/50 R20, also 744 mm Durchmesser auf 235 mm Breite oder
78 auf 25 Einheiten. Das Rad ist im Bild der einzige Gegenstand mit bekanntem
Mass - ist es zu klein, wirkt alles andere zu gross, allen voran die
Schnauze. Die ist naemlich richtig: bis zum Scheibenfuss sind es 1,6 m von
4,65 m Gesamtlaenge, am Auto knapp 1,8 m.
Die Tueren waren gleich lang. Sind sie nicht: die Trennfuge liegt bei 2,60 m,
die hintere Fuge bei 3,35 m, macht 85 zu 75 Zentimeter (89 zu 79 Einheiten).
Vorher waren beide 104 Einheiten lang und zusammen einen halben Meter zu
lang.
Heckscheibe und Heckklappe sind eine Schaltflaeche - die Scheibe sitzt in der
Klappe und geht mit ihr auf. Sie behaelt nur ihr Aussehen (.teil > .scheibe
im Stylesheet, und beim Oeffnen faerbt sie sich durchsichtiger als das
Blech). Erst dadurch konnte das Dach dorthin, wo es hingehoert: es endet
jetzt bei 4,0 m statt 3,8 m, am Auto sind es 4,15 m. Als getrennte Flaeche
waere die Klappe dabei auf drei Zentimeter geschrumpft und nicht mehr zu
treffen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Frage war berechtigt. Nachgemessen an der Seitenansicht, umgerechnet mit
105 Einheiten je Meter (der Wagen ist 4,65 m lang und 488 Einheiten):
vorher jetzt Fahrzeug
Scheibenfuss 1,39 m 1,62 m ~1,75 m
Dachanfang 1,85 m 2,37 m ~2,55 m
Dachende 3,14 m 3,81 m ~4,15 m
Dachlaenge 1,30 m 1,44 m ~1,55 m
Das ganze Glashaus sass also gut einen halben Meter zu weit vorn und war zu
kurz - und mit ihm Reling und Spoiler. Die Reling lief ausserdem nur ueber
zwei Drittel des Daches; sie geht jetzt von 262 bis 402, also fast von der
Windschutzscheibe bis zum Spoiler, wie am Auto.
Mitgezogen sind alle Teile, die am Glashaus haengen: Motorhaube, beide
Scheiben, die Tueren (jetzt 104 statt 74 und 66 Einheiten lang, nach den
echten Tuerbreiten), die Seitenfenster, die Aussenspiegel an den Fuss der
A-Saeule und der Klimaknopf in die Mitte der Windschutzscheibe.
Ganz massstaeblich ist es weiterhin nicht: das Dach endet am Auto erst bei
4,15 m. Dahinter blieben fuer Heckscheibe, Klappe und Stossfaenger zusammen
fuenf Zentimeter Bild, und die Heckklappe waere als Schaltflaeche nicht mehr
zu treffen. Die letzten vierzig Zentimeter sind deshalb gedehnt - eine
bewusste Abweichung, die im Quelltext auch so dasteht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Dinge aus dem Abgleich mit dem Foto:
Die Front lief spitz zu wie das Heck vorher. Der Enyaq ist auch vorn stumpf:
eine Kante von 70 bis 154, davor die Tech-Deck-Blende als Band statt als
Bogen, die acht Leuchtelemente flacher und weiter aussen, die Motorhaube an
die neue Bugkante gezogen.
Die Anhaengerkupplung stand ueber die Heckkante hinaus und las sich wie eine
Unterbrechung des Umrisses. Sie sitzt jetzt vollstaendig innerhalb.
Dachreling und Heckspoiler lagen im Markup vor der Akkuplatte - also unter
ihr, und die Platte ist halbdurchsichtig: von den Holmen war fast nichts mehr
zu sehen. Sie stehen jetzt dahinter, wo sie hingehoeren (Reling und Spoiler
liegen auf dem Dach, die Batterie im Boden), und sind schwarz statt in
Blechfarbe - an diesem Fahrzeug sind sie es auch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Fahrzeug lief hinten spiegelbildlich zur Front spitz zusammen - von oben
genau die Form eines Coupes. Der Enyaq ist aber der SUV:
Karosserie Die Flanken bleiben bis kurz vor den Schluss auf voller Breite
(212 bei y=250, noch 206 bei y=452), dann runden zwei Ecken auf
eine gerade Heckkante von 56 bis 168.
Heckscheibe steiler (336 bis 376 statt 382) und nach unten schmaler statt
breiter - das Auslaufen nach hinten war das Fliessheck-Merkmal.
Heckklappe folgt der neuen Kontur, innen abgesetzt wie am Auto.
Rueckleuchten sitzen in den Ecken und greifen von der Klappe auf die Flanke
ueber, so wie das Band am Original um die Ecke laeuft. Weiter
innen sahen sie aus wie zwei Griffe in der Klappe.
Dazu die Anhaengerkupplung, die dieses Fahrzeug hat: Hals und Kugel, das
einzige Teil, das ueber die Heckkante hinaussteht - Platz dafuer war im
viewBox unten schon.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Anpassungen am Fahrbild:
Die Zeichenflaeche ist 15 % breiter (viewBox 294,4 statt 256, mittig um den
Wagen), und die max-width waechst mit auf 297 px - das Fahrzeug bleibt also
gleich gross, es kommt nur Platz daneben dazu. Die beiden Markierungen
ruecken um dieselben 15 % nach aussen (x -23,7 und 247,7), damit zwischen Rad
und Fahrbahnrand Luft fuer den Fahrtwind bleibt.
Die Markierung ist 4,2 statt 3,15 breit und etwas heller. Massstaeblich waere
3,15; so hebt sie sich aber deutlich vom Fahrtwind ab, der mit 2,5 daneben
laeuft - und darum ging es.
Die Bananenschale liegt jetzt in der linken Radspur (x 16, die Raeder stehen
zwischen 5 und 26) statt frei auf der Fahrbahn. Unter dem Reifen hat sie ihre
Wirkung, und dass der Wagen danach nach rechts ausbricht, passt zur Seite, auf
der er den Halt verliert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ganz selten liegt waehrend der Fahrt eine Bananenschale auf der Strasse, und
der Wagen kommt kurz ins Schleudern - erst bricht er nach rechts aus, dann
faengt ihn das Gegenlenken, dann trudelt er aus.
Der Vorlauf der zweiten Bewegung ist gerechnet, nicht geschaetzt: die Schale
startet 40 Einheiten ueber dem Bild, die Vorderachse liegt bei 97, macht 137
Einheiten - bei 437 Einheiten je Sekunde sind das 0,31 s. Genau dann setzt
das Schleudern ein.
Damit das Fahrzeug sich drehen kann, ohne die Strasse mitzunehmen, liegt es
jetzt in einer eigenen Gruppe (#wagen); die Schale sitzt im Markup davor und
verschwindet unter der Karosserie, sobald der Wagen darueberrollt.
Ausgeloest wird alle 20 Sekunden mit zwei Prozent Wahrscheinlichkeit und nur
waehrend der Fahrt - im Mittel einmal in gut sechzehn Minuten. Selten genug,
dass man es nicht erwartet; haeufig genug, dass es irgendwann jemand sieht.
Wer Bewegungen abbestellt hat, bekommt den Gruss gar nicht erst: ein
schleuderndes Auto ist genau das, was damit gemeint ist. Haelt der Wagen
mitten im Ausrutscher an, wird die Schale eingesammelt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die seitlichen Streifen liefen genau auf der Linie der Markierung und sahen
dort aus wie eine zweite, gestrichelte Begrenzung statt wie Luft. Sie sitzen
jetzt zwischen Rad und Markierung (x 0 und 224 statt -6 und 230), und alle
vier sind schmaler: 2,5 statt 4 neben dem Wagen, 2 statt 3 darueber.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Striche waren immer noch zu praesent. Jetzt liegt die Strasse im Viertel
des Fahrzeugmassstabs: Leitlinie 157,5 auf 315 Luecke, 3,15 breit, rechts
weiterhin durchgezogen. Das Verhaeltnis 1:2 bleibt, die Markierung ist
Beiwerk statt Hauptsache.
Das Tempo ist mit halbiert - 437 statt 875 Einheiten je Sekunde. Weil auch
die Strichlaenge halbiert ist, ziehen die Striche im selben Takt vorbei wie
zuvor; die Bewegung selbst ist ruhiger. Der Fahrtwind laeuft weiterhin genau
so schnell wie die Fahrbahn (nachgemessen: 437 gegen 436 Einheiten je
Sekunde).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Massstaeblich waren die Striche zu gross fuers Bild: 12,6 Einheiten breit und
630 lang, das fuellte die Raender und zog den Blick vom Fahrzeug weg.
Jetzt ist die Strasse im halben Massstab des Wagens gezeichnet - Leitlinie
315 auf 630 Luecke, 6,3 breit. Das Verhaeltnis 1:2 bleibt, die Markierung
liest sich weiter als Leitlinie, und das Fahrzeug ist wieder das Groesste im
Bild. Rechts bleibt die Fahrbahnbegrenzung durchgezogen.
Die Geschwindigkeit bleibt bei 875 Einheiten je Sekunde. Im halben Massstab
sind das gut 60 km/h statt der 30 zuvor - fuer eine Landstrasse die
passendere Zahl, und der Takt der vorbeiziehenden Striche bleibt derselbe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Baumkronen neben der Fahrbahn sahen aus wie Erbsen und nicht wie eine
Allee - sie sind raus. Stattdessen ist die Markierung jetzt richtig.
Massstab: der Wagen ist 4,65 m lang und misst im Bild 488 Einheiten, eine
Einheit ist also knapp ein Zentimeter (105 je Meter). Danach richten sich
alle Masse:
rechts Fahrbahnbegrenzung, durchgezogen
links Leitlinie, 6 m Strich auf 12 m Luecke (630 auf 1260 Einheiten)
beide 0,12 m breit, also 12,6 Einheiten
Der Strich ist damit laenger als das Bild hoch ist, und zwischen zwei
Strichen liegt mehr als eine Bildhoehe - genau so sieht eine Landstrasse aus
dem Auto auch aus. Sichtbar ist eine Markierung dadurch etwa zwei Drittel der
Zeit.
Die Geschwindigkeit ist ebenfalls abgeleitet und nicht geraten: 875 Einheiten
je Sekunde sind gut 30 km/h. Der Fahrtwind laeuft jetzt genauso schnell - ein
Streifen, der die Fahrbahnmarkierung ueberholt, faellt sofort auf.
Nicht massstaeblich bleibt die Breite der Fahrbahn: neben dem Wagen sind
zwanzig Zentimeter Platz statt der drei Viertel Meter einer echten Spur.
Dafuer muesste das Fahrzeug halb so gross gezeichnet werden, und darum geht
es auf dieser Kachel nicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ob das Auto gerade rollt, stand bisher nur klein unter der Karte
("unterwegs - zuletzt: ..."). Im Bild selbst, wo man zuerst hinsieht, war es
nicht zu erkennen.
Waehrend der Fahrt liegt jetzt eine Strasse unter dem Wagen: dunkler Belag,
gestrichelte Markierungen in den Randstreifen neben den Raedern, zwei Reihen
Baumkronen, die aussen vorbeiziehen. Dazu vier Windstreifen - zwei neben dem
Wagen, zwei ueber ihn hinweg, heller und duenner, damit sie wie Luft wirken
und nicht wie ein Riss im Lack.
Beide Schleifen treffen sich selbst: die Striche wandern um eine
Strich-Lueckenlaenge (46), die Baumreihen um ihren Abstand (160) - danach
steht das Muster wieder wie zuvor, und man sieht keinen Sprung. Markierungen
und Baeume laufen mit derselben Geschwindigkeit, der Wind etwa anderthalbmal
so schnell; groessere Unterschiede lassen die Bewegungen auseinanderfallen.
Dazu ein Abzeichen "unterwegs" im Kopf der Kachel - fuer Vorleseprogramme und
fuer alle, die Bewegungen abgeschaltet haben; dann steht die Landschaft still
(prefers-reduced-motion).
Der Zustand kommt aus park_state der juengsten Zeile; der Broker kennt ihn
nicht, unter solarManager/ev* stehen nur Ladestand, Reichweite und Ladung.
Unterwegs fragt der Sammler alle vier Minuten, die Seite laedt jede Minute
nach - die Anzeige hinkt also um wenige Minuten hinterher.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"status_ntf" am Geraet heisst nur, dass gesendet werden darf - nicht, dass
jede Komponente es tut. Der erste Suchlauf hat deshalb auch die
Temperaturkomponente der beiden Pro 3EM auf ein Topic gelegt
(Power_EG/status/temperature:0), und dort kam nie etwas an: unter Power_EG/#
sendet das Geraet ausschliesslich em:0, emdata:0 und online. Die beiden
Temperaturmesswerte waeren still auf ihrem letzten Wert stehengeblieben.
Jetzt entscheidet die Liste MQTT_KOMPONENTEN, welche Komponente ein Topic
bekommt - heute em und switch. Alles andere bleibt beim Abfragen: langsamer,
aber richtig. Nachgetragen wird per Hand, nachdem man mitgehoert hat; eine
automatische Erkennung waere unzuverlaessig, weil eine Komponente, die nur
bei Aenderung sendet, waehrend eines kurzen Lauschens nichts sagt.
Nach dem erneuten Suchlauf: die beiden EM-Zaehler kommen ueber den Broker,
die beiden Temperaturen und der Gen1-Handtuchtrockner werden abgefragt -
HTTP: 3 Messwerte an 3 Endpunkten statt vorher 35.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ein Zaehler zaehlt in der Richtung, in der er eingebaut ist - einer der
beiden Shelly-Zaehler meldet deshalb mit umgekehrtem Vorzeichen, und auf der
Kachel stand der Verbrauch als Minusleistung.
Neu gibt es dafuer den Schalter "negativ" an jedem Kachelwert. Er sitzt in
der Anzeige und nicht am Zaehler: Automatiken und Statistik lesen dieselbe
Nachricht und rechnen mit dem Vorzeichen, das dort steht - wer es an der
Quelle drehte, verschoebe die Rechnung an einer Stelle, an der niemand
danach sucht.
Gedreht wird vor dem Formatieren, also auch vor der Skalierung zwischen W
und kW und vor den Nachkommastellen. Aus -0 wird wieder 0. Was keine Zahl
ist, bleibt unangetastet und die Kachel zeigt weiter ihren Strich.
In der eingeklappten Kurzfassung steht das Minus vor dem Namen, damit man
ohne Aufklappen sieht, welcher Wert gedreht ist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fuer die Symbole vor den Zahlen standen drei Codepunkte von Hand in
rooms.php, und die Maske bot genau diese drei an. Jedes weitere Symbol waere
eine Codeaenderung gewesen.
Die Codepunkte stehen aber schon im Haus: css/bootstrap-icons.min.css fuehrt
sie unter .bi-<name>::before - dieselbe Quelle, aus der auch der Browser
liest. bootstrapIcons() liest sie von dort (2078 Stueck, einmal je Anfrage),
kachelIcon() schlaegt darin nach. Damit ist jedes Symbol moeglich, und ein
Versionswechsel der Icons zieht von selbst mit.
In der Maske steht deshalb kein Auswahlfeld mehr, sondern der Name mit einer
Vorschau davor - "moisture" sagt nichts, das Symbol daneben schon. Die
Vorschlagsliste beginnt mit gut dreissig ueblichen Symbolen unter deutscher
Beschriftung (Temperatur, Feuchte, Leistung, Wallbox, Regen ...), danach folgt
der ganze Rest alphabetisch. Ein Name, den es nicht gibt, zeigt sofort ein
rotes Fragezeichen und wird beim Speichern mit Begruendung abgelehnt.
In der eingeklappten Kurzfassung einer Kachel steht das Symbol jetzt mit -
es ist das schnellste Erkennungszeichen dafuer, welcher der drei Werte
gemeint ist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Einstellungen bestanden aus einer einzigen langen Spalte mit den
Preistabellen. Sie bekommt Reiter, und darin zwei neue Flaechen: was die
Kacheln der Startseite anzeigen, und welche Geraete es ueberhaupt gibt.
Reiter gab es vorher dreimal in drei Ausfuehrungen - die Etagen ueber den
Automatismen mit eigenem switchTab(), die Geraetegruppen im Raum-Modal mit
eigener CSS-Klasse, und die Einstellungsseite noch einmal anders. Jetzt baut
restricted/reiter.php alle drei; umgeschaltet wird von Bootstrap, den offenen
Reiter merkt reiterMerken() in der Adresse.
Kachelwerte: was auf einer Kachel steht, stand fest in rooms.php. Die neue
Tabelle kachelWerte (solarLog_kacheln.sql) ueberschreibt das je Raum, die
Maske waehlt die Messwerte aus demselben Katalog wie der Automatik-Editor -
nach Etage sortiert, die Geraete des eigenen Raums oben. Fehlt die Tabelle,
zeigt jede Kachel weiter ihre Vorgabe.
Geraete: die Zuordnung Geraet -> Raum war ein Modal, erreichbar ueber ein
Zahnrad neben den Automatismen. Sie ist eine Einstellung und steht jetzt dort,
zusammen mit dem, was fehlte: seit wann ein Geraet nichts mehr meldet, in
welchen Automatiken es steckt, und ein Loeschknopf. Letzterer ist noetig, weil
der Suchlauf nichts loescht - er legt an und frischt auf, damit die Automatiken
ihre Zustands-Ids behalten; ein abgebautes Geraet bliebe sonst fuer immer
stehen. Geloescht wird nur, was in keiner Automatik vorkommt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Shelly-Erkennung schrieb bisher fuer jedes Geraet eine HTTP-Adresse in
actor_states.url; der Automatik-Runner musste die Werte deshalb im Takt
abfragen, obwohl die Gen2-Geraete ihren Zustand ohnehin von sich aus an den
Broker melden. Sichtbar wurde das an den beiden Stromzaehlern: ihre Messwerte
standen nirgends als Topic, weshalb sie weder in den Kachelwerten noch im
Automatik-Editor auftauchten.
Gen2-Geraete werden jetzt nach ihrer MQTT-Einrichtung gefragt
(/rpc/Mqtt.GetConfig). Ist sie eingeschaltet, meldet das Geraet Statusaenderungen
und hat ein Topic-Praefix, so steht in url das Topic
(<praefix>/status/<komponente>:<index>) und in value_path der Schluessel in der
Nachricht. Fehlt eines davon - und bei allen Gen1-Geraeten, die kein MQTT
koennen - bleibt alles beim HTTP-Weg.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Teile, die zusammengehoeren: die Fahrzeugkachel zeigt den Ladestand
jetzt dort, wo er im Auto auch sitzt, die Jahresstatistik wird zur
Tabelle, und beide holen ihr Aussehen aus einer gemeinsamen Farbwelt.
Fahrzeugkachel. Die Kachel "Batterie und Ladung" ist aufgeloest; ihr
Inhalt steckt in der Draufsicht. Die Akkuplatte im Fahrzeugboden fuellt
sich von hinten nach vorn, traegt die Zielmarke und nennt Prozent und
Reichweite in ihrer Mitte - auf dem Goldenen Schnitt der Plattenhoehe,
damit sie nicht am Klimaknopf klebt. Beim Laden wandern Streifen im
gefuellten Teil nach vorn, und vom Anschluss fliesst eine Linie in die
Platte. Was sich nicht zeichnen laesst - Ladeleistung, Restzeit,
Kilometerstand, Klima, Herkunft des Ladestroms - steht als Kennzahl
daneben, dazu die gefahrenen Kilometer aus Woche, Monat und Jahr
(?was=strecke, gerechnet aus dem Zaehlerstand statt aus erkannten
Fahrten - faellt eine Zeile aus, fehlt die Fahrt in der Liste, im
Zaehlerstand aber nicht).
Am Fahrzeug selbst: kein Panoramadach, das hat unseres nicht. Reling und
Spoiler neu gezeichnet, weil sie mit der Dachplatte bisher ein
geschlossenes Rechteck bildeten und das wie ein Fensterrahmen aussah. Die
Blende am Bug ist schmaler und heller - von oben sieht man von einer
senkrechten Flaeche nur einen Streifen, und fast schwarz las sie sich wie
ein Loch. Die Ladeklappe ist gebaut wie der Klimaknopf; den Ladezustand
traegt jetzt die Farbe statt einer zweiten Form.
Jahresvergleich. getStats.php liefert kein fertiges HTML mehr, sondern
JSON, das sich selbst beschreibt: Einheit, Nachkommastellen, Richtung und
Zugehoerigkeit stehen als Metadaten je Kennzahl, nicht mehr als zwei
Arrays, die ueber den Spaltenindex mit der Abfrage synchron gehalten
werden mussten. Zwei Abfragen holen alles - Monatswerte, daraus die
ganzen Jahre und die Summe seit Aufzeichnungsbeginn, dazu der gleiche
Zeitraum jedes Jahres bis zum heutigen Kalendertag. Verhaeltniszahlen
sind auf jeder Ebene neu aus den Summen gerechnet; ein Jahresmittel ist
nicht das Mittel der Monatsmittel.
Gezeichnet wird das von einem Baustein, den sich Historien- und
Solarseite teilen: dort drei Jahresspalten mit verschiebbarem Fenster bis
zurueck zum ersten Jahr, hier eine Spalte ohne Werkzeuge. Zeilen, die
sich aufteilen, stehen als "davon" darunter; was bereits in einer anderen
Zeile steckt, als "darin" samt Namen der Zeile - der Beitrag der Batterie
und die Solarladung des Autos duerfen nicht zum Ertrag addiert werden.
Zusammengefasste Zeilen sind zunaechst zu, damit die Tabelle mit zehn
Zeilen aufmacht statt mit siebzehn.
Farbwelt. Statt Regel fuer Regel zu ueberschreiben, ist die Palette
ausgetauscht: ein paar Variablen am Wurzelelement, an die Bootstrap und
AdminLTE ohnehin gehen. Anthrazit als Grund, eine Spur hellere Flaeche
fuer Karten, Haarlinien statt Rahmen und Schatten, Bernstein als einzige
Akzentfarbe - auf dieser Seite die Farbe der eigenen Anlage. Gruen, Rot
und Gelb bleiben den Zustaenden vorbehalten.
Erklaerungen, die bisher nur im title standen, sind antippbar: am Finger
gibt es kein Ueberfahren, und ein title erscheint dort nie.
Die beiden neuen Abfragen sind gegen solarLog gelaufen, die Monatswerte
decken sich mit einer unabhaengigen Zerlegung. grundpreisImJahr() ruft
jetzt grundpreisImZeitraum() auf - dieselbe Rechnung, nur auch fuer einen
Teil des Jahres.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der SolarManager legt gut 130 Topics auf den Broker, aber er meldet sich
nicht per Home-Assistant-Discovery. Das MQTT-Modul findet ihn deshalb
nicht, und eine Automatik konnte weder auf den Netzbezug noch auf den
Ladestand der Batterie oder die Temperatur im Puffer reagieren.
Vier feste Geraete mit neun Messwerten, ausgewaehlt nach dem, was das
Realtime-SVG zeigt - von der PV nur die Summe. Alles anzulegen haette die
Auswahl im Editor unbrauchbar gemacht: jeder Wechselrichter einzeln, jeder
Phasenstrom, jede Vorlauftemperatur.
Netzanschluss Bezug, Einspeisung
Stromzaehler Obergeschoss Leistung
Solaranlage PV-Leistung, Batterie-Ladestand
Pufferspeicher drei Temperaturen, Heizstab-Leistung
Die beiden Modbus-Zaehler am Gen24 (meter0 am Hausanschluss, meter1 fuer
das Obergeschoss) gibt es nur ueber diesen Weg - sie sprechen sonst mit
niemandem. Die beiden Shelly EM3 bleiben dagegen aussen vor: die stehen
ueber die Home-Assistant-Discovery laengst als Power_EG_EM_0 und
Power_UG_EM_0 in der Tabelle. solarManager/eg waere ohnehin nicht
dasselbe, dort ist die Wallbox im Carport eingerechnet.
Beim Netzanschluss stehen Bezug und Einspeisung statt P_Grid: eine Zahl
mit Vorzeichen liest sich in einer Bedingung falsch herum. Beim
Obergeschoss geht das nicht, der Zaehler meldet Verbrauch negativ - das
steht als Warnung im Modul.
Alles nur zum Lesen. Geschaltet wird am SolarManager nichts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zwei Sachen, beide an der Anlage aufgefallen.
Abgebrochen wurde auf "core:MovingState ist false". Das ist nicht
dasselbe wie "steht": die Box meldet das Ende der Fahrt, bevor Hoehe und
Neigung darauf nachgezogen haben, und der festgehaltene Wert war dann der
von kurz davor. Statt einer festen Wartezeit zaehlt jetzt Stabilitaet -
fertig ist es, wenn zwei Abfragen hintereinander dasselbe sagen. Damit
faellt auch die Bestaetigungsrunde weg, sie war genau dieser Gedanke in
schlechter.
Der Umweg der Kugelschreiber-Mechanik hing am Neigungswert (ueber 30 %).
Er gehoert an die Hoehe: eine Hoehenfahrt rastet die Lamellen um, danach
muss die Neigung ueber 0 % wieder angefahren werden - bei jedem Winkel,
nicht erst bei grossen. Wird dagegen nur die Neigung verstellt, steht die
Mechanik schon richtig und es geht direkt. NEIGUNG_DIREKT_MAX faellt
damit weg.
Der Hoehenregler im Raum-Modal schickt deshalb jetzt das kombinierte
Kommando mit der Stellung des Neigungsreglers daneben - ohne
Neigungsziel gaebe es nichts, was der Umweg anfahren koennte.
Geprueft an der Wozi-Schiebetuer: Hoehe von 48 auf 60 bei Neigung 76, und
die 76 standen danach wieder da. Vorher htte die Mechanik sie auf einen
beliebigen Wert umgerastet. Dazu elf Faelle im Browser und sieben gegen
transports.py, darunter "Position+Neigung 10" (Umweg) gegen "nur Neigung
80" (direkt).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Wer das Raum-Modal gleich nach einem Fahrbefehl zumachte, nahm den
einzigen Zuschauer mit: die Verfolgung im Browser endet mit dem Modal,
und niemand hielt fest, wo die Jalousie stehen blieb. In actor_states
stand bis zum naechsten Poll des Runners der alte Wert - genau die fuenf
Minuten, die eigentlich weg sein sollten.
ajax/room.php schickt die Antwort auf ein Tahoma-Kommando jetzt ab,
schliesst die Verbindung und wartet danach selbst auf das Ende der Fahrt
(fastcgi_finish_request, dieselbe Bauart wie in ajax/tahoma.php). Ob der
Browser noch da ist, spielt keine Rolle mehr; ignore_user_abort deckt
auch den Fall ab, dass er mitten im Aufruf verschwindet.
Die Verfolgung im Modal bleibt, sie ist jetzt aber nur noch fuer die
Anzeige zustaendig, solange jemand hinsieht. Das Aufschreiben haengt
nicht mehr daran.
Geprueft an der Wozi-Schiebetuer: Kommando auf Position 70, 0,7 Sekunden
spaeter die Seite neu geladen. 48 Sekunden danach zeigte das frisch
geoeffnete Modal 70 - und eine Neigung von 59 statt 62, die sich beim
Fahren von selbst verstellt hatte und die nur die Box kannte.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Am echten Geraet ausprobiert - drei Sachen stimmten nicht.
Die PHP-Warnung. Nicht jeder Tahoma-Zustand ist eine Zahl oder ein Wort,
manche sind Listen. strval() darauf ist eine Warnung, und die stand mitten
in der JSON-Antwort. response.json() scheiterte, raumRequest() lieferte
{error}, die Verfolgung brach still ab - genau das Bild, das der Bericht
"kommt noch nicht" beschreibt. Nicht-Skalare werden jetzt uebergangen, und
ein Fehler wird gemeldet statt verschluckt.
Das Mitziehen waehrend der Fahrt. Gemessen: die Hoehe steht die ganzen
zwanzig Sekunden auf dem alten Wert und springt erst am Ende um. Wer das
anzeigte, holte den Regler vom eingestellten Ziel auf den alten Stand
zurueck, um ihn danach wieder vorzuschieben. Angezeigt wird deshalb erst,
was am Ende dasteht.
Das vorzeitige Aufhoeren. Zwischen den beiden Befehlen der
Kugelschreiber-Mechanik steht die Jalousie still und meldet die
Zwischenstellung. Die Verfolgung hielt das fuer das Ende und schrieb
"Neigung 0" fest, wo 62 gemeint war. Sie laeuft jetzt mindestens, bis der
Auftrag zurueck ist, und danach noch vierzehn Sekunden - so lange dauert
eine Neigungsfahrt von Anschlag zu Anschlag.
Gegengeprueft an der Wozi-Schiebetuer: Position 49 -> 20 -> 100 -> 49,
Neigung 62 -> 80 -> 62. Die Neigung wanderte beim Herunterfahren von
selbst auf 100 und stand sofort richtig im Modal. Waehrend des zehn
Sekunden langen Kugelschreiber-Auftrags liefen drei Verfolgungsanfragen
durch - die Sitzungssperre ist also wirklich weg.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
actor_states.current_value schrieb bisher nur der AutoAction-Runner fort,
und der fragt die Tahoma-Box alle fuenf Minuten ab (poll_tahoma). Nach
einem Fahrbefehl stand im Raum-Modal deshalb bis zu fuenf Minuten lang
der Stand von vor der Fahrt.
Das Modal verfolgt die Jalousie jetzt selbst: alle zwei Sekunden fragt es
ueber ajax/room.php?action=jalousie genau dieses eine Geraet, zieht die
beiden Regler und das Lamellenbild nach und hoert auf, sobald die Box
keinen Fahrbefehl mehr meldet. Der gelesene Stand landet dabei gleich in
actor_states, damit auch das naechste Oeffnen und der Automatik-Editor
ihn haben. Wer gerade selbst am Schieber zieht, behaelt ihn.
Drei Dinge mussten dafuer aus dem Weg:
- Die Sitzung. helper.php startet sie und schliesst sie nie, PHP sperrt
ihre Datei bis zum Ende der Anfrage. Ein "Zu" wartet ueber eine Minute
auf das Ende der Fahrt - solange stand jede weitere Anfrage desselben
Browsers still. ajax/room.php gibt sie jetzt frei, sobald checkLogin()
durch ist; danach wird $_SESSION nur noch gelesen.
- Drei Abfragen je Warterunde. warteAufJalousie() holte MovingState,
Neigung und Position einzeln, obwohl eine Abfrage die ganze Liste
liefert. Jetzt eine.
- Kein Ort, an dem der frische Stand haengenbleibt. Dafuer
tahomaZustaende(), tahomaZustaendeSchreiben() und tahomaAktorUrl().
Wahrheitswerte werden dabei als "True"/"False" geschrieben - so macht es
der Runner mit str(), und zwei Schreibweisen fuer denselben Zustand
waeren schlimmer als eine schraege.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Anzeigen im Realtime-SVG und im Bewaesserungs-Modal lasen ihre
Vorschau aus Gartenwasser/AutoWatering/<zone>/RainStatus, das
auto_watering.py stuendlich veroeffentlicht hat. Solange das so blieb,
konnte das Skript nicht abgeschaltet werden, obwohl die Entscheidung
laengst in den Automatiken des Runners steht - und dessen Schwellen
haetten dann neben denen im Skript gestanden, ohne dass ein Unterschied
auffaellt.
Statt des Plans zeigen die Anzeigen jetzt, ob die Zone heute schon
gelaufen ist. Die Regenautomatik loest zum Sonnenaufgang aus; wer
spaeter auf das Dashboard schaut, will ohnehin wissen, was passiert ist,
nicht was vorgesehen war. Die Angabe kommt aus dem retained
WateringToday der Ventilsteuerung, das die Karte schon fuer "Heute"
auswertet - eine Bewaesserung von Hand zaehlt damit genauso, was hier
richtig ist.
Im SVG steht dafuer ein Haekchen statt der Stoppuhr, das Schild im
Modal sagt "heute bewaessert" statt "heute geplant", und die
Planungszeilen in der Automatik-Karte entfallen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nicht nachgebaut, sondern powerToString() aus common.js benutzt. Sie macht
genau das schon, und die Solarseite formatiert dieselben Zahlen damit - eine
eigene Regel hier haette bedeutet, dass dieselbe Wallbox an zwei Stellen
verschieden gerundet dasteht. common.js wird im Fuss vor den seitenweisen
Skripten geladen, steht homeMQTT.js also zur Verfuegung.
Ersetzt wird nur das Trennzeichen: auf der Kachel steht ein schmales
Leerzeichen zwischen Zahl und Einheit, im Rest der Anwendung ein
gewoehnliches.
Betroffen sind Garage, Carport OG und Carport EG. Der Regen im Garten bleibt
bei Einheit und Nachkommastelle - Millimeter skalieren nicht.
Nebenbei: mein Einschub von wechselrichterWert() hatte den Kommentarblock
von kachelWert() von seiner Funktion getrennt, er stand seitdem ueber der
falschen. Zurueckgesetzt und um die beiden neuen Schluessel ergaenzt.
Geprueft mit dem echten Code im Browser: 0 -> "0 W", 999 -> "999 W",
1234 -> "1.23 kW", 12340 -> "12.3 kW"; die Summe der vier Carport-Hoymiles
ergibt 1.23 kW und laesst einen fuenften Wechselrichter richtigerweise
draussen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Rendering des Grundstuecks fuellt seinen Rahmen aus, die drei
Geschossbilder haben dagegen breiten schwarzen Rand - deshalb lagen die
Etagenschalter nur beim Aussengelaende auf dem Bild. Der Rand gehoert ins
Bild und nicht in home.php: dort einzurechnen haette auch OG, EG und UG
verschoben, und deren Kacheln sind auf die heutige Lage eingemessen. AG.png
bekommt links 114 durchsichtige Punkte, die sieben Kacheln sind mit
derselben Abbildung umgerechnet.
Die Schalter selbst waren ein duenner Ring in einem Amber (#aa7713), das in
css/solar.css nirgends vorkommt - und alle vier sahen immer gleich aus, die
aktive Etage war an ihnen nicht zu erkennen. Jetzt tragen sie dieselbe
Scheibe wie die Kacheln im Grundriss, die aktive bekommt die Akzentfarbe der
Schieberegler (#00788F), und switchFloor() zieht den Zustand mit. Dort
classList und nicht die Helfer addClass/removeClass weiter oben: deren
"el.className +=" wirkt auf SVG-Elementen nicht, className ist dort
schreibgeschuetzt.
Ausserdem sind sie kleiner. Mit halber Groesse beherrschten sie die linke
Seite, und das Bild musste umso weiter einruecken, um sie freizuhalten - bei
0,38 statt 0,50 bleibt mehr Plan uebrig. Die Groesse steht als eine Zahl in
home.php, Abstand und Bildrand folgen daraus.
Die Beschriftung sitzt jetzt ueber text-anchor und dominant-baseline im
Kreismittelpunkt. Vorher stand je Etage ein von Hand gesuchter Versatz im
Markup (62, 63, 64), und jede neue Etage haette einen neuen gebraucht.
Weggefallen: die Definition #floorBtn, die nur einmal benutzt wurde, und die
Animationen showOG/showEG/showUG, die ein bereits sichtbares Element von 0
auf 1 blendeten.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ihre beiden Kacheln lagen auf der Westfassade des Hauses so dicht
beieinander, dass sie mehr gestiftet als erklaert haben. Ohne x/y bleiben
Veranda EG und OG Raeume wie zuvor - Geraete sind ihnen zugeordnet und
Automatiken laufen darauf, das haengt allein daran, dass sie in dieser
Tabelle stehen.
Die Wechselrichter der Veranda OG stehen als Kommentar daneben. Sie waren
muehsam genug zu finden, und ohne Kachel gaebe es keinen Ort mehr, an dem
die Namen ueberlebt haetten.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Carport EG und Veranda OG zeigen jetzt ihre PV-Leistung. Der SolarManager
legt die Hoymiles unter solarManager/inverters0, /inverters1 und so fort ab
- die Nummer ist eine Position in einer Liste und sagt nichts darueber,
welches Dach gemeint ist. Ein fest eingetragenes "inverters3" waere
stillschweigend falsch, sobald sich die Reihenfolge aendert.
Deshalb sucht wechselrichterWert() ueber invertersN/name und summiert die
genannten auf. Das ist eine dritte Art, an einen Wert zu kommen - neben
Topic und JSON-Pfad -, aber sie bleibt auf einen Schluessel und eine
Funktion beschraenkt, und der gewoehnliche Weg ist unberuehrt. Findet sie
keinen der Namen, schreibt sie die vorhandenen in die Konsole; sonst stuende
nur ein Strich auf der Kachel und niemand wuesste, woran es liegt.
tileTopics() unterschied bisher nicht und machte aus dem fehlenden Topic ein
"/#" - eine Anmeldung auf einen leeren Zweig.
Dazu Symbole vor den Zahlen. "0 W" allein sagt nicht, ob geladen, erzeugt
oder verbraucht wird, und die Einheit beantwortet das nicht. Die Icons
kommen als Schrift und nicht als Pfad: css/bootstrap-icons.min.css ist
ohnehin eingebunden, und SVG-Text darf dieselbe Schriftfamilie benutzen wie
HTML. Die Codepunkte stehen in kachelIcon() mit dem Namen daneben,
abgeschrieben aus genau dieser CSS.
Wegen font-display:block bleiben die Symbole bis zum Laden der Schriftdatei
unsichtbar - die Werte stehen so lange ohnehin auf einem Strich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Raum-Modal fand die Geraete von "Carport EG" und den fuenf anderen
AG-Raeumen mit Leerzeichen nicht - es meldete stattdessen, dem Raum sei
nichts zugeordnet. ajax/room.php bereinigte den Schluessel mit
[^A-Za-z0-9_] und warf dabei das Leerzeichen weg: aus "AG_Carport EG" wurde
"AG_CarportEG", der Vergleich gegen die gespeicherte Zuordnung
"AG/Carport EG" ging ins Leere. Aufgefallen ist es erst jetzt, weil sechs
von neun AG-Raeumen ein Leerzeichen im Namen haben und keiner der achtzehn
auf den anderen Etagen. Durchgespielt: vorher 6 von 27 Raeumen kaputt,
danach 0.
Messwerte auf den AG-Kacheln, wo es etwas zu messen gibt:
Garage solarManager/evPower - die Wattpilot der EG-Partei
Carport OG solarManager/evPowerOG - der go-e Charger
Garten Wetter/Regen [tage1] - Regen des laufenden Tages
Veranda, Terrasse und Pergola behalten ihren Namen: dort haengen Licht und
Rollladen, und die zeigt das Raum-Modal. Carport EG bleibt vorerst ohne -
die Hoymiles liegen auf solarManager/invertersN, positionsnummeriert, und
welcher Strang der Carport ist, steht nirgends im Code. Geraten wird das
nicht.
tileTopics() zieht Wetter/# von selbst nach, das Abonnement folgt aus dem
Topic.
Ausserdem der weisse Saum am freigestellten Rendering. Die feste Schwelle
liess den ein bis zwei Punkte breiten Uebergang stehen - gemessen 247, 250,
241, 204, 145, und die 241 blieb knapp haengen und leuchtete vor dem
schwarzen Grund. Die Flutfuellung frisst jetzt entlang der Kante in immer
dunklere Punkte nach und legt zuletzt einen Punkt mit halber Deckung an,
damit die Kante nicht treppig wird.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bisher entschied jede Arbeitsstation fuer sich, welche Zeilenenden ein
Commit bekommt: Git fuer Windows setzt core.autocrlf=input in seiner
System-Konfiguration, die NAS setzt nichts. Weil der Bestand ausserdem in
sich gemischt war - 34 PHP-Dateien mit LF, 30 mit CRLF -, gab es gar kein
richtiges Zeilenende, an das ein Werkzeug sich haette halten koennen. Jede
Ergaenzung mit LF in einer CRLF-Datei ergab eine gemischte Datei; helper.php
und js/solar/homeMQTT.js waren bereits so entstanden.
.gitattributes macht die Zeilenenden zur Eigenschaft des Repositorys. LF,
weil dieses Verzeichnis der Web-Ordner der NAS ist und von Linux
ausgeliefert wird - und weil Git fuer Windows mit "input" ohnehin schon
dorthin zeigt.
restricted/WebAuthn bleibt ausgenommen und damit byteweise so, wie die
Bibliothek geliefert wurde; darunter liegen 292 Zertifikate.
Von den 47 geaenderten Dateien wurde nachgerechnet keine einzige im Inhalt
angefasst - der Vergleich HEAD-ohne-CR gegen Index ist ueberall gleich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das Rendering des Grundstuecks tritt an die Stelle des Vektorplans. Es kommt
aus derselben Art Quelle wie die drei Geschossbilder und passt damit besser
zu ihnen, als der Plan es je koennte; der hat seinen Zweck erfuellt, indem
er die Geometrie sortiert hat.
Freigestellt wird mit einer Flutfuellung vom Rand her, nicht mit einem
Farbtausch: Weiss kommt auch im Bild selbst vor - Hauswand,
Grundstuecksmauer -, und nur was vom Rand aus zusammenhaengend erreichbar
ist, ist wirklich Hintergrund. Aufgefuellt statt beschnitten auf 4:3, weil
1024x792 etwas hoeher ist und Wegschneiden das Bild selbst treffen wuerde.
Etagenbilder und Schalter in home.php kommen jetzt aus einer Schleife.
Ausgeschrieben waren die Blenden bei drei Etagen neun Zeilen und bei vier
schon sechzehn, und jede neue Etage haette alle anderen mit angefasst. Die
Schalter ruecken ab der vierten Etage von 100 auf 78 Einheiten zusammen,
sonst faellt der unterste aus der 300 hohen viewBox.
Die Kachelpositionen sind ein Startwert, kein Endstand: Richtung aus dem
Modell gerechnet - Westen liegt links unten, Sueden rechts unten -, Lage
per Auge im Raster. Der erste Wurf hatte die Terrasse an der falschen
Fassade; im Modell liegt sie an der Suedwestecke.
Lange Raumnamen brechen jetzt um. "Terrasse OG" stand einzeilig ueber die
24 Einheiten breite Kachel hinaus - sichtbar wurde das erst hier, weil im
Aussengelaende jeder Raumname aus zwei Woertern besteht.
Nebenbei: xcursor="pointer" am OG-Schalter war ein Tippfehler, der Kreis
hatte als einziger keinen Zeiger. Das tote border-Attribut am OG-Bild ist
mit weggefallen, SVG kennt es nicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Aus OG.png gemessen, nicht geschaetzt: die hellste Stufe ist genau neutral
und liegt bei 200 - heller wird dort nichts -, und je dunkler eine Flaeche
wird, desto blauer wird sie. Beides steckt jetzt in aussenSchatten(), das
bisher farbtreu gegen Schwarz gerechnet hat.
Damit allein fehlte dem Plan aber immer noch das obere Drittel der
Helligkeitsskala, das die Renderings haben. Grund war, dass jede Aussenwand
denselben Faktor bekam, egal wohin sie zeigte - der Plan hatte gar kein
gerichtetes Licht. aussenBeleuchtung() liefert es jetzt aus einer Sonne im
Westsuedwesten und ersetzt nebenbei die grobe Zweistufung am Dach.
Waagerechte Flaechen bleiben knapp unter der besonnten Wand. Mit vollem
Licht waren Boden und Terrassen das Hellste im Bild; im Vorbild sind es die
Waende.
Die Deckflaeche lief bisher an aussenSchatten() vorbei, sonst haette der
Deckel die flachen Flaechen nie erreicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der OG-Carport sah aus wie ein Tisch auf vier Beinen: seine Westwand fehlte
scheinbar, man schaute an ihrer Stelle in den Innenraum. Gezeichnet wurde sie
die ganze Zeit - die Kennungen der Flaechen zeigen sie als "Wand W aussen".
Der Fehler lag in der Reihenfolge. Die Flaechen einer Wand entstehen in
Kantenreihenfolge, und die Nordwand ist Kante 3, die Westwand Kante 2. Die
Innenseite der hinteren Nordwand wurde damit nach der Aussenseite der
vorderen Westwand gemalt und uebermalte sie. Bei einem geschlossenen Koerper
faellt das nie auf, weil dort keine Innenseiten sichtbar sind; erst mit
Oeffnungen und Wandstaerke kam es heraus.
Jetzt werden die Wandflaechen eines Koerpers gesammelt, nach Tiefe sortiert
und dann gemalt. Das Tiefenmass ist die Projektion des Flaechenmittelpunkts
auf die Blickrichtung - bei dieser Projektion faellt genau eine Raumrichtung
auf einen Bildpunkt zusammen, ihre Komponenten sind sin(Winkel), cos(Winkel)
und Stauchung/Ueberhoehung. Die projizierte Y-Koordinate taugt dafuer nicht:
in ihr steckt auch die Hoehe, ein hoher Punkt saehe damit weiter hinten aus.
Boden und Dach bleiben ausserhalb der Sortierung - der eine liegt immer
unten, das andere immer oben.
Dazu tragen die Flaechen jetzt eine Kennung ("Carport OG: Wand W aussen").
aussenSvg() liest sie nicht, sie kostet also nichts und macht die Fehlersuche
moeglich, ohne den Zeichner umzubauen - ohne sie waere dieser Fehler
Farbraten geblieben.
Die Schnittkanten sind nebenbei von 0,84 auf 0,66 abgedunkelt. Heller als die
Wand liessen sie die Ecken wie Pfosten aussehen, was den Tischeindruck noch
verstaerkt hat.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Gartenumriss laeuft als Schluesselloch um Haus und Veranda herum. In
seiner westlichen Ausbuchtung sprang er von [22.7, 24.2] gleich weiter nach
[19.9, 25.6] und liess damit den Keil zwischen der Ostkante der Garage, der
Westseite der Veranda und der Nordkante des Hofs aus. Dort lag ueberhaupt
keine Flaeche, und der schwarze Hintergrund schien durch.
Vier Punkte fuehren den Rand jetzt um diesen Keil herum: an der Veranda
hinauf, ueber die Nordkante der Garage und an deren Ostkante wieder herunter
zum Hof. Der Umriss bleibt dabei ueberschneidungsfrei - nachgerechnet ueber
alle 17 Kantenpaare, denn ein Schluesselloch, das sich selbst kreuzt, wuerde
die Fuellregel an unerwarteter Stelle aussparen und den Fehler nur
verschieben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Auf dem OG-Carport liegt keine Anlage - die Module gehoeren aufs Hausdach.
Dafuer kann der Zeichner jetzt auch Module auf einer Dachschraege und nicht
nur auf einer waagrechten Deckflaeche: "pv" nimmt eine Himmelsrichtung. Auf
dem Haus ist es die Suedschraege, und weil die Wiederkehr danach gezeichnet
wird, deckt sie die Mitte ab - genau wie auf dem Luftbild, wo die Module
links und rechts von ihr liegen. Eingezogen wird dort im Bild und nicht in
Metern: die Schraege ist schon projiziert, und auf ihrer Ebene bleibt ein
Einzug auch nach der Projektion ein Einzug.
Die Carportdaecher haben eine Dicke, mit 30 cm etwas mehr als die 20 cm der
Waende. Das brauchte zwingend einen Ueberstand: buendig aufliegend sind
Stirnflaeche und Wandflaeche deckungsgleich, die Dicke waere gerechnet und
trotzdem unsichtbar. Genau daher kam auch der Eindruck, dem OG-Carport fehle
die Westwand - sie war die ganze Zeit da und wurde auch gezeichnet, sie hatte
nur keine Kante, an der sie aufgehoert haette. Mit 25 cm Ueberstand steht sie
jetzt sichtbar unter dem Dach.
Die Pergola ist ein Sonnensegel: eine Bahn Tuch auf zwei Metern, heller und
ohne Bauwerk darunter. Dass sie zu schweben scheint, ist richtig so - die
Masten waeren bei diesem Massstab duenner als ein Strich.
Der Hof laeuft vor dem EG-Carport gerade bis an den Garten weiter; der
Carport steht damit auf ihm. Seine suedliche Kante sind dieselben beiden
Punkte, die auch im Gartenumriss stehen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vier Korrekturen am Aussenplan:
Die Waende sind Kaesten und keine Flaechen mehr. An einer Oeffnung stand
sonst ein Blatt Papier im Raum - Innenseite, Oberkante und die beiden
Schnittkanten fehlten, und genau das sah seltsam aus. Die Dicke wird nur
gerechnet, wo ein Koerper ueberhaupt offen ist; bei einer geschlossenen Wand
sieht man sie nie.
Der First der Garage lief vorher schon richtig, Nord-Sued. Die Drehung um 90
Grad war ein Missverstaendnis und ist zurueckgenommen - jetzt steht die Achse
ausgeschrieben da, damit bei diesem fast quadratischen Grundriss nicht wieder
die zweite Nachkommastelle entscheidet.
Die halb offenen Nord- und Suedwaende des EG-Carports sind wieder zu. Die
Faehigkeit bleibt im Zeichner, sie wird hier nur nicht mehr gebraucht.
Beide Pultdaecher sind auf ein Drittel abgeflacht: 0,27 m statt 0,8 beim
OG-Carport, 0,23 statt 0,7 beim EG-Carport - rund vier Prozent Neigung. Beim
OG-Carport ist die Wandhoehe dafuer auf 2,23 m gesetzt, damit die hohe Seite
bei 2,50 m herauskommt und dort an die Traufe des Garagendachs anschliesst.
Nachgerechnet: beide bei 2,50 m.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Zeichner konnte bisher nur Klotz mit Satteldach. Jetzt:
* Pultdaecher mit Fallrichtung. Die Richtung kommt aus der Aussennormalen
der genannten Kante und nicht aus einem festen Nord-Sued-Vektor - das
Grundstueck steht zehn Grad schief, und eine Traufe soll parallel zum
Gebaeude laufen und nicht fast parallel.
* Offene und halb offene Seiten. Genannt werden Himmelsrichtungen, die
Kanten sagen selbst, welche gemeint ist. Bei einer halb offenen Seite
bleibt die Haelfte stehen, die von der Oeffnung weiter weg liegt.
* Ein Tor, mittig in seiner Wand.
* Module, die plan auf der Dachflaeche liegen.
* Rueckflaechen fallen weg. Bei positivem Umlauf der Grundflaeche haben die
zugewandten Seiten eine positive projizierte Flaeche - damit verschwinden
die Kanten, die man sonst durch einen Koerper hindurch gesehen haette,
ohne sie einzeln benennen zu muessen.
* Der First laeuft nicht mehr an festen Eckennummern entlang, sondern
zwischen den Mitten zweier benannter Kanten. "achse" ueberschreibt das -
bei der fast quadratischen Garage entschiede sonst die zweite
Nachkommastelle, welche Seite die laengere ist.
Damit steht am Grundstueck: das Haus bekommt seine Wiederkehr auf der
Suedseite (als eigener Koerper auf derselben Grundflaeche - sie liegt
suedlich und damit weiter vorn, deckt das Hauptdach also von selbst richtig
ab; Breite und Tiefe sind vom Luftbild geschaetzt). Die Garage hat ein
begruentes Dach, ihr First liegt quer und ihr Tor nach Sueden. Der OG-Carport
ist nach Sueden offen und faellt zur Strasse hin ab, der EG-Carport ist nach
Westen offen, seine Nord- und Suedwand stehen nur hinten, und er faellt nach
Sueden ab. Auf beiden liegen die Module.
Die Farben folgen den Innenansichten: Weiss und Grau, dazu ein blaeulicher
Grauton fuer die Boeden von Veranda und Terrasse, OG etwas heller als EG.
Rot war ohnehin falsch, seit das Garagendach begruent ist.
Drei Fehler kamen beim Zeichnen heraus:
* Die Dachflaechen nahmen die Firstenden in fester Reihenfolge. Eine der
beiden wurde damit zur Schleife und zeichnete einen Zacken quer ueber das
Haus. Jetzt bekommt jedes Traufende den Firstpunkt, der bei ihm liegt.
* Die Wiederkehr zog ihre Ost- und Westwand mitten durch das Haus. Sie hat
jetzt gar keine Waende: sie sitzt als reines Dach auf sechs Metern.
* Wo eine Seite offen ist, schaute man durch den Koerper auf den schwarzen
Hintergrund - ein Loch, kein Unterstand. Solche Koerper bekommen jetzt
einen Boden.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die elf Flaechen sind am Luftbild abgeklickt und danach gerichtet worden:
von Hand trifft man keine rechten Winkel, und Ecken, die derselbe Punkt sein
sollten, lagen ein paar Dezimeter auseinander.
Gerichtet wurde im Bezugssystem des Grundstuecks. Dessen Ausrichtung steckt
in den Hauskanten - laengengewichtet gemittelt ueber den vierfachen Winkel,
weil vier Kanten in vier Richtungen desselben Rasters zeigen und erst der
vierfache Winkel sie zusammenfallen laesst. Ergebnis: -9,77 Grad.
In diesem System sind die Gebaeude achsparallel. Sie durch ihr umschliessendes
Rechteck zu ersetzen macht sie damit genau rechtwinklig, und das anschliessende
Zusammenschnappen der Koordinaten - u und v getrennt - laesst sie Rechtecke
bleiben. Andersherum waere das nicht gegangen: schnappt man vorher, stehen die
Winkel wieder schief.
Hof, Garten und Pergola bleiben, wie sie abgeklickt wurden. Die ersten beiden
sind gewachsene Formen, und am dritten haengt ein Sonnensegel - die sind
selten rechteckig. Ihre Ecken schnappen trotzdem mit, sonst klafften Luecken
zu den Gebaeuden.
Ergebnis, alle acht Gebaeude auf 90,0 Grad:
Haus 15,3 x 14,2 m Veranda EG/OG 2,4 x 11,5 m
Garage 6,5 x 6,4 m Terrasse EG/OG 2,6 x 5,0 m
Carport OG 4,0 x 6,4 m Carport EG 9,0 x 4,3 m
Die groesste Verschiebung einer Ecke betrug 0,92 m, die meisten lagen unter
einem halben Meter.
Dazu zwei Fehler am Dach, die erst die Zeichnung zeigte: die Giebel standen
offen, sodass an den Schmalseiten die Wand durchschien, und der First lag
fest an den Ecken 0/3 und 1/2 - bei einem quer stehenden Gebaeude waere er
damit ueber die kurze Achse gelaufen. Jetzt schliessen zwei Giebeldreiecke
das Dach, und der First richtet sich nach der laengeren Seite.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Veranda und Terrasse gibt es zweimal, je Wohnpartei eine. In der Draufsicht
laege das obere Paar genau auf dem unteren: nicht auseinanderzuhalten und
schon gar nicht getrennt anzuklicken. Deshalb wird AG nicht flach von oben
gezeichnet, sondern schraeg von Suedwesten - von dort sieht man den Hof, auf
den die Veranden zeigen, und die Ostseite des Hauses traegt nichts, was
vorkommen muesste.
restricted/aussenplan.php haelt die Projektion und die Geometrie. Gezeichnet
wird in Militaerprojektion, nicht in echter Perspektive:
X = x·cos φ − y·sin φ
Y = (x·sin φ + y·cos φ)·STAUCHUNG − z·UEBERHOEHUNG
Der Grundriss bleibt dabei masshaltig - Geraden bleiben gerade, Rechtecke
Rechtecke. Genau deshalb diese und keine perspektivische: die Flaechen lassen
sich am Luftbild von oben abklicken, und dieselben Zahlen ergeben ohne Umweg
die Schraegsicht. Eine echte Perspektive muesste man neu vermessen.
Das Vorzeichen des Winkels bestimmt die Himmelsrichtung. Bei +35° zeigt der
Y-Gradient nach Osten und Sueden, die naechste Ecke waere die suedoestliche;
fuer Suedwesten muss er negativ sein. Was die Paare trennt, ist ohnehin nicht
die Drehung, sondern Stauchung und Ueberhoehung - bei 1,4 stehen Terrasse EG
und Terrasse OG rund 34 Einheiten auseinander, eine Kachel ist 19 hoch.
Hoehen: Traufe 6 m, First 9 m, Carport 2,5 m. Die OG-Ebene ist mit 3 m
angenommen - die halbe Traufhoehe bei zwei Geschossen.
tools/lageplan.php nimmt dafuer jetzt je Flaeche eine Hoehe entgegen und
zeigt die Schraegsicht live neben dem Luftbild: nur dort sieht man beim
Abklicken, ob die Paare wirklich auseinandergehen. Die Vorschau rechnet
dieselben Formeln im Browser nach; massgeblich bleibt der PHP-Code, von dem
spaeter die gezeichnete Etage und die Kachelpositionen kommen.
Dazu die Raeume: aus "Veranda" und "Terrasse" werden je zwei, eine pro
Partei. Welche der vier Geraete zu welcher gehoeren, sagt kein Name - die
beiden Wechselrichter tragen immerhin "OG" ("Veranda OG2-4", "Veranda
UG/OG1"), Licht und Rollladen der Terrasse gar nichts. Sie stehen deshalb
vorlaeufig auf Veranda OG und Terrasse EG.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Es gibt nicht einen Carport, sondern zwei - einen fuer die EG-Partei und
einen fuer die OG-Partei. Damit heissen sie "Carport EG" und "Carport OG"
und benutzen dieselben Kuerzel wie die Etagen; das Haus hat dieses Vokabular
ohnehin ueberall.
Der go-e Charger steht am OG-Carport: restricted/config.php haelt fest, dass
"og" der go-e ist und "eg" die Wattpilot - und die steht in der Garage, nicht
am Carport.
Welcher der fuenf Wechselrichter auf welchem Carport sitzt, sagt weder sein
Name ("Carport 1-6", "Carport 7-12" ...) noch die OpenDTU, aus der die Namen
stammen. Sie stehen deshalb vorlaeufig zusammen auf dem EG-Carport - ein
benannter Raum ist besser als ein Schluessel, den es nicht mehr gibt. Die
Aufteilung ist ein Klick im Zuordnungsdialog, sobald sie feststeht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Was draussen haengt, stand als Pseudo-Raum "aussen" in automations.php:
"Geraete, die zu keinem Raum der Wohnung gehoeren - Carport, Garage,
Regensensor". Das waren inzwischen sechzehn Geraete in einem einzigen Topf,
der groesste ueberhaupt - in der Geraeteauswahl des Editors standen die fuenf
Carport-Wechselrichter, das Sonnensegel und das Garagentor unsortiert
nebeneinander.
Jetzt ist das Aussengelaende eine Etage wie OG, EG und UG, mit eigenen
Raeumen: Carport, Veranda, Pergola, Terrasse, Garage und Garten. Die Namen
stammen von den Geraeten selbst - die Hoymiles heissen seit jeher "Carport
1-6" und "Veranda OG2-4". Die achtzehn Geraete sind verteilt (die beiden
Ventilsteuerungen hatten noch gar keinen Raum und stehen jetzt im Garten,
zusammen mit dem Regensensor, der ihre Automatiken ausloest); "Ohne Raum"
faellt damit von acht auf sechs, und die sind es zu Recht.
AG ist eine Etage ohne Grundriss. Ihre Raeume haben kein x/y, es gibt ja
kein Bild, auf das eine Kachel zeigen koennte - ein Raum ohne Position war
schon immer vorgesehen. Das Menue und das SVG richten sich deshalb nach der
neuen floorsWithPlan(), die Zuordnung und die Automatiken nach $floors.
Bekommt der erste AG-Raum eine Kachel, erscheint die Etage von selbst auch
im Menue; es gibt keine zweite Liste, die man nachziehen muesste.
Die Etagen standen bisher an sechs Stellen noch einmal im Code. Jetzt gibt
es genau eine Liste, $floors in rooms.php, und alles andere leitet sich ab:
* automations.php prueft gegen $floors statt gegen eine eigene Whitelist
* ajax/AutoAction.php baut seine Etagen-Auswahl daraus
* home.php baut Reiter und Inhaltsbereiche in einer Schleife statt
dreimal fast dasselbe HTML
* header.php baut die Menuepunkte daraus
* switchTab() in homeMQTT.js liest die Reiter aus der Seite, statt OG, EG
und UG sechsmal aufzuzaehlen
* refreshAutomations() ebenso - eine feste Liste haette die vierte Etage
still ausgelassen, die Tabelle waere ohne Fehlermeldung leer geblieben
Dazu die ausgeschriebenen Namen in $floorLabels: das Kuerzel steht in URLs,
SVG-Ids und im MQTT-Baum, "Aussengelaende" nur als Titel am Menuepunkt und
am Reiter.
In der Datenbank ist das Enum um 'AG' erweitert; header.php laedt rooms.php
jetzt selbst, weil es vor home.php eingebunden wird.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Git fuer Windows setzt core.autocrlf=input in seiner System-Konfiguration,
die Synology-Seite hat das nicht. Dieselbe Arbeitskopie liegt auf beiden
Systemen - unter /volume1/web/smart und als Z:\ -, und die Datei war deshalb
im Arbeitsverzeichnis CRLF, im Repository aber LF: Windows sah sie sauber,
die NAS dauerhaft geaendert. Ein "git pull" dort waere daran haengengeblieben.
Jetzt liegt sie so im Repository, wie sie im Arbeitsverzeichnis steht - und
wie die uebrigen Discovery-Module, die ebenfalls mit CRLF eingecheckt sind.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Upserts schrieben current_value = VALUES(current_value). Ein Modul, das
keinen Startwert kennt - das Gartenwasser-Modul zum Beispiel, dessen Werte
ausschliesslich per MQTT hereinkommen -, liefert dort NULL, und damit
ueberschrieb jeder Discovery-Lauf den laufenden Wert mit NULL.
Der Runner holte das nicht zurueck. Er merkt sich in `geschrieben`, was er
zuletzt in die Datenbank geschrieben hat, und `regelwerk_laden` uebernimmt
diesen Merker beim Neuladen per setdefault - der naechste hereinkommende
Wert war damit "unveraendert" und wurde nicht erneut geschrieben. Im Editor
stand danach "Regen heute (= )" statt "(= 0,0 mm)", und zwar bis sich der
Wert zufaellig einmal aenderte. Bei "Bewaessert heute" koennen das Tage
sein.
Jetzt COALESCE: ein NULL aus dem Modul heisst "kein Startwert" und laesst
stehen, was da ist. Module, die beim Suchen wirklich einen Wert ablesen -
Tahoma, Shelly, WLED -, schreiben ihn weiterhin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Firmware der Ventilsteuerungen liefert seit heute ein retained
Gartenwasser/<x>/Running mit "running", "running<Ventil>" und "mode", dazu
das schon vorbereitete "daysSinceWatering<Ventil>" in LastWatering.
Der Messwert "Laufende Automatik" las diese Angabe bisher aus Timers und
weicht deshalb. Timers ist nicht retained und wird nur im Sekundentakt
gesendet, solange etwas laeuft: der Runner sah im Ruhezustand gar nichts
und behielt nach einem Lauf den zuletzt gesehenen Wert - also genau das
Gegenteil von verlaesslich. Running ist retained und faellt ueber eine
Last-Will-Nachricht auch dann auf false, wenn die Steuerung mitten im
Giessen wegbricht.
Neu sind damit je Steuerung "Bewaesserung laeuft" und "Laufender Modus",
dazu je Zone ein eigener Laufmerker - aber nur, wo eine Steuerung mehr als
eine Zone bedient. Bei "hinten" waere er derselbe Wert wie der Merker der
Steuerung, und ein Messwert, der nie etwas anderes sagt, macht die Auswahl
nur laenger.
"Bewaesserung laeuft = NEIN" ist der Waechter fuer jede Regel, die hier
etwas anstossen will: die Zonen einer Steuerung haengen an derselben
Leitung, zwei gleichzeitig gibt es nicht.
Die beiden alten Zeilen "Laufende Automatik" muessen von Hand aus
actor_states verschwinden - das Discovery schreibt nur mit ON DUPLICATE KEY
UPDATE und loescht nie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Erster Teil der Ablosung von restricted/gartenbewaesserung/auto_watering.py.
Das Skript holt heute stuendlich den Regen, vergleicht ihn mit Schwellen
aus einer ZONES-Tabelle im Quelltext und schaltet selbst. Kuenftig
entscheidet der AutoAction-Runner, und die Schwellen stehen im Editor.
Dafuer legt ein neues Discovery-Modul drei Geraete an. Es sucht nichts,
sondern schreibt sie fest hin - wie das Logic-Modul auch:
* Die beiden ESP32-Ventilsteuerungen sprechen zwar MQTT, aber ohne
Home-Assistant-Discovery; das MQTT-Modul findet sie deshalb nicht.
* "Regen" ist gar kein Geraet, sondern das, was gatherRainData.py im
SolarManager von Open-Meteo holt und nach Wetter/Regen legt.
Je Steuerung entsteht ein Kommando "Automatik" mit dem Modus als
Parameter - ein Kommando ohne Parameter schickt im Runner eine leere
Nutzlast, der Klartext ("Hoch", "Trog", "Vorn") muss also der Parameter
sein. Dazu je Zone zwei Messwerte:
Bewaessert heute ersetzt die Zwoelf-Stunden-Sperre des Skripts;
"heute noch nicht" heisst hier "= 0". Die
Steuerung setzt den Wert um Mitternacht zurueck,
der Runner kann den mitgelieferten "wateringDay"
naemlich nicht pruefen.
Tage seit Bewaesserung ersetzt max_dry_days. Ein Zeitstempel nuetzte
nichts: der Runner vergleicht Datumsangaben nur
gegen einen festen Wert, "laenger als fuenf Tage
her" ist damit nicht formulierbar. Die Firmware
liefert deshalb gleich die Anzahl Tage.
Die Regensummen kommen als tage1 bis tage7 herein; welche davon als
Messwert auftauchen, entscheidet allein dieses Modul. Der Sammler
veroeffentlicht immer alle sieben, damit sich die beiden Repositorien
nicht ueber eine Fensterliste einigen muessen.
Die Logseite kennt rainOutput.log jetzt ebenfalls.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bisher stand ueber jedem Raum eine eigene Ueberschrift - bei neunzehn
Raeumen aus rooms.php also neunzehn Stueck, jede mit der Etage davor:
"OG - Bad", "EG - Bad", "UG - Bad". In einer Liste, die fuenfzehn Zeilen
hoch ist, sah man dadurch mehr Ueberschrift als Geraet.
Jetzt gruppiert nur die Etage, und der Raum steht klein und rechtsbuendig
an jeder Zeile. Sortiert wird innerhalb der Etage nach Raum (Reihenfolge
wie in rooms.php), sodass die Geraete eines Raums trotzdem beisammen
stehen; aus zwanzig Ueberschriften werden fuenf. Ein Raum, den es in
rooms.php nicht mehr gibt, bekommt eine eigene Ueberschrift, statt
stillschweigend unter den Unzugeordneten zu verschwinden.
Die Suche laeuft zusaetzlich ueber den Raum: "bad" findet damit auch den
Handtuchtrockner, der im Bad haengt, ohne es im Namen zu tragen. In der
Trefferliste steht keine Ueberschrift darueber, deshalb traegt dort jede
Zeile die volle Angabe "OG - Bad".
Dafuer nennt raumListe() Etage und Raum jetzt auch einzeln, und der
Geraetekatalog reicht beides durch - der Schluessel "Etage/Raum" muss so
nicht im JavaScript wieder auseinandergenommen werden.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Seit der Umstellung auf MQTT ruft es niemand mehr auf - kein PHP, kein
Startskript, kein Aufgabenplaner. Der neue Name macht das sichtbar, bevor
die Datei irgendwann geloescht wird; das Wallbox-Passwort steht darin
weiterhin im Klartext.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Von der Skoda-Website abgelesen. Datenbanken im Netz nennen fuer den RS
des Modelljahrs 2026 teils 79 kWh nutzbar - der Hersteller ist die
verlaesslichere Quelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Schieberegler "Zusaetzlich benoetigte Ladung" rechnet Prozent in
Wattstunden um. Dafuer standen bisher drei verschiedene Zahlen im Code:
140 Wh/% beim Schreiben der EG-Wallbox, 90 Wh/% beim go-e und feste
14000 Wh beim Zurueckrechnen im Browser - fuer beide Autos dieselbe. Eine
Einstellung von 50 % am go-e schrieb 4500 Wh und las sich beim naechsten
Oeffnen als 32 % zurueck.
Jetzt kommt die Zahl aus einer Quelle: restricted/config.php nennt Auto
und nutzbare Akkukapazitaet je Wallbox, carForm.php gibt die Wattstunden
je Prozent als data-Attribut an den Schieberegler weiter, und das
JavaScript rechnet damit zurueck statt mit einer festen Konstanten.
EG: Skoda Enyaq RS, Modelljahr 2026, 84 kWh brutto / 79 kWh nutzbar
OG: Jeep Compass 4xe, 11,4 kWh
Das Lademodal zeigt Auto und Kapazitaet jetzt unter dem Regler an - damit
sichtbar ist, worauf sich die Prozente beziehen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
carEG.php und carOG.php waren fast identisch und unterschieden sich nur im
Transportweg: der go-e bekam seine Kommandos per HTTP, die Wattpilot ueber
einen eigenen Python-Prozess je Klick, der sich einen Websocket aufbaute,
anmeldete, ein Feld setzte und wieder starb.
Beide haengen laengst am selben MQTT-Broker - der go-e mit eigenem Client
(mce=true, mcr=false), die Wattpilot ueber wattpilot_bruecke.py. Beide
nehmen Kommandos auf <praefix><schluessel>/set entgegen. Die Steuerung
steht deshalb jetzt einmal in carSteuerung.php; was die Wallboxen wirklich
trennt - Topic-Praefix, die Namen ate/att gegen ftt/fte und die
Wattstunden je Prozent - steht als Tabelle in restricted/wallboxen.php.
Nebenbei faellt damit /volume1/homes/wagner/wattpilot.py weg, das das
Passwort der Wallbox im Klartext enthaelt und ausserhalb jedes Repos liegt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>