Geraete hingen ueber den Text "Etage/Raum" an ihrem Raum, das Raum-Modal zerlegte "EG_Bad" am Unterstrich, und das Thermostat-Topic wurde aus Etage und Name zusammengesetzt. Ein umbenannter Raum haette still alle Geraete, seinen Temperaturregler und sein Heizsymbol verloren. - actors.room (Text) -> actors.room_id, Fremdschluessel auf rooms, beim Loeschen eines Raums SET NULL. Alle 59 Zuordnungen uebernommen. - automations.floor: ENUM(UG,EG,OG,AG) -> Verweis auf floors. Eine neue Etage kann damit auch Automatiken tragen. - room.php nimmt ?room=<Nummer>; Solltemperatur geht an rooms.thermostat + /changeSetTemp. - homeMQTT.js: Heizsymbol, Regler und Ist-Werte ueber mqttZweig(thermostat) statt mqttData.Raumtemp[Etage][Name]. - Raumvorschlaege in den Einstellungen: Messwerte unter dem Thermostat- Zweig eines Raums statt fest Raumtemp/<Etage>/<Name>. - Schluessel in raumListe(), Katalog und Maske ist die Raumnummer als Text. Geprueft gegen den Stand davor: Startseite gleich bis auf das Klickziel, jede der 25 Kacheln oeffnet ihren eigenen Raum; Geraeteliste, Vorschlaege, Editor-Katalog und die eigenen Geraete je Kachel gleich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
97 lines
5.6 KiB
SQL
97 lines
5.6 KiB
SQL
-- ---------------------------------------------------------------------------
|
|
-- Grundriss der Home-Ansicht: Etagen, Raeume, Kacheln - Datenbank `homeMesh`
|
|
-- ---------------------------------------------------------------------------
|
|
-- Vorher stand das alles fest in restricted/rooms.php, und die Werte auf den
|
|
-- Kacheln ließen sich getrennt davon in solarLog.kachelWerte ueberschreiben.
|
|
-- Fuer ein anderes Haus haette man den Quelltext umschreiben muessen. Jetzt
|
|
-- ist es Inhalt: eingestellt unter Einstellungen -> Grundriss, gelesen von
|
|
-- rooms.php.
|
|
--
|
|
-- In homeMesh und nicht in solarLog: actors.room und automations.floor zeigen
|
|
-- auf Raeume und Etagen, und Fremdschluessel greifen nur innerhalb einer
|
|
-- Datenbank.
|
|
--
|
|
-- Die Tabellen duerfen leer sein. Dann zeigt die Startseite einen Hinweis auf
|
|
-- die Einstellungen statt eines Hauses - das ist der Anfang jeder neuen
|
|
-- Installation.
|
|
--
|
|
-- Einspielen NACH homeMesh_DB-layout.sql und homeMesh_automations.sql: am
|
|
-- Ende haengt diese Datei die Fremdschluessel von actors.room_id und
|
|
-- automations.floor an die neuen Tabellen. Ein zweiter Lauf schadet nicht.
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
SET NAMES utf8mb4;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Etagen. `code` ist der Schluessel und bleibt es: er steht in URLs
|
|
-- (?floor=EG), in SVG-Element-Ids (EG_Info), in automations.floor und im
|
|
-- MQTT-Baum. Umbenennen heisst deshalb `label` aendern, nicht `code`.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `floors` (
|
|
`code` varchar(4) NOT NULL COMMENT 'Kuerzel: URL, SVG-Ids, automations.floor. Nach dem Anlegen fest',
|
|
`label` varchar(40) NOT NULL COMMENT 'Ausgeschriebener Name, z.B. Erdgeschoss',
|
|
`position` int(11) NOT NULL DEFAULT 0 COMMENT 'Reihenfolge in Menue, Reitern und Etagenschaltern',
|
|
`bild` varchar(255) DEFAULT NULL COMMENT 'Grundriss relativ zum Web-Root, z.B. tiles/grundriss/EG-1a2b.png. NULL = noch keins',
|
|
`standard` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Diese Etage oeffnet, wenn keine gewaehlt ist. Hoechstens eine',
|
|
PRIMARY KEY (`code`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Raeume. `id` ist die feste Nummer, auf die Geraete zeigen sollen; Name und
|
|
-- Kuerzel duerfen sich aendern.
|
|
--
|
|
-- kuerzel Teil der SVG-Element-Ids: <floor>_w0_<kuerzel>. Je Etage
|
|
-- eindeutig, sonst schriebe ein Wert in zwei Kacheln.
|
|
-- x, y linke obere Ecke der 24 x 19 grossen Kachel in der 400 x 300
|
|
-- grossen Zeichenflaeche. NULL = Raum ohne Kachel.
|
|
-- thermostat Zweig der Thermostatwerte, z.B. Raumtemp/EG/Bad. Traegt das
|
|
-- Heizsymbol und die Vorgabewerte der Kachel (Soll, Ist,
|
|
-- Feuchte). NULL = kein Thermostat.
|
|
-- werte JSON-Liste der Kachelwerte (Form siehe restricted/kacheln.php).
|
|
-- NULL = die Vorgabe aus dem Thermostat; [] = bewusst kein
|
|
-- Messwert, die Kachel traegt nur ihren Namen.
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS `rooms` (
|
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
|
`floor` varchar(4) NOT NULL,
|
|
`name` varchar(40) NOT NULL COMMENT 'Anzeigename, z.B. Wohnzimmer',
|
|
`kuerzel` varchar(40) NOT NULL COMMENT 'Teil der SVG-Ids, je Etage eindeutig',
|
|
`position` int(11) NOT NULL DEFAULT 0 COMMENT 'Reihenfolge innerhalb der Etage',
|
|
`x` smallint(6) DEFAULT NULL COMMENT 'Kachel: linke obere Ecke, NULL = keine Kachel',
|
|
`y` smallint(6) DEFAULT NULL,
|
|
`thermostat` varchar(120) DEFAULT NULL COMMENT 'MQTT-Zweig des Thermostats, NULL = keins',
|
|
`werte` text DEFAULT NULL COMMENT 'JSON der Kachelwerte, NULL = Vorgabe',
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uq_rooms_kuerzel` (`floor`, `kuerzel`),
|
|
UNIQUE KEY `uq_rooms_name` (`floor`, `name`),
|
|
CONSTRAINT `fk_rooms_floor` FOREIGN KEY (`floor`) REFERENCES `floors` (`code`)
|
|
ON UPDATE CASCADE ON DELETE RESTRICT
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Verweise auf Etagen und Raeume.
|
|
--
|
|
-- actors.room_id: ein geloeschter Raum laesst seine Geraete unzugeordnet
|
|
-- zurueck (SET NULL) - sie tauchen dann unter "ohne Raum" wieder auf.
|
|
-- automations.floor: eine Etage mit Automatiken laesst sich nicht loeschen
|
|
-- (RESTRICT); die Einstellungsseite nennt vorher die Namen.
|
|
--
|
|
-- Idempotent ueber information_schema, weil MariaDB kein
|
|
-- ADD CONSTRAINT IF NOT EXISTS fuer Fremdschluessel kennt.
|
|
-- ---------------------------------------------------------------------------
|
|
SET @da := (SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_NAME = 'fk_actors_room');
|
|
SET @sql := IF(@da = 0,
|
|
'ALTER TABLE actors ADD KEY idx_actors_room (room_id),
|
|
ADD CONSTRAINT fk_actors_room FOREIGN KEY (room_id) REFERENCES rooms (id) ON DELETE SET NULL',
|
|
'DO 0');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
|
|
|
SET @da := (SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
|
|
WHERE CONSTRAINT_SCHEMA = DATABASE() AND CONSTRAINT_NAME = 'fk_automations_floor');
|
|
SET @sql := IF(@da = 0,
|
|
'ALTER TABLE automations ADD CONSTRAINT fk_automations_floor FOREIGN KEY (floor)
|
|
REFERENCES floors (code) ON UPDATE CASCADE ON DELETE RESTRICT',
|
|
'DO 0');
|
|
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|