Drei Sachen an den Kacheln und am Raum-Modal. Die Platzhalter sind nur noch Striche. Vorher stand dort "---- hPa", gefuellt wurde die Zeile aber mit der Solltemperatur - eine Einheit, die nie kam, an einer Stelle, die etwas anderes zeigt. Der Heizungs-Reiter erscheint nur noch, wo auch ein Thermostat haengt. Frueher entschied das "hat der Raum eine Kachel" - das stimmte, solange nur Raeume mit Thermostat eine bekamen. Seit auch Kueche und Technik eine haben, bekamen sie einen Regler fuer eine Heizung, die es dort nicht gibt. Jetzt zaehlt, ob im Raum ein Geraet der Bedienform "heizung" steht. Und eine Kachel zeigt jetzt ein bis drei frei gewaehlte Messwerte. In restricted/rooms.php steht je Raum unter "werte", welche das sind: topic, optional pfad (Schluessel in einer JSON-Nachricht), einheit, stellen. Ohne Angabe bleibt es bei den drei Thermostatwerten samt Heizsymbol, also genau wie bisher - nur diese Raeume zeichnen die Symbole ueberhaupt noch. Alles kommt live ueber MQTT, auch die beiden Shelly-Zaehler: sie schicken ihre sechzehn Werte als eine JSON-Nachricht auf Power_EG/status/em:0, aus der "pfad" den gesuchten Schluessel greift. Der Browser meldet nicht mehr fest "Raumtemp/#" an, sondern die Zweige, die die Raumtabelle nennt - derzeit vier statt vierzig einzelner Topics. Damit steht auf EG Technik die Leistung (gemessen 293 W), auf UG Technik Leistung und Wasserzaehler (78 W, 400,4 m3). Raeume ohne Messwert tragen ihren Namen und oeffnen den Raum; ein leeres Rechteck saehe aus wie ein Fehler. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
145 lines
6.4 KiB
PHP
145 lines
6.4 KiB
PHP
<?php
|
|
/*
|
|
* Einzige Quelle für die Räume der Home-Ansicht.
|
|
*
|
|
* Aus dieser Tabelle entstehen sowohl die SVG-Kacheln in home.php als auch
|
|
* die Aktualisierungsschleife in js/solar/homeMQTT.js (die Tabelle wird dafür
|
|
* als JSON in die Seite geschrieben). Ein neuer oder umbenannter Raum ist
|
|
* damit eine Zeile hier statt drei Stellen im Code.
|
|
*
|
|
* floor Etage; bestimmt zugleich den Zweig Raumtemp/<floor>/
|
|
* mqtt Name des Raums im MQTT-Baum: Raumtemp/<floor>/<mqtt>/...
|
|
* id Kürzel in den SVG-Element-IDs: <floor>_w0_<id>, <floor>_<id>_heater
|
|
* x, y Position der Kachel im SVG (viewBox 400x300) - fehlt bei Räumen
|
|
* ohne Kachel
|
|
* werte Was auf der Kachel steht: bis zu drei Messwerte, jeder mit
|
|
* topic, optional pfad (Schlüssel in einer JSON-Nachricht),
|
|
* einheit und stellen (Nachkommastellen). Fehlt der Eintrag, sind
|
|
* es die drei Thermostatwerte - Soll, Ist, Feuchte - wie bisher.
|
|
* Eine leere Liste heisst: kein Messwert, die Kachel trägt nur
|
|
* ihren Namen und öffnet den Raum.
|
|
*
|
|
* Ein Raum ohne x/y ist trotzdem ein Raum: Geräte lassen sich ihm zuordnen
|
|
* (siehe die Spalte actors.room und den Zuordnungsdialog in der Karte
|
|
* "Automatismen"), er erscheint nur nicht als Kachel im Grundriss. Derzeit
|
|
* hat jeder Raum eine Kachel; die Unterscheidung bleibt, weil ein neuer Raum
|
|
* zuerst als Zeile ohne Position entsteht und erst dann seinen Platz im
|
|
* Grundriss bekommt.
|
|
*
|
|
* Wo eine Kachel hingehört, misst tools/kachelpositionen.php aus: Grundriss
|
|
* mit Raster, Geisterkachel am Zeiger, fertige Zeile zum Abschreiben. x/y
|
|
* ist die linke obere Ecke der 24 x 19 grossen Kachel, nicht ihre Mitte.
|
|
*/
|
|
|
|
// Reihenfolge im Menü und in der Anzeige; OG ist die Standardetage.
|
|
$floors = ["OG", "EG", "UG"];
|
|
|
|
$rooms = [
|
|
["floor" => "OG", "mqtt" => "Wohnzimmer", "id" => "wozi", "x" => 180, "y" => 140],
|
|
["floor" => "OG", "mqtt" => "KiZi", "id" => "kizi", "x" => 130, "y" => 80],
|
|
["floor" => "OG", "mqtt" => "Schlafzimmer", "id" => "schlafen", "x" => 235, "y" => 70],
|
|
["floor" => "OG", "mqtt" => "Bad", "id" => "bad", "x" => 260, "y" => 120],
|
|
["floor" => "OG", "mqtt" => "Buero", "id" => "buero", "x" => 265, "y" => 175],
|
|
// Kein Thermostat, und noch kein Gerät zugeordnet - die Kachel trägt
|
|
// vorerst nur ihren Namen.
|
|
["floor" => "OG", "mqtt" => "Kueche", "id" => "kueche", "x" => 122, "y" => 138,
|
|
"werte" => []],
|
|
["floor" => "OG", "mqtt" => "Technik", "id" => "technik", "x" => 173, "y" => 67,
|
|
"werte" => []],
|
|
["floor" => "EG", "mqtt" => "Wohnzimmer", "id" => "wozi", "x" => 185, "y" => 150],
|
|
["floor" => "EG", "mqtt" => "Florian", "id" => "kizi", "x" => 130, "y" => 90],
|
|
["floor" => "EG", "mqtt" => "Schlafen", "id" => "schlafen", "x" => 235, "y" => 80],
|
|
["floor" => "EG", "mqtt" => "Bad", "id" => "bad", "x" => 253, "y" => 130],
|
|
["floor" => "EG", "mqtt" => "Magdalena", "id" => "buero", "x" => 258, "y" => 180],
|
|
["floor" => "EG", "mqtt" => "Kueche", "id" => "kueche", "x" => 126, "y" => 146,
|
|
"werte" => []],
|
|
// Der Shelly-Zähler des EG meldet seine Werte als JSON in einer einzigen
|
|
// Nachricht; "pfad" greift den Schlüssel daraus heraus.
|
|
["floor" => "EG", "mqtt" => "Technik", "id" => "technik", "x" => 172, "y" => 78,
|
|
"werte" => [
|
|
["topic" => "Power_EG/status/em:0", "pfad" => "total_act_power",
|
|
"einheit" => "W", "stellen" => 0, "gross" => true],
|
|
]],
|
|
["floor" => "UG", "mqtt" => "Buero", "id" => "buero", "x" => 140, "y" => 140],
|
|
["floor" => "UG", "mqtt" => "Bad", "id" => "bad", "x" => 210, "y" => 80],
|
|
["floor" => "UG", "mqtt" => "Kueche", "id" => "kueche", "x" => 190, "y" => 195],
|
|
["floor" => "UG", "mqtt" => "Technik", "id" => "technik", "x" => 238, "y" => 93,
|
|
"werte" => [
|
|
["topic" => "Power_UG/status/em:0", "pfad" => "total_act_power",
|
|
"einheit" => "W", "stellen" => 0, "gross" => true],
|
|
["topic" => "wasser/main/value", "einheit" => "m³", "stellen" => 1],
|
|
]],
|
|
];
|
|
|
|
/**
|
|
* Räume einer Etage, die eine Kachel im Grundriss haben.
|
|
*
|
|
* Alles, was zeichnet oder aktualisiert, geht hierüber - ein Raum ohne
|
|
* Position hätte keine Stelle im SVG und keine Elemente, die sich füllen
|
|
* liessen.
|
|
*/
|
|
function roomsOnFloor($floor)
|
|
{
|
|
return array_values(array_filter($GLOBALS["rooms"], function ($room) use ($floor) {
|
|
return $room["floor"] == $floor && isset($room["x"]);
|
|
}));
|
|
}
|
|
|
|
/** Alle Räume, auch die ohne Kachel - für die Geräte-Zuordnung. */
|
|
function allRooms()
|
|
{
|
|
return $GLOBALS["rooms"];
|
|
}
|
|
|
|
/** Nur die Räume mit Kachel, für die Aktualisierungsschleife im Browser. */
|
|
function roomsWithTile()
|
|
{
|
|
return array_values(array_map("mitWerten", array_filter($GLOBALS["rooms"], function ($room) {
|
|
return isset($room["x"]);
|
|
})));
|
|
}
|
|
|
|
/**
|
|
* Die Messwerte einer Kachel, fertig ausgeschrieben.
|
|
*
|
|
* Ohne eigene Angabe sind es die drei Thermostatwerte, die dort schon immer
|
|
* standen: Solltemperatur klein darüber, Isttemperatur gross, Feuchte klein
|
|
* darunter. Nur diese Räume bekommen auch die Symbole für "heizt" und
|
|
* "Pufferbetrieb" - anderswo gibt es nichts zu heizen.
|
|
*/
|
|
function mitWerten($room)
|
|
{
|
|
if (isset($room["werte"])) {
|
|
$room["heizung"] = false;
|
|
$room["werte"] = array_slice($room["werte"], 0, 3);
|
|
return $room;
|
|
}
|
|
$zweig = "Raumtemp/" . $room["floor"] . "/" . $room["mqtt"] . "/";
|
|
$room["heizung"] = true;
|
|
$room["werte"] = [
|
|
["topic" => $zweig . "Set Temp[degC]", "einheit" => "°C", "stellen" => 0],
|
|
["topic" => $zweig . "Temp[degC]", "einheit" => "°C", "gross" => true],
|
|
["topic" => $zweig . "rHum[%]", "einheit" => "%rF"],
|
|
];
|
|
return $room;
|
|
}
|
|
|
|
/**
|
|
* Was der Browser beim Broker anmelden muss, damit die Kacheln laufen.
|
|
*
|
|
* Nicht die einzelnen Topics, sondern ihre Zweige: aus vierzig Anmeldungen
|
|
* für Raumtemp werden so vier insgesamt. Der Zweig bringt ausserdem mit,
|
|
* was die Kachel nebenbei braucht - "Heating" und "mode" stehen in keiner
|
|
* Werteliste, das Heizsymbol lebt aber davon.
|
|
*/
|
|
function tileTopics()
|
|
{
|
|
$zweige = [];
|
|
foreach (roomsWithTile() as $room) {
|
|
foreach ($room["werte"] as $wert) {
|
|
$zweige[explode("/", $wert["topic"])[0] . "/#"] = true;
|
|
}
|
|
}
|
|
return array_keys($zweige);
|
|
}
|