Files
2025-11-11 16:38:41 +01:00

352 lines
7.0 KiB
Markdown

# Device Simulator Web Application
Web-basierte Anwendung zur Simulation von Home-Automation-Geräten mit Echtzeit-Monitoring.
## Features
-**Web-Interface**: Dashboard mit Echtzeit-Anzeige aller Events
-**Server-Sent Events (SSE)**: Live-Updates ohne Polling
-**Funktioniert ohne Browser**: Simulator läuft im Hintergrund
-**Multi-Device Support**: Lights + Thermostats
-**MQTT Integration**: Vollständige Kommunikation über MQTT
-**Statistiken**: Zähler für Events, Commands und States
-**Event-History**: Letzte 50 Events mit Details
## Geräte
### Lights (3 Stück)
- `test_lampe_1` - Dimmbar
- `test_lampe_2` - Einfach
- `test_lampe_3` - Dimmbar
### Thermostats (1 Stück)
- `test_thermo_1` - Auto/Heat/Off Modi, Temperatur-Drift
## Installation
Der Simulator ist bereits Teil des Projekts. Keine zusätzlichen Dependencies erforderlich.
## Start
### Local Development
```bash
# Standard-Start (Port 8010)
poetry run uvicorn apps.simulator.main:app --host 0.0.0.0 --port 8010
# Mit Auto-Reload für Entwicklung
poetry run uvicorn apps.simulator.main:app --host 0.0.0.0 --port 8010 --reload
# Im Hintergrund
poetry run uvicorn apps.simulator.main:app --host 0.0.0.0 --port 8010 > /tmp/simulator.log 2>&1 &
```
### Docker Container
#### Build Image
```bash
docker build -t simulator:dev -f apps/simulator/Dockerfile .
```
#### Run Container
```bash
docker run --rm -p 8010:8010 \
-e MQTT_BROKER=172.23.1.102 \
-e MQTT_PORT=1883 \
-e SIM_PORT=8010 \
simulator:dev
```
**Note for finch/nerdctl users:**
- finch binds ports to `127.0.0.1` by default
- The web interface will be accessible at `http://127.0.0.1:8010`
#### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `MQTT_BROKER` | `172.16.2.16` | MQTT broker hostname/IP |
| `MQTT_PORT` | `1883` | MQTT broker port |
| `SIM_PORT` | `8010` | Port for web interface |
## Web-Interface
Öffne im Browser:
```
http://localhost:8010
```
### Features im Dashboard
1. **Status-Anzeige**
- MQTT-Verbindungsstatus
- Anzahl aktiver Geräte
- Simulator-Status
2. **Geräte-Übersicht**
- Echtzeit-Anzeige aller Light-States
- Echtzeit-Anzeige aller Thermostat-States
3. **Event-Stream**
- Alle MQTT-Commands
- Alle State-Updates
- Temperatur-Drift-Events
- Fehler und Warnungen
4. **Statistiken**
- Total Events
- Commands Received
- States Published
5. **Controls**
- Clear Events
- Toggle Auto-Scroll
## API Endpoints
### `GET /`
Web-Dashboard (HTML)
### `GET /health`
Health-Check
```json
{
"status": "ok",
"simulator_running": true,
"mqtt_connected": true
}
```
### `GET /status`
Vollständiger Status
```json
{
"connected": true,
"running": true,
"light_states": {...},
"thermostat_states": {...},
"broker": "172.16.2.16:1883"
}
```
### `GET /events`
Letzte Events (JSON)
```json
{
"events": [...]
}
```
### `GET /realtime`
Server-Sent Events Stream
## Event-Typen
### `simulator_connected`
Simulator hat MQTT-Verbindung hergestellt
```json
{
"type": "simulator_connected",
"broker": "172.16.2.16:1883",
"client_id": "device_simulator-abc123"
}
```
### `command_received`
SET-Command von MQTT empfangen
```json
{
"type": "command_received",
"device_id": "test_lampe_1",
"topic": "vendor/test_lampe_1/set",
"payload": {"power": "on"}
}
```
### `light_updated`
Light-State wurde aktualisiert
```json
{
"type": "light_updated",
"device_id": "test_lampe_1",
"changes": {
"power": {"old": "off", "new": "on"}
},
"new_state": {"power": "on", "brightness": 50}
}
```
### `thermostat_updated`
Thermostat-State wurde aktualisiert
```json
{
"type": "thermostat_updated",
"device_id": "test_thermo_1",
"changes": {
"mode": {"old": "off", "new": "heat"}
},
"new_state": {...}
}
```
### `temperature_drift`
Temperatur-Drift simuliert (alle 5 Sekunden)
```json
{
"type": "temperature_drift",
"device_id": "test_thermo_1",
"old_temp": 20.5,
"new_temp": 20.7,
"target": 21.0,
"mode": "auto"
}
```
### `state_published`
State wurde nach MQTT publiziert
```json
{
"type": "state_published",
"device_id": "test_lampe_1",
"device_type": "light",
"topic": "vendor/test_lampe_1/state",
"payload": {"power": "on", "brightness": 50}
}
```
## MQTT Topics
### Subscribe
- `vendor/test_lampe_1/set`
- `vendor/test_lampe_2/set`
- `vendor/test_lampe_3/set`
- `vendor/test_thermo_1/set`
### Publish (retained, QoS 1)
- `vendor/test_lampe_1/state`
- `vendor/test_lampe_2/state`
- `vendor/test_lampe_3/state`
- `vendor/test_thermo_1/state`
## Integration mit anderen Services
Der Simulator funktioniert nahtlos mit:
1. **Abstraction Layer** (`apps.abstraction.main`)
- Empfängt Commands über MQTT
- Sendet States zurück
2. **API** (`apps.api.main`)
- Commands werden via API gesendet
- Simulator reagiert automatisch
3. **UI** (`apps.ui.main`)
- UI zeigt Simulator-States in Echtzeit
- Bedienung über UI beeinflusst Simulator
## Deployment
### Systemd Service
```ini
[Unit]
Description=Device Simulator
After=network.target
[Service]
Type=simple
User=homeautomation
WorkingDirectory=/path/to/home-automation
ExecStart=/path/to/.venv/bin/uvicorn apps.simulator.main:app --host 0.0.0.0 --port 8003
Restart=always
[Install]
WantedBy=multi-user.target
```
### Docker
```dockerfile
FROM python:3.14
WORKDIR /app
COPY . .
RUN pip install poetry && poetry install
EXPOSE 8003
CMD ["poetry", "run", "uvicorn", "apps.simulator.main:app", "--host", "0.0.0.0", "--port", "8003"]
```
## Troubleshooting
### Simulator startet nicht
```bash
# Check logs
tail -f /tmp/simulator.log
# Verify MQTT broker
mosquitto_sub -h 172.16.2.16 -t '#' -v
```
### Keine Events im Dashboard
1. Browser-Console öffnen (F12)
2. Prüfe SSE-Verbindung
3. Reload Seite (F5)
### MQTT-Verbindung fehlgeschlagen
```bash
# Test broker connection
mosquitto_pub -h 172.16.2.16 -t test -m hello
# Check broker status
systemctl status mosquitto
```
## Unterschied zum alten Simulator
### Alt (`tools/device_simulator.py`)
- ✅ Reine CLI-Anwendung
- ✅ Logging nur in stdout
- ❌ Keine Web-UI
- ❌ Keine Live-Monitoring
### Neu (`apps/simulator/main.py`)
- ✅ FastAPI Web-Application
- ✅ Logging + Web-Dashboard
- ✅ SSE für Echtzeit-Updates
- ✅ REST API für Status
- ✅ Funktioniert auch ohne Browser
- ✅ Statistiken und Event-History
## Entwicklung
### Code-Struktur
```
apps/simulator/
├── __init__.py
├── main.py # FastAPI app + Simulator logic
└── templates/
└── index.html # Web dashboard
```
### Logging
```python
logger.info() # Wird in stdout UND als Event gestreamt
add_event({}) # Wird nur als Event gestreamt
```
### Neue Event-Typen hinzufügen
1. Event in `main.py` erstellen: `add_event({...})`
2. Optional: CSS-Klasse in `index.html` für Farbe
3. Event wird automatisch im Dashboard angezeigt
## Performance
- **Memory**: ~50 MB
- **CPU**: <1% idle, ~5% bei Commands
- **SSE Connections**: Unbegrenzt
- **Event Queue**: Max 100 Events (rolling)
- **Per-Client Queue**: Unbegrenzt
## License
Teil des Home-Automation Projekts.