Einstellungen -> Grundriss: Etagen, Raeume und Kacheln am Plan pflegen
Neuer Reiter mit Plan-Editor: Etagen anlegen, umbenennen, sortieren, loeschen und als Standard markieren; Grundrissbild hochladen; Raeume mit Name, Kuerzel und Thermostat-Zweig anlegen und bearbeiten; Kacheln im Plan ziehen oder einen Raum ohne Kachel mit "Platzieren" und einem Klick setzen. Loest tools/kachelpositionen.php ab - Raster, Geisterkachel und die Umrechnung Mitte -> linke obere Ecke sind von dort uebernommen. - restricted/grundriss.php: alle Pruefungen und Schreibzugriffe. Eine Etage mit Raeumen oder Automatiken laesst sich nicht loeschen, die Ablehnung nennt die Namen. Raeume loeschen laesst ihre Geraete ohne Raum. - Grundrissbilder nach tiles/grundriss/ (beschreibbar, nicht im Git), nur PNG/JPEG/WebP, am Inhalt geprueft; SVG bewusst nicht. Prüfsumme im Dateinamen, alte hochgeladene Bilder werden weggeraeumt. - ajax/settings.php: ?action=grundriss und sieben POST-Aktionen, jede antwortet mit dem ganzen neuen Stand. - "Werte" springt in den Reiter Home-Kacheln und oeffnet die Kachel; Home-Kacheln und Geraete laden nach einer Grundriss-Aenderung nach. - Startseite ohne Etage mit platziertem Raum: Hinweis auf die Einstellungen statt einer leeren Zeichenflaeche. - README: Grundriss als Inhalt statt Code, neue Dateien und Endpunkte, Reihenfolge der Schema-Dateien fuer ein neues Haus. Backend mit einer Probe-Etage durchgespielt (auch Fehlerfaelle, Upload, Aufraeumen); Oberflaeche auf einer Probeseite mit echten Daten und Zeiger-Ereignissen geprueft: Ziehen, Antippen, Platzieren, neuer Raum. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+61
-3
@@ -8,15 +8,25 @@
|
||||
* POST ?action=kacheln-save {"floor": "OG", "room": "bad",
|
||||
* "werte": [ ... ] oder null}
|
||||
* GET ?action=geraete Geraete mit Raum, Verwendung und Alter
|
||||
* POST ?action=geraete-raeume {"rooms": {"12": "OG/Bad", ...}}
|
||||
* POST ?action=geraete-raeume {"rooms": {"123": "11", ...}} Geraet -> Raumnummer
|
||||
* POST ?action=geraet-loeschen {"id": 12}
|
||||
* GET ?action=skoda-keys Stand der Fahrzeug-Schluessel (ohne Werte!)
|
||||
* POST ?action=skoda-keys-save {"felder": {"API_KEY2": "..."},
|
||||
* "loeschen": ["API_KEY3"]}
|
||||
*
|
||||
* GET ?action=grundriss Etagen, Raeume, Kachelpositionen
|
||||
* POST ?action=etage-speichern {"code": "EG", "label": "...", "standard": true, "neu": false}
|
||||
* POST ?action=etagen-reihenfolge {"codes": ["OG", "EG", ...]}
|
||||
* POST ?action=etage-loeschen {"code": "EG"}
|
||||
* POST ?action=etage-bild multipart: code, bild (Datei)
|
||||
* POST ?action=raum-speichern {"nr": 0|12, "floor": "EG", "name": "...", "kuerzel": "", "thermostat": ""}
|
||||
* POST ?action=raum-position {"nr": 12, "x": 120, "y": 80} (x/y null = vom Plan)
|
||||
* POST ?action=raum-loeschen {"nr": 12}
|
||||
* Die Grundriss-Aktionen antworten mit dem ganzen neuen Stand.
|
||||
*
|
||||
* Ein reiner Verteiler: geprueft und geschrieben wird in
|
||||
* restricted/costs.php bzw. restricted/kacheln.php, damit Maske und Endpunkt
|
||||
* dieselbe Wahrheit ueber einen Zeitraum oder eine Kachel haben.
|
||||
* restricted/costs.php, kacheln.php bzw. grundriss.php, damit Maske und
|
||||
* Endpunkt dieselbe Wahrheit ueber einen Zeitraum oder eine Kachel haben.
|
||||
*/
|
||||
|
||||
require_once("../helper.php");
|
||||
@@ -24,6 +34,7 @@ require_once("../restricted/costs.php");
|
||||
require_once("../restricted/kacheln.php");
|
||||
require_once("../restricted/automations.php");
|
||||
require_once("../restricted/skodaKeys.php");
|
||||
require_once("../restricted/grundriss.php");
|
||||
|
||||
if (!checkLogin()) {
|
||||
http_response_code(403);
|
||||
@@ -40,6 +51,20 @@ function jsonAntwort($data, $code = 200)
|
||||
|
||||
$action = $_GET["action"] ?? "list";
|
||||
|
||||
// Das Grundrissbild kommt als Formular mit Datei, nicht als JSON - deshalb
|
||||
// vor dem JSON-Teil.
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST" && $action === "etage-bild") {
|
||||
try {
|
||||
$bild = etageBildSpeichern($_POST["code"] ?? "", $_FILES["bild"] ?? null);
|
||||
grundriss(true);
|
||||
jsonAntwort(["bild" => $bild, "stand" => grundrissStand()]);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
jsonAntwort(["error" => $e->getMessage()], 400);
|
||||
} catch (Throwable $e) {
|
||||
jsonAntwort(["error" => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$body = json_decode(file_get_contents("php://input"), true);
|
||||
if (!is_array($body)) {
|
||||
@@ -90,6 +115,31 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$name = geraetLoeschen($body["id"] ?? 0);
|
||||
jsonAntwort(["geloescht" => $name, "geraete" => geraeteListe()]);
|
||||
|
||||
case "etage-speichern":
|
||||
etageSpeichern($body);
|
||||
grundriss(true);
|
||||
jsonAntwort(["stand" => grundrissStand()]);
|
||||
case "etagen-reihenfolge":
|
||||
etagenReihenfolge($body["codes"] ?? null);
|
||||
grundriss(true);
|
||||
jsonAntwort(["stand" => grundrissStand()]);
|
||||
case "etage-loeschen":
|
||||
etageLoeschen($body["code"] ?? "");
|
||||
grundriss(true);
|
||||
jsonAntwort(["stand" => grundrissStand()]);
|
||||
case "raum-speichern":
|
||||
$nr = raumSpeichern($body);
|
||||
grundriss(true);
|
||||
jsonAntwort(["nr" => $nr, "stand" => grundrissStand()]);
|
||||
case "raum-position":
|
||||
$pos = raumPosition($body["nr"] ?? 0, $body["x"] ?? null, $body["y"] ?? null);
|
||||
grundriss(true);
|
||||
jsonAntwort(["position" => $pos, "stand" => grundrissStand()]);
|
||||
case "raum-loeschen":
|
||||
raumLoeschen($body["nr"] ?? 0);
|
||||
grundriss(true);
|
||||
jsonAntwort(["stand" => grundrissStand()]);
|
||||
|
||||
case "skoda-keys-save":
|
||||
/*
|
||||
* Neue Schluessel eintragen. Zurueck kommt der neue Stand -
|
||||
@@ -130,6 +180,14 @@ if ($action === "kacheln") {
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === "grundriss") {
|
||||
try {
|
||||
jsonAntwort(grundrissStand());
|
||||
} catch (Throwable $e) {
|
||||
jsonAntwort(["error" => "Grundriss nicht abrufbar: " . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
if ($action === "skoda-keys") {
|
||||
try {
|
||||
jsonAntwort(skodaStand());
|
||||
|
||||
Reference in New Issue
Block a user