Aussengelaende wird die vierte Etage AG

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>
This commit is contained in:
2026-09-04 17:55:11 +02:00
co-authored by Claude Opus 5
parent 71f2f844c8
commit d3c1cb4682
8 changed files with 117 additions and 69 deletions
+56 -1
View File
@@ -32,7 +32,23 @@
*/
// Reihenfolge im Menü und in der Anzeige; OG ist die Standardetage.
$floors = ["OG", "EG", "UG"];
//
// AG ist das Außengelände - eine Etage ohne Grundriss. Was draußen hängt,
// stand vorher als Pseudo-Raum "aussen" in automations.php und war damit ein
// einziger Topf: Carport, Pergola, Garage und die Wechselrichter alle
// nebeneinander. Als Etage bekommt jeder davon einen Raum, und die
// Geräteauswahl im Automatik-Editor gruppiert danach wie überall sonst.
$floors = ["OG", "EG", "UG", "AG"];
// Ausgeschriebene Namen für Beschriftungen, wo Platz ist. Das Kürzel steht in
// URLs (?floor=AG), in SVG-Element-Ids (AG_Info) und im MQTT-Baum - dort will
// man weder Umlaute noch Länge.
$floorLabels = [
"OG" => "Obergeschoss",
"EG" => "Erdgeschoss",
"UG" => "Untergeschoss",
"AG" => "Außengelände",
];
$rooms = [
["floor" => "OG", "mqtt" => "Wohnzimmer", "id" => "wozi", "x" => 180, "y" => 140],
@@ -69,6 +85,21 @@ $rooms = [
"einheit" => "W", "stellen" => 0, "gross" => true],
["topic" => "wasser/main/value", "einheit" => "", "stellen" => 1],
]],
// Außengelände: noch ohne x/y, es gibt ja keinen Lageplan, auf den eine
// Kachel zeigen könnte. Zuordnen und Automatiken anlegen geht trotzdem -
// dafür zählt allein, dass der Raum hier steht. Kommt der Lageplan, sind
// es zwei Zahlen je Zeile, gemessen mit tools/kachelpositionen.php.
//
// Die Namen stammen von den Geräten selbst: die Hoymiles heißen seit jeher
// "Carport 1-6" und "Veranda OG2-4", das Sonnensegel sitzt an der Pergola.
["floor" => "AG", "mqtt" => "Carport", "id" => "carport", "werte" => []],
["floor" => "AG", "mqtt" => "Veranda", "id" => "veranda", "werte" => []],
["floor" => "AG", "mqtt" => "Pergola", "id" => "pergola", "werte" => []],
["floor" => "AG", "mqtt" => "Terrasse", "id" => "terrasse", "werte" => []],
["floor" => "AG", "mqtt" => "Garage", "id" => "garage", "werte" => []],
// Der Garten ist kein Bauteil wie die anderen, aber ein Ort: hier haengen
// der Regensensor und die beiden Ventilsteuerungen.
["floor" => "AG", "mqtt" => "Garten", "id" => "garten", "werte" => []],
];
/**
@@ -91,6 +122,30 @@ function allRooms()
return $GLOBALS["rooms"];
}
/** Ausgeschriebener Name einer Etage; unbekannte bleiben ihr Kürzel. */
function floorLabel($floor)
{
return $GLOBALS["floorLabels"][$floor] ?? $floor;
}
/**
* Etagen mit Grundriss - die, die im Menü und im SVG auftauchen.
*
* Das Außengelände ist eine Etage ohne Bild: seine Räume haben keine Kachel,
* und ein Menüpunkt dorthin führte auf eine leere Zeichenfläche. Sobald der
* erste AG-Raum ein x/y bekommt, erscheint die Etage von selbst auch dort -
* es gibt keine zweite Liste, die man nachziehen müsste.
*
* Für die Zuordnung und die Automatiken zählt dagegen $floors: dort ist das
* Außengelände von Anfang an dabei.
*/
function floorsWithPlan()
{
return array_values(array_filter($GLOBALS["floors"], function ($floor) {
return count(roomsOnFloor($floor)) > 0;
}));
}
/** Nur die Räume mit Kachel, für die Aktualisierungsschleife im Browser. */
function roomsWithTile()
{