
EchoMuse, Teil 1: Echo Dot ohne Alexa - die Infrastruktur
EchoMuse, Teil 1: Echo Dot ohne Alexa - die Infrastruktur
Ausgangslage
Bei mir liegen zwei Echo Dots der 2. Generation herum, Baujahr 2016, Codename „biscuit“. Mikrofone, Lautsprecher, LED-Ring und Tasten funktionieren einwandfrei - nur Alexa und ein Amazon-Konto will ich dafür nicht mehr. Das Ziel: die Dots als Sprachsatelliten für Home Assistant weiterverwenden.
Genau dafür gibt es EchoMuse von wilbowes. Die Entsperrung der Dots basiert auf amonet-biscuit von R0rt1z2.
So greifen die Teile ineinander:
- Echo Dot mit emOS: ein eigenes, schlankes Linux statt Amazons Android. Der Dot liefert Mikrofone, Lautsprecher, LED-Ring und Tasten.
- EchoMuse-Controller als Docker-Container auf meinem NUC: Wake-Word-Erkennung mit openWakeWord („Hey Jarvis“), Geräteverwaltung und ein Dashboard.
- Home Assistant auf einem Raspberry Pi 4: sieht jeden Dot als normalen ESPHome-Sprachsatelliten und übernimmt Spracherkennung, Verstehen und Sprachausgabe über die Assist-Pipeline.
- Traefik stellt das Dashboard per HTTPS bereit, nur im LAN.
Wichtig vorab: In Home Assistant muss nichts zusätzlich installiert werden. Die eingebaute ESPHome-Integration reicht.
Der Artikel ist in zwei Teile geteilt. In diesem geht es um alles, was stehen muss, bevor der erste Dot überhaupt angefasst wird. Teil 2 behandelt das Entsperren, Flashen und Provisionieren - mit Erfahrungen aus zwei Durchgängen.
Umsetzung
Home Assistant: Assist-Pipeline prüfen
Die einzige echte Voraussetzung auf HA-Seite ist eine funktionierende Assist-Pipeline. Geprüft habe ich das in drei Schritten.
Pipeline ansehen (Einstellungen → Sprachassistenten): Meine Pipeline heißt „Local Assistant“, Sprache Deutsch, Konversationsagent Home Assistant. Spracherkennung und Sprachausgabe laufen über Home Assistant Cloud (Österreichisches Deutsch, Stimme Jonas). Trotz des Namens geht Sprache damit über Nabu Casa. Für die Inbetriebnahme habe ich das bewusst so gelassen, weil die Cloud-Pipeline eine bekannte Größe ist. Was das für die Cloud-Unabhängigkeit bedeutet, steht am Ende von Teil 2.

Entitäten freigeben: Bei Assist stand „0 entities exposed“. Ohne freigegebene Entitäten versteht Assist zwar, kann aber nichts steuern. Ich habe zuerst nur ein, zwei Testlichter freigegeben.

Testen: zuerst per Text im Assist-Dialog („decke aus“ schaltet das Licht), dann per Sprache über das Mikrofon. Das Mikrofon im Browser funktioniert nur über HTTPS oder in der Companion-App.

Nebenbei gelernt: Kurze Befehle wie „decke ein“ werden teils falsch zugeordnet. Ganze Sätze („Schalte die Decke ein“) greifen zuverlässiger.
EchoMuse-Controller auf dem NUC
Der Controller läuft als fertiges Image aus der GitHub Container Registry. Abgelegt habe ich ihn neben meinen anderen Stacks unter ~/docker/echomuse, der Ordner data/ steht in der .gitignore.
curl -O https://raw.githubusercontent.com/wilbowes/EchoMuse/main/controller/docker-compose.deploy.yml
curl -o .env https://raw.githubusercontent.com/wilbowes/EchoMuse/main/controller/.env.example
sed -i 's/^SERVER_IP=.*/SERVER_IP=192.168.1.10/' .env
docker compose -f docker-compose.deploy.yml up -d
Drei Dinge sind dabei wichtig:
network_mode: hostist Pflicht. Der Controller kündigt sich per mDNS an und öffnet pro Dot einen eigenen ESPHome-Port. Hinter Docker-Port-Mapping funktioniert beides nicht.SERVER_IPexplizit setzen. Mein NUC hat viele Interfaces (Docker-Netze, WireGuard). Ohne feste IP kündigt der Controller womöglich die falsche an.- Ports kennen: 8768 für das Dashboard, 8767 und 8770 für die Verbindung zu den Dots (plain und TLS), ab 16001 ESPHome pro Dot, ab 17001 der Bluetooth-Proxy.
Beim ersten Start schreibt der Controller einen Setup-Token einmalig ins Log:
docker logs echomuse-controller
Beim ersten Abruf fehlte er bei mir, weil der Container noch Datenbank-Migrationen lief. Ein paar Sekunden warten, Log erneut lesen, dann ist er da.
Eine Warnung im Log ist harmlos: zeroconf meldet einen Fehler auf dem WireGuard-Interface (Required key not available). mDNS auf dem LAN-Interface läuft trotzdem.
Dashboard über Traefik, nur im LAN
Warum überhaupt Traefik? Der Provisioning-Wizard im Dashboard spricht per WebUSB mit dem Dot, und Chrome erlaubt WebUSB nur in einem sicheren Kontext - also HTTPS oder localhost. Deshalb kam das Dashboard hinter Traefik, bevor der erste Dot angeschlossen wurde.
Weil der Container im Host-Netz läuft, funktionieren Docker-Labels hier nicht wie gewohnt. Stattdessen habe ich einen Eintrag im bestehenden File-Provider (dynamic.yml) angelegt:
http:
routers:
echomuse:
rule: "Host(`echomuse.home.example.com`)"
entryPoints: [websecure]
tls:
certResolver: letsencrypt
service: echomuse
middlewares: [lan-only]
services:
echomuse:
loadBalancer:
servers:
- url: "http://192.168.1.10:8768"
middlewares:
lan-only:
ipAllowList:
sourceRange: ["192.168.1.0/24", "10.0.0.0/24"]
- Nur das Dashboard läuft über Traefik. Dots und Home Assistant verbinden sich direkt mit dem Controller.
lan-onlyist Pflicht: Das Dashboard enthält eine Root-Shell auf jeden Dot. Das gehört nicht ins Internet.- Das Zertifikat kommt per Let’s-Encrypt-DNS-Challenge bei Hostinger, DNS über meinen vorhandenen Wildcard-Eintrag
*.home. - Bei einer einzeln gemounteten Datei nach dem Bearbeiten sicherheitshalber
docker restart traefik.
Getestet habe ich vom Laptop aus. Anfragen vom NUC selbst kommen mit einer Docker-IP bei Traefik an und werden von lan-only korrekt abgewiesen - ein 403 dort ist also kein Fehler, sondern der Beweis, dass die Middleware greift.

Ergebnis
Die Assist-Pipeline schaltet per Text und Sprache, der Controller läuft im Host-Netz auf dem NUC, und das Dashboard ist per HTTPS aus dem LAN erreichbar - sonst nirgends. Damit sind alle Voraussetzungen für den Provisioning-Wizard erfüllt.
Stolpersteine
| Stolperstein | Symptom | Lösung |
|---|---|---|
| Keine Entitäten freigegeben | Assist versteht, steuert aber nichts | Entitäten bei Assist freigeben, klein anfangen |
| Setup-Token fehlt im Log | Log endet mitten in den Migrationen | einige Sekunden warten, Log erneut lesen |
| Labels bei Host-Netz-Container | Traefik erreicht den Dienst nicht zuverlässig | File-Provider mit Host-IP |
| Test vom NUC selbst | 403 von Traefik | vom Laptop testen, lan-only greift korrekt |
Fazit
Der eigentliche Aufwand dieses Teils steckt in drei Details: freigegebene Entitäten in Home Assistant, network_mode: host mit fester SERVER_IP und HTTPS fürs Dashboard wegen WebUSB. Wer das vorher sauber aufsetzt, kann sich beim Flashen ganz auf den Dot konzentrieren.
In Teil 2 geht es ans Gerät: Unlock mit amonet-biscuit, FireOS 6 in beide Slots, der Wizard auf emOS und die Einbindung in Home Assistant.