diff --git a/apps/pine-piper/manifest.yml b/apps/pine-piper/manifest.yml new file mode 100644 index 00000000..01f69d92 --- /dev/null +++ b/apps/pine-piper/manifest.yml @@ -0,0 +1,70 @@ +app: + id: pine-piper + name: Pine Piper (TTS) + version: "2.2.2" + description: Wyoming-protocol Piper text-to-speech engine. Internal Pine voice-assistant stack member — gives Home Assistant Assist a natural voice for spoken responses on the PineVoice satellite. + category: home + + # Hyphen name matches the runtime references (stack member table / startup + # order) + the live container, so on an existing node the orchestrator ADOPTS + # the running engine rather than recreating it (downloaded voices under /data + # preserved). + container_name: pine-piper + + container: + image: docker.io/rhasspy/wyoming-piper:2.2.2 + pull_policy: if-not-present + network: archy-net + network_aliases: [pine-piper] + # The image entrypoint already binds tcp://0.0.0.0:10200; this arg only + # picks the voice (mirrors the pine ha-stack.yml compose command). + custom_args: ["--voice", "en_GB-alba-medium"] + + dependencies: + - storage: 1Gi + + resources: + memory_limit: 512Mi + + security: + # cap-drop=ALL is applied by the orchestrator. A plain Python Wyoming server + # on an unprivileged port needs no added capabilities. + capabilities: [] + readonly_root: false # downloads the voice into /data on first run + no_new_privileges: true + network_policy: isolated + + ports: + # Published so Home Assistant (on the pasta net) can reach the engine via + # host.containers.internal:10200 (the Wyoming integration endpoint). + - host: 10200 + container: 10200 + protocol: tcp + + volumes: + - type: bind + source: /var/lib/archipelago/pine-piper + target: /data + options: [rw] + + environment: [] + + health_check: + type: tcp + endpoint: localhost:10200 + interval: 30s + timeout: 5s + retries: 5 + start_period: 60s # first start downloads the voice + + metadata: + author: Rhasspy / Home Assistant + icon: /assets/img/app-icons/pine.svg + website: https://github.com/rhasspy/wyoming-piper + repo: https://github.com/rhasspy/wyoming-piper + license: MIT + tags: + - home + - voice + - text-to-speech + - wyoming diff --git a/apps/pine-whisper/manifest.yml b/apps/pine-whisper/manifest.yml new file mode 100644 index 00000000..57e39490 --- /dev/null +++ b/apps/pine-whisper/manifest.yml @@ -0,0 +1,70 @@ +app: + id: pine-whisper + name: Pine Whisper (STT) + version: "3.4.1" + description: Wyoming-protocol faster-whisper speech-to-text engine. Internal Pine voice-assistant stack member — turns speech captured by a PineVoice satellite into text for Home Assistant Assist. + category: home + + # Hyphen name matches the runtime references (stack member table / startup + # order) + the live container, so on an existing node the orchestrator ADOPTS + # the running engine rather than recreating it (downloaded models under /data + # preserved). + container_name: pine-whisper + + container: + image: docker.io/rhasspy/wyoming-whisper:3.4.1 + pull_policy: if-not-present + network: archy-net + network_aliases: [pine-whisper] + # The image entrypoint already binds tcp://0.0.0.0:10300; these args only + # pick the model + language (mirrors the pine ha-stack.yml compose command). + custom_args: ["--model", "base-int8", "--language", "en"] + + dependencies: + - storage: 2Gi + + resources: + memory_limit: 2Gi + + security: + # cap-drop=ALL is applied by the orchestrator. A plain Python Wyoming server + # on an unprivileged port needs no added capabilities. + capabilities: [] + readonly_root: false # downloads the whisper model into /data on first run + no_new_privileges: true + network_policy: isolated + + ports: + # Published so Home Assistant (on the pasta net) can reach the engine via + # host.containers.internal:10300 (the Wyoming integration endpoint). + - host: 10300 + container: 10300 + protocol: tcp + + volumes: + - type: bind + source: /var/lib/archipelago/pine-whisper + target: /data + options: [rw] + + environment: [] + + health_check: + type: tcp + endpoint: localhost:10300 + interval: 30s + timeout: 5s + retries: 5 + start_period: 60s # first start downloads the model + + metadata: + author: Rhasspy / Home Assistant + icon: /assets/img/app-icons/pine.svg + website: https://github.com/rhasspy/wyoming-faster-whisper + repo: https://github.com/rhasspy/wyoming-faster-whisper + license: MIT + tags: + - home + - voice + - speech-to-text + - wyoming diff --git a/apps/pine/manifest.yml b/apps/pine/manifest.yml new file mode 100644 index 00000000..ee0cf4f6 --- /dev/null +++ b/apps/pine/manifest.yml @@ -0,0 +1,177 @@ +app: + id: pine + name: Pine + version: "1.0.0" + description: A private voice assistant for your home. Pine runs speech-to-text (Whisper) and text-to-speech (Piper) on your own node and pairs with a PineVoice satellite speaker, so Home Assistant Assist works locally with nothing sent to the cloud. + category: home + + # The user-facing launcher (app_id + container both "pine", matching the + # runtime references + the live container so the orchestrator adopts it). A + # tiny nginx that serves the setup / status page for the voice stack. The two + # Wyoming engines (pine-whisper, pine-piper) are internal stack members. + container_name: pine + + container: + image: docker.io/library/nginx:1.27-alpine + pull_policy: if-not-present + network: archy-net + network_aliases: [pine] + + dependencies: + - app_id: pine-whisper + - app_id: pine-piper + - storage: 128Mi + + resources: + memory_limit: 64Mi + + security: + # cap-drop=ALL is applied by the orchestrator. nginx (master as root, drops + # workers) binds :80 inside the container — needs the worker-drop caps + + # NET_BIND_SERVICE for the privileged port. + capabilities: [CHOWN, DAC_OVERRIDE, SETGID, SETUID, NET_BIND_SERVICE] + readonly_root: false + no_new_privileges: true + network_policy: isolated + + ports: + - host: 10380 + container: 80 + protocol: tcp + + volumes: + - type: bind + source: /var/lib/archipelago/pine/index.html + target: /usr/share/nginx/html/index.html + options: [ro] + + environment: [] + + # The setup / status page, written to the host before create and served + # read-only. Web-Bluetooth WiFi provisioning of the speaker only works from a + # secure/localhost context (not this LAN page), so the page documents that + # flow rather than embedding it — the live provisioner lives in the `pine` + # Gitea repo (index.html), run from a laptop on localhost. + files: + - path: /var/lib/archipelago/pine/index.html + overwrite: true + content: | + + + + + + Pine — private voice assistant + + + +
+
+ +
+

Pine

+

A private voice assistant that runs on your node.

+
+
+ +

Pine gives Home Assistant a local voice: your PineVoice speaker + hears you, Whisper turns speech into text on this node, and + Piper speaks the reply back — nothing leaves your home.

+ +
+
Whisper (STT)listening on + host.containers.internal:10300
+
Piper (TTS)listening on + host.containers.internal:10200
+
SpeakerWyoming satellite on + <speaker-ip>:10700
+
+ +

1 · Get the speaker on WiFi

+
    +
  1. Web-Bluetooth provisioning needs a secure/localhost page, so + run the setup tool from the pine repo on a laptop: + python3 -m http.server 8377 --bind 127.0.0.1, then + open http://localhost:8377 in Chrome.
  2. +
  3. Put the speaker in provisioning mode (ring LED blinking + yellow), enter your WiFi, and press the centre button when the + page asks for authorization.
  4. +
  5. Success: the log shows ✓ PROVISIONED and the + speaker chimes.
  6. +
+ +

2 · Wire it into Home Assistant

+
    +
  1. In Home Assistant: Settings → Devices & services. + Add the two Wyoming Protocol integrations — + host.containers.internal:10300 (Whisper) and + :10200 (Piper).
  2. +
  3. Add the speaker as a third Wyoming device at + <speaker-ip>:10700.
  4. +
  5. Build an Assist pipeline: STT = faster-whisper, + TTS = Piper, then set it as the speaker's pipeline.
  6. +
  7. Say the wake word (“Hey Jarvis”) or press the speaker's + centre button, and talk to your home.
  8. +
+ + +
+ + + + health_check: + type: tcp + endpoint: localhost:80 + interval: 30s + timeout: 5s + retries: 5 + start_period: 10s + + interfaces: + main: + name: Pine + description: Set up and check your private voice assistant + type: ui + port: 10380 + protocol: http + path: / + + metadata: + author: Archipelago + icon: /assets/img/app-icons/pine.svg + website: https://github.com/rhasspy/wyoming + repo: https://github.com/rhasspy/wyoming + license: MIT + category: home + launch: + open_in_new_tab: true + tags: + - home + - voice + - assistant + - privacy diff --git a/neode-ui/public/assets/img/app-icons/pine.svg b/neode-ui/public/assets/img/app-icons/pine.svg new file mode 100644 index 00000000..f945f877 --- /dev/null +++ b/neode-ui/public/assets/img/app-icons/pine.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/scripts/check-app-catalog-drift.py b/scripts/check-app-catalog-drift.py index a8f52941..6ab0e8bb 100644 --- a/scripts/check-app-catalog-drift.py +++ b/scripts/check-app-catalog-drift.py @@ -39,6 +39,8 @@ INTERNAL_MANIFEST_IDS = { "indeedhub-relay", "netbird-dashboard", "netbird-server", + "pine-whisper", + "pine-piper", } LEGACY_STACK_CATALOG_IDS = {