230 lines
5.1 KiB
Markdown
230 lines
5.1 KiB
Markdown
# ML-Serving-API
|
|
|
|
Diese Dokumentation beschreibt die REST-Endpunkte der aktuellen
|
|
Modell-Artefakt-, Vorhersage- und aktor-zentrierten Lifecycle-Schnittstelle.
|
|
|
|
Das Serving verwendet ein lokal trainiertes statistisches Baseline-Modell.
|
|
|
|
## Basis-URL
|
|
|
|
- Standard: `http://127.0.0.1:8000/ml`
|
|
- Health: `/health`
|
|
- Modelle: `/models`
|
|
- Retraining: `/retrain`
|
|
- Evaluation: `/evaluate`
|
|
- Einzelvorhersage: `/predict`
|
|
- Batchvorhersage: `/batch`
|
|
|
|
Die aktor-zentrierte API liegt unter `/v1/actuators`.
|
|
|
|
Der Standard-Start erfolgt über `uvicorn app.main:app`, danach stehen HA- und
|
|
ML-Routen in derselben Anwendung bereit.
|
|
|
|
## Endpoints
|
|
|
|
### `GET /ml/health`
|
|
|
|
Health-Check der ML-Services.
|
|
|
|
**Beispielantwort**
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"updated_at": "2026-06-11T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
### `GET /ml/models`
|
|
|
|
Listet alle registrierten Modell-Artefakte auf.
|
|
|
|
**Beispielantwort**
|
|
```json
|
|
{
|
|
"models": ["default"]
|
|
}
|
|
```
|
|
|
|
### `POST /ml/predict`
|
|
|
|
Einzelne Vorhersage für einen Sensor.
|
|
|
|
**Request**
|
|
```json
|
|
{
|
|
"modelId": "default",
|
|
"sensor_id": "sensor.kitchen",
|
|
"values": {"temperature": 21.0}
|
|
}
|
|
```
|
|
|
|
**Antwort**
|
|
```json
|
|
{
|
|
"model_id": "default",
|
|
"sensor_id": "sensor.kitchen",
|
|
"predictions": {"temperature": 21.4},
|
|
"confidence": 0.78,
|
|
"model_type": "statistical_baseline",
|
|
"explanations": {
|
|
"temperature": {
|
|
"direction": "steigend",
|
|
"change": 0.4,
|
|
"sample_count": 24,
|
|
"historical_mean": 20.7,
|
|
"trend_per_step": 0.4,
|
|
"summary": "temperature: steigend; Prognose ..."
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Die Erklärung nennt pro Merkmal den aktuellen und prognostizierten Wert,
|
|
Richtung, Veränderung, Datenbasis, historischen Bereich, Streuung, Trend und
|
|
Confidence. Sie wird deterministisch aus den gespeicherten Modellparametern
|
|
erzeugt.
|
|
|
|
### `POST /ml/retrain`
|
|
|
|
Trainiert die Artefakt-Metadaten aus neuen Sensordaten. Existiert `modelId`
|
|
bereits, wird das Artefakt atomisch ersetzt und beim nächsten Prozessstart aus
|
|
dem Modellverzeichnis geladen.
|
|
|
|
**Request**
|
|
```json
|
|
{
|
|
"modelId": "home-model",
|
|
"samples": [
|
|
{
|
|
"sensor_id": "sensor.kitchen",
|
|
"values": {"temperature": 21.0},
|
|
"label": "occupied"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Antwort**
|
|
```json
|
|
{
|
|
"model_id": "home-model",
|
|
"supported_sensors": ["sensor.kitchen"],
|
|
"trained_features": 1,
|
|
"model_type": "statistical_baseline",
|
|
"replaced": false
|
|
}
|
|
```
|
|
|
|
### `POST /ml/evaluate`
|
|
|
|
Vergleicht Modellvorhersagen mit Validierungsdaten und liefert MAE, RMSE und
|
|
Coverage. Der Request verwendet dasselbe Sample-Format wie `/ml/retrain`.
|
|
|
|
### `POST /ml/batch`
|
|
|
|
Batch-Vorhersage für mehrere Sensorwerte.
|
|
|
|
**Request**
|
|
```json
|
|
{
|
|
"requests": [
|
|
{
|
|
"modelId": "default",
|
|
"sensor_id": "sensor.kitchen",
|
|
"values": {"temperature": 21.0}
|
|
},
|
|
{
|
|
"modelId": "default",
|
|
"sensor_id": "sensor.bedroom",
|
|
"values": {"temperature": 18.5}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Antwort**
|
|
```json
|
|
{
|
|
"predictions": [
|
|
{
|
|
"model_id": "default",
|
|
"sensor_id": "sensor.kitchen",
|
|
"predictions": {"temperature": 21.4},
|
|
"confidence": 0.78,
|
|
"model_type": "statistical_baseline"
|
|
},
|
|
{
|
|
"model_id": "default",
|
|
"sensor_id": "sensor.bedroom",
|
|
"predictions": {"temperature": 18.3},
|
|
"confidence": 0.74,
|
|
"model_type": "statistical_baseline"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Fehlerfälle
|
|
|
|
- `404 Not Found`: Modell nicht registriert.
|
|
- `422 Unprocessable Content`: Sensor wird vom Modell nicht unterstützt oder Eingabe ist ungültig.
|
|
- `503 Service Unavailable`: Registry ist nicht initialisiert.
|
|
|
|
## Aktuator-zentrierte API
|
|
|
|
### `GET /v1/actuators/discovery`
|
|
|
|
Listet unterstützte Aktuatoren mit angereicherter HA-Metadatenbasis.
|
|
|
|
### `POST /v1/actuators`
|
|
|
|
Registriert einen Aktor. Das System ermittelt passende Messwerte und
|
|
Kontext-Entities vollständig automatisch, trainiert bei ausreichender Historie
|
|
ein Modell und liefert Zuordnung, Confidence, Evidenz und Lifecycle-Status zur
|
|
Diagnose zurück.
|
|
|
|
**Request**
|
|
```json
|
|
{
|
|
"actuator_entity_id": "light.abstellkammer",
|
|
"enabled": true
|
|
}
|
|
```
|
|
|
|
### `POST /v1/actuators/reconciliation/run`
|
|
|
|
Führt eine sichere globale Reconciliation aus. Die periodische Add-on-Schleife
|
|
ruft denselben idempotenten Ablauf auf, startet aber keine Services in Home
|
|
Assistant.
|
|
|
|
### `POST /v1/actuators/{actuator_entity_id}/evaluate`
|
|
|
|
Erstellt aus aktuellem Kontext eine neue Shadow- oder Aktiv-Vorhersage. Im
|
|
Shadow-Modus wird niemals geschaltet.
|
|
|
|
### `POST /v1/actuators/{actuator_entity_id}/activation`
|
|
|
|
```json
|
|
{"active": true}
|
|
```
|
|
|
|
Aktiviert autonomes Schalten erst nach ausreichendem Training und nur für
|
|
erlaubte Aktor-Domains. Mit `false` wird der Aktor sofort wieder in den
|
|
Shadow-Modus versetzt.
|
|
|
|
## Betrieb
|
|
|
|
Die produktive App lädt Artefakte aus `SILLYHOME_MODEL_STORE`. Aktor- und
|
|
Reconciliation-Zustände liegen atomisch in
|
|
`SILLYHOME_ACTUATOR_STORE`. Neue Artefakte werden über `/ml/retrain`,
|
|
`RetrainingService` oder den aktor-zentrierten Lifecycle registriert. Die API
|
|
sollte nur in einem vertrauenswürdigen Netz oder hinter einem
|
|
authentifizierenden Reverse Proxy erreichbar sein.
|
|
|
|
## Verweise
|
|
|
|
- `app/ml/predictor.py`
|
|
- `app/ml/retraining.py`
|
|
- `app/ml/registry/model_registry.py`
|
|
- `backend/routes/ml.py`
|