Home Assistant Skill: umfassende README mit Step-by-Step-Anleitung
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# Home Assistant Alexa Skill
|
||||
|
||||
Ein privater, selbst gehosteter Alexa Custom Skill, mit dem du Home Assistant per Sprache abfragen kannst — z.B. Raumtemperaturen. Läuft als **Alexa-hosted Skill** (Node.js), keine eigene AWS-Infrastruktur nötig.
|
||||
|
||||
**Beispiel:**
|
||||
> "Alexa, frag Home Assistant wie warm es im Wohnzimmer ist"
|
||||
> → "Die Temperatur im Wohnzimmer beträgt 24.4 Grad."
|
||||
|
||||
---
|
||||
|
||||
## Inhalt dieses Repos
|
||||
|
||||
```
|
||||
home-assistant-skill/
|
||||
├── index.js # Lambda-Handler (Alexa-hosted Skill Code)
|
||||
├── package.json # Node-Abhängigkeiten (ask-sdk-core, dotenv, ...)
|
||||
├── .env.example # Vorlage für HA_URL / HA_TOKEN
|
||||
└── README.md # diese Anleitung
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Warum ein Custom Skill (statt nur die native Nabu-Casa-Integration)?
|
||||
|
||||
Home Assistant über Nabu Casa bietet bereits einen offiziellen **Smart Home Skill**, der native Sprachbefehle wie "Alexa, wie warm ist es im Wohnzimmer" *ohne* Skill-Namen unterstützt. Das funktioniert aber nur, wenn:
|
||||
- die Entität für Alexa freigegeben ist (Home Assistant → Einstellungen → Sprachassistenten → Alexa)
|
||||
- die Capability korrekt erkannt wird (`Alexa.TemperatureSensor`)
|
||||
- das Gerät in der Alexa-App einem Raum zugeordnet ist
|
||||
- Discovery erneut ausgeführt wurde
|
||||
|
||||
Falls das bei dir (z.B. bei komplexeren Geräten wie Homematic-Heizungsthermostaten) nicht zuverlässig funktioniert, ist ein **eigener Custom Skill** die zuverlässige Alternative — mit dem Nachteil, dass du immer den Invocation Name sagen musst (z.B. "frag Home Assistant ..."). Das ist eine feste Grammatikregel von Alexa für alle Custom Skills und lässt sich nicht umgehen — auch nicht mit Environment Variables oder Code-Tricks.
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Amazon Developer Account (Identitätsverifizierung ggf. erforderlich — Amazon fordert bei manchen Accounts einen Ausweis-Upload unter "Verify Identity")
|
||||
- Home Assistant Instanz, die per HTTPS von außen erreichbar ist (Nabu Casa Cloud, eigener Reverse Proxy oder Tunnel)
|
||||
- Long-Lived Access Token aus Home Assistant
|
||||
|
||||
---
|
||||
|
||||
## Schritt-für-Schritt-Anleitung
|
||||
|
||||
### 1. Skill in der Alexa Developer Console anlegen
|
||||
|
||||
1. Auf [developer.amazon.com](https://developer.amazon.com) einloggen → **Alexa** → **Alexa Skills Kit**
|
||||
2. **Create Skill**
|
||||
3. Namen vergeben (z.B. "HomeAssistantSkill")
|
||||
4. Locale: **German (DE)**
|
||||
5. Modell: **Custom**
|
||||
6. Hosting-Methode: **Alexa-hosted (Node.js)**
|
||||
7. Hosting-Region: **EU (Ireland)** (geringste Latenz für Nutzer in Europa)
|
||||
8. Template: **Start from Scratch**
|
||||
9. **Create Skill** klicken
|
||||
|
||||
### 2. Invocation Name festlegen
|
||||
|
||||
- Build-Tab → **Invocations** → Invocation Name setzen, z.B. `home assistant`
|
||||
- Damit sprichst du den Skill später an: *"Alexa, frag home assistant ..."*
|
||||
- Save klicken
|
||||
|
||||
### 3. Slot Type für Räume anlegen
|
||||
|
||||
- Build-Tab → **Slot Types** → **+ Add** → Namen `RoomList` → "Create custom slot type"
|
||||
- Für jeden Raum einen **Value** eintragen, plus eine saubere **ID** (klein, ohne Umlaute/Leerzeichen), z.B.:
|
||||
|
||||
| Value | ID |
|
||||
|---|---|
|
||||
| Diele | diele |
|
||||
| Gäste WC | gaeste_wc |
|
||||
| Badezimmer | badezimmer |
|
||||
| Balkon Hinten | balkon_hinten |
|
||||
| Balkon Vorne | balkon_vorne |
|
||||
| Kammer | kammer |
|
||||
| Kinderzimmer | kinderzimmer |
|
||||
| Schlafzimmer | schlafzimmer |
|
||||
| Wohnzimmer | wohnzimmer |
|
||||
| Küche | kueche |
|
||||
|
||||
Die ID ist wichtig: Der Code liest den sauberen, festen Wert über die Slot-Resolution aus — nicht den roh gesprochenen Text (der z.B. durch angehängte Wörter wie "ist" verfälscht sein kann).
|
||||
|
||||
- Save klicken
|
||||
|
||||
### 4. Intent anlegen: GetTemperatureIntent
|
||||
|
||||
- Build-Tab → **Intents** → den vom Template vorgegebenen `HelloWorldIntent` löschen
|
||||
- **+ Add Intent** → Name `GetTemperatureIntent` → "Create custom intent"
|
||||
- Sample Utterances hinzufügen, z.B.:
|
||||
```
|
||||
wie warm ist es im {Room}
|
||||
wie warm ist es in der {Room}
|
||||
wie ist die temperatur im {Room}
|
||||
wie ist die temperatur in der {Room}
|
||||
temperatur im {Room}
|
||||
```
|
||||
- Beim ersten Eintippen von `{Room}` erscheint ein Popup: "Create a new slot" → **Add** klicken
|
||||
- Danach im Bereich **Intent Slots** beim Slot `Room` als **Slot Type** `RoomList` auswählen
|
||||
- Save klicken
|
||||
|
||||
> Die Standard-Intents `AMAZON.CancelIntent`, `AMAZON.HelpIntent`, `AMAZON.StopIntent`, `AMAZON.NavigateHomeIntent` und `AMAZON.FallbackIntent` bleiben unverändert — die sind Pflicht und werden im Code bereits gehandhabt.
|
||||
|
||||
### 5. Modell bauen
|
||||
|
||||
- Oben rechts **Build Skill** klicken (dauert ca. 1 Minute)
|
||||
- **Wichtig:** Nach *jeder* Änderung an Utterances/Intents/Slots muss neu gebaut werden — sonst bleiben Änderungen im Simulator/auf dem Gerät unwirksam.
|
||||
|
||||
### 6. Long-Lived Access Token in Home Assistant erstellen
|
||||
|
||||
- In Home Assistant: Profil (unten links) → ganz nach unten scrollen zu **"Long-lived access tokens"**
|
||||
- **Token erstellen** → Namen vergeben (z.B. "Alexa Skill") → Token **sofort kopieren** (wird nur einmal angezeigt)
|
||||
|
||||
### 7. Code einrichten
|
||||
|
||||
- Im Skill: Tab **Code**
|
||||
- `index.js` Inhalt durch den Code aus diesem Repo ersetzen (`home-assistant-skill/index.js`)
|
||||
- `package.json` Inhalt durch die Version aus diesem Repo ersetzen (enthält zusätzlich `dotenv`)
|
||||
- Neue Datei `.env` anlegen (New File → Name `.env`, im `lambda`-Ordner, gleiche Ebene wie `index.js`) und Inhalt aus `.env.example` übernehmen, mit deinen echten Werten:
|
||||
```
|
||||
HA_URL=https://deine-ha-domain.de
|
||||
HA_TOKEN=dein-long-lived-access-token
|
||||
```
|
||||
|
||||
> **Hinweis:** Alexa-hosted Skills bieten *keine* Environment-Variables-Oberfläche in der Konsole (im Gegensatz zu selbst verwalteten AWS-Lambda-Funktionen). Die `.env`-Datei ist daher die praktikabelste Lösung, um Secrets wenigstens von der Programmlogik getrennt zu halten. Sicherheitsrelevant bleibt sie trotzdem — nicht öffentlich teilen oder in ein öffentliches Repo pushen (dieses Gitea-Repo ist privat, das reicht für den Zweck).
|
||||
|
||||
- Im Raum-Mapping in `index.js` die Entity-IDs an deine echten Home-Assistant-Entitäten anpassen:
|
||||
```js
|
||||
const roomToClimateEntity = {
|
||||
badezimmer: 'climate.badezimmer_heizungssteuerung',
|
||||
kinderzimmer: 'climate.kinderzimmer_heizungssteuerung',
|
||||
kueche: 'climate.kueche_heizungssteuerung',
|
||||
schlafzimmer: 'climate.schlafzimmer_heizungssteuerung',
|
||||
wohnzimmer: 'climate.wohnzimmer_heizungssteuerung',
|
||||
};
|
||||
```
|
||||
Entity-IDs findest du in Home Assistant unter **Entwicklerwerkzeuge → Zustände** (Filter z.B. nach `climate.*`).
|
||||
|
||||
- **Save** → **Deploy** klicken
|
||||
|
||||
### 8. Testen
|
||||
|
||||
- Tab **Test** → Skill-Testing auf **Development** stellen
|
||||
- Im Simulator eintippen oder sprechen:
|
||||
```
|
||||
frag home assistant wie warm es im wohnzimmer ist
|
||||
```
|
||||
- Bei Erfolg antwortet der Simulator mit der aktuellen Temperatur
|
||||
- Sobald es im Simulator funktioniert, ist der Skill automatisch auch auf allen Echo-Geräten verfügbar, die mit demselben Amazon-Konto verknüpft sind — keine separate Veröffentlichung nötig
|
||||
|
||||
---
|
||||
|
||||
## Fehlersuche
|
||||
|
||||
- **Fehlermeldung im Simulator:** JSON Output rechts prüfen — zeigt meist den genauen Fehler (z.B. HTTP-Statuscode von Home Assistant)
|
||||
- **"Ich konnte keine Verbindung herstellen":** Prüfen, ob `HA_URL` korrekt ist (kein Pfad, kein abschließender Slash) und ob Home Assistant tatsächlich von außen per HTTPS erreichbar ist
|
||||
- **"Ich kenne den Raum ... nicht":** Slot-Erkennung hat nicht gegriffen — meist hilft eine zusätzliche Sample Utterance mit der genauen Formulierung, die genutzt wurde, plus erneutes "Build Skill"
|
||||
- **Ausführlichere Logs:** Code-Tab → **CloudWatch Logs** (führt zu den AWS-Logs der Lambda-Funktion)
|
||||
|
||||
---
|
||||
|
||||
## Offene Erweiterung (zurückgestellt)
|
||||
|
||||
- `GetPowerUsageIntent` für Stromverbrauchs-Abfragen — bisher nicht implementiert, kann nach demselben Muster wie `GetTemperatureIntent` ergänzt werden (neuer Intent + neuer Handler in `index.js`, passende `sensor.*`-Entity in Home Assistant).
|
||||
Reference in New Issue
Block a user