246 lines
7.0 KiB
Markdown
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;
|
|
```
|