Smart-Dashboard/README.md
2026-02-02 19:21:09 +01:00

246 lines
7.0 KiB
Markdown

# Normalisierte Datenbankstruktur für Somfy Tahoma
## Übersicht
Die Datenbank wurde von einer denormalisierten Struktur (mit JSON in `parameters`)
in eine vollständig normalisierte relationale Struktur überführt.
## Datenbankschema
### Haupttabellen
#### `actors`
Speichert alle Aktoren (Geräte mit Steuerungsfunktion)
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| type | VARCHAR(50) | Gerätetyp (z.B. RollerShutter) |
| name | VARCHAR(70) | Name des Geräts |
| parameters | TEXT (nullable) | Optionale Meta-Informationen |
| url | VARCHAR(100) UNIQUE | Tahoma Device URL |
#### `sensors`
Speichert alle Sensoren (Geräte die Werte melden)
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| type | VARCHAR(50) | Sensortyp (z.B. TemperatureSensor) |
| name | VARCHAR(70) | Name des Sensors |
| parameters | TEXT (nullable) | Optionale Meta-Informationen |
| url | VARCHAR(100) UNIQUE | Tahoma Device URL |
### Aktor-Detailtabellen
#### `actor_commands`
Speichert alle verfügbaren Commands für jeden Aktor
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| actor_id | INT (FK → actors.id) | Referenz zum Aktor |
| command_name | VARCHAR(100) | Name des Commands (z.B. setPosition, open) |
**Beispieldaten:**
```
actor_id | command_name
---------|-------------
1 | open
1 | close
1 | setPosition
2 | on
2 | off
```
#### `command_parameters`
Speichert die Parameter für jeden Command
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| command_id | INT (FK → actor_commands.id) | Referenz zum Command |
| parameter_name | VARCHAR(100) | Name des Parameters (z.B. position) |
| parameter_type | VARCHAR(50) | Datentyp (z.B. integer, string) |
| min_value | DECIMAL(10,2) | Minimaler Wert (nullable) |
| max_value | DECIMAL(10,2) | Maximaler Wert (nullable) |
| possible_values | TEXT | JSON Array mit möglichen Werten (nullable) |
**Beispieldaten:**
```
command_id | parameter_name | parameter_type | min_value | max_value
-----------|----------------|----------------|-----------|----------
3 | position | integer | 0 | 100
```
#### `actor_states`
Speichert die aktuellen States von Aktoren
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| actor_id | INT (FK → actors.id) | Referenz zum Aktor |
| state_name | VARCHAR(100) | Name des State (z.B. core:ClosureState) |
| state_type | INT | State-Typ Code aus Tahoma API |
| current_value | VARCHAR(255) | Aktueller Wert |
| unit | VARCHAR(20) | Einheit (nullable) |
| last_updated | TIMESTAMP | Zeitpunkt der letzten Aktualisierung |
### Sensor-Detailtabellen
#### `sensor_states`
Speichert alle verfügbaren States für jeden Sensor
| Spalte | Typ | Beschreibung |
|--------|-----|--------------|
| id | INT (PK, AUTO_INCREMENT) | Eindeutige ID |
| sensor_id | INT (FK → sensors.id) | Referenz zum Sensor |
| state_name | VARCHAR(100) | Name des State (z.B. core:TemperatureState) |
| state_type | INT | State-Typ Code aus Tahoma API |
| current_value | VARCHAR(255) | Aktueller Wert |
| unit | VARCHAR(20) | Einheit (z.B. °C, %) (nullable) |
| last_updated | TIMESTAMP | Zeitpunkt der letzten Aktualisierung |
**Beispieldaten:**
```
sensor_id | state_name | state_type | current_value | unit
----------|-------------------------|------------|---------------|------
1 | core:TemperatureState | 1 | 21.5 | °C
2 | core:LuminanceState | 1 | 350 | lux
```
## Beziehungen (Foreign Keys)
```
actors (1) ──< (N) actor_commands
└──< (N) command_parameters
actors (1) ──< (N) actor_states
sensors (1) ──< (N) sensor_states
```
Alle Foreign Keys mit `ON DELETE CASCADE` → Wenn ein Aktor/Sensor gelöscht wird,
werden automatisch alle zugehörigen Commands, Parameter und States gelöscht.
## Hilfreiche Views
### `view_actors_with_commands`
Zeigt alle Aktoren mit ihren Commands und Parametern in einer flachen Ansicht
```sql
SELECT * FROM view_actors_with_commands WHERE actor_name = 'Wohnzimmer Rollo';
```
### `view_sensors_with_states`
Zeigt alle Sensoren mit ihren aktuellen States
```sql
SELECT * FROM view_sensors_with_states WHERE sensor_type = 'TemperatureSensor';
```
### `view_all_devices`
Zeigt eine Übersicht aller Geräte (Aktoren und Sensoren)
```sql
SELECT * FROM view_all_devices ORDER BY name;
```
## Beispiel-Queries
### Alle Commands eines bestimmten Aktors anzeigen
```sql
SELECT
a.name as aktor_name,
ac.command_name,
cp.parameter_name,
cp.min_value,
cp.max_value
FROM actors a
JOIN actor_commands ac ON a.id = ac.actor_id
LEFT JOIN command_parameters cp ON ac.id = cp.command_id
WHERE a.name = 'Wohnzimmer Rollo';
```
### Alle Temperatursensoren mit aktuellem Wert
```sql
SELECT
s.name as sensor_name,
ss.current_value as temperatur,
ss.unit,
ss.last_updated
FROM sensors s
JOIN sensor_states ss ON s.id = ss.sensor_id
WHERE s.type = 'TemperatureSensor'
AND ss.state_name LIKE '%Temperature%';
```
### Alle Aktoren eines bestimmten Typs
```sql
SELECT
name,
type,
COUNT(DISTINCT ac.id) as anzahl_commands
FROM actors a
LEFT JOIN actor_commands ac ON a.id = ac.actor_id
WHERE a.type = 'RollerShutter'
GROUP BY a.id, a.name, a.type;
```
### Commands ohne Parameter finden
```sql
SELECT
a.name as aktor,
ac.command_name
FROM actors a
JOIN actor_commands ac ON a.id = ac.actor_id
LEFT JOIN command_parameters cp ON ac.id = cp.command_id
WHERE cp.id IS NULL;
```
## Vorteile der normalisierten Struktur
1. **Keine Datenduplizierung**: Jeder Command und Parameter wird nur einmal gespeichert
2. **Einfache Queries**: SQL-Joins statt JSON-Parsing
3. **Flexible Erweiterung**: Neue Spalten können einfach hinzugefügt werden
4. **Referentielle Integrität**: Foreign Keys garantieren Konsistenz
5. **Performance**: Indizes auf relevanten Spalten für schnelle Suchen
6. **Typsicherheit**: Min/Max als DECIMAL statt String
## Migration von alter zu neuer Struktur
Falls Sie bereits Daten in der alten Struktur haben:
```sql
-- Backup erstellen
CREATE TABLE actors_old AS SELECT * FROM actors;
CREATE TABLE sensors_old AS SELECT * FROM sensors;
-- Alte Tabellen löschen
DROP TABLE actors;
DROP TABLE sensors;
-- Neue Struktur erstellen (database_schema.sql ausführen)
SOURCE database_schema.sql;
-- Python-Script ausführen um Daten neu zu importieren
```
## Wartung
### Regelmäßige Aktualisierung der States
Das Script kann regelmäßig ausgeführt werden. Bei `CLEAR_TABLES = True` werden
alle Daten neu importiert. Bei `CLEAR_TABLES = False` können Updates implementiert werden.
### Veraltete Geräte entfernen
```sql
-- Geräte finden die nicht mehr in der Tahoma Box vorhanden sind
-- (nach erneutem Import)
```
### Index-Optimierung prüfen
```sql
SHOW INDEX FROM actors;
SHOW INDEX FROM actor_commands;
```