diff --git a/.dockerignore b/.dockerignore index 25eeda1..a214bb5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,16 @@ * !requirements.txt +!requirements_audio_enhancement.txt +!requirements_vad.txt !MANIFEST.in !setup.py !script/setup !script/run +!script/run_2mic +!script/run_4mic !wyoming_satellite/*.py !wyoming_satellite/utils !wyoming_satellite/VERSION !docker/run !sounds/*.wav +!examples/* diff --git a/.github/workflows/docker-build-nightly.yml b/.github/workflows/docker-build-nightly.yml new file mode 100644 index 0000000..a0d28ae --- /dev/null +++ b/.github/workflows/docker-build-nightly.yml @@ -0,0 +1,49 @@ +--- +name: Build and publish the voice sattelite docker image + +on: + push: + branches: + - "master" + +env: + REGISTRY: ghcr.io + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + attestations: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Log in to the Container registry + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ github.token }} + # Build Docker Images (amd64 and arm64) + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push Docker image + id: push + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 + with: + context: . + platforms: linux/amd64,linux/aarch64 + push: true + tags: ${{ env.REGISTRY }}/${{ github.repository }}:nightly + labels: "nightly" + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1.4.4 + with: + subject-name: ${{ env.REGISTRY }}/${{ github.repository }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/.github/workflows/docker-build-release.yml b/.github/workflows/docker-build-release.yml new file mode 100644 index 0000000..9f6ccea --- /dev/null +++ b/.github/workflows/docker-build-release.yml @@ -0,0 +1,61 @@ +--- +name: Build and publish the voice sattelite stable docker image + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" # For releases, e.g. v1.2.0 + - "v[0-9]+.[0-9]+.[0-9]+-[a-zA-Z0-9]+" # For prereleases, e.g. v1.3.0-alpha1 + +env: + REGISTRY: ghcr.io + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + attestations: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Log in to the Container registry + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ github.token }} + # Build Docker Images (amd64 and arm64) + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + with: + images: ${{ env.REGISTRY }}/${{ github.repository }} + # E.g. tag v1.2.0 produces 3 tags: '1.2.0', '1.2', and 'latest' + # https://github.com/docker/metadata-action?tab=readme-ov-file#semver + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + - name: Build and push Docker image + id: push + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 + with: + context: . + platforms: linux/amd64,linux/aarch64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ github.repository }} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true +... diff --git a/Dockerfile b/Dockerfile index 1700442..67d972e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,20 +4,35 @@ ENV LANG C.UTF-8 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ - apt-get install --yes --no-install-recommends avahi-utils + apt-get install --yes --no-install-recommends avahi-utils alsa-utils pulseaudio-utils pipewire-bin build-essential +# set workdir WORKDIR /app +# copy content for voice COPY sounds/ ./sounds/ COPY script/setup ./script/ -COPY setup.py requirements.txt MANIFEST.in ./ +COPY script/run ./script/ +COPY script/run_2mic ./script/ +COPY script/run_4mic ./script/ +COPY setup.py requirements.txt requirements_audio_enhancement.txt requirements_vad.txt MANIFEST.in ./ COPY wyoming_satellite/ ./wyoming_satellite/ +COPY docker/run ./ -RUN script/setup +# copy content for led +COPY examples/ ./examples/ -COPY script/run ./script/ -COPY docker/run ./ +# run installation +RUN python3 -m venv .venv +RUN .venv/bin/pip3 install --upgrade pip +RUN .venv/bin/pip3 install --upgrade wheel setuptools +RUN .venv/bin/pip3 install --extra-index-url 'https://www.piwheels.org/simple' -f 'https://synesthesiam.github.io/prebuilt-apps/' -r requirements.txt -r requirements_audio_enhancement.txt -r requirements_vad.txt -r examples/requirements.txt +#RUN .venv/bin/pip3 install 'pixel-ring' -EXPOSE 10700 +# set port for voice and led +EXPOSE 10700 10500 +# set start script +# add parameters in docker ENTRYPOINT ["/app/run"] +#ENTRYPOINT ["/app/script/run_2mic" "--uri" "tcp://0.0.0.0:10500"] for led diff --git a/docker-compose.yml b/docker-compose.yml index 664d016..fcc0273 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,38 +1,88 @@ -version: "3.8" +--- +networks: + default: # default network for this project + + services: - microphone: - image: "rhasspy/wyoming-mic-external" - ports: - - "10600:10600" + satellite: + # satellite for homeassistant - nabucasa - whyoming voice + container_name: satellite + image: "ghcr.io/florian-asche/pi-voice-assistant:nightly" + restart: unless-stopped + network_mode: "host" devices: - /dev/snd:/dev/snd + - /dev/bus/usb group_add: - audio + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro command: - - "--device" - - "sysdefault" - "--debug" - playback: - image: "rhasspy/wyoming-snd-external" - ports: - - "10601:10601" + - "--name" + - "satellite-wohnzimmer" + - "--vad" + #- "--vad-buffer-seconds" + #- "4" + - "--mic-auto-gain" + - "5" + - "--mic-noise-suppression" + - "2" + #- "--wake-refractory-seconds" + #- "3" + - "--mic-command" + - "arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t raw" + - "--snd-command" + - "aplay -D plughw:CARD=seeed2micvoicec,DEV=0 -r 22050 -c 1 -f S16_LE -t raw" + - "--wake-uri" + - "tcp://127.0.0.1:10400" + - "--wake-word-name" + - "hey_jarvis" + - "--event-uri" + - "tcp://127.0.0.1:10500" + depends_on: + - ledcontrol + - openwakeword + + # Control 2mic_hat led + ledcontrol: + container_name: ledcontrol + image: "ghcr.io/florian-asche/pi-voice-assistant:nightly" + restart: unless-stopped + network_mode: "host" + entrypoint: /app/script/run_2mic devices: - - /dev/snd:/dev/snd - group_add: - - audio + - /dev/gpiomem:/dev/gpiomem + - /dev/spidev0.0:/dev/spidev0.0 + - /dev/spidev0.1:/dev/spidev0.1 + #group_add: + # - audio + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro command: - - "--device" - - "sysdefault" - - "--debug" - satellite: - image: "rhasspy/wyoming-satellite" - ports: - - "10700:10700" - command: - - "--name" - - "my satellite" - - "--mic-uri" - - "tcp://microphone:10600" - - "--snd-uri" - - "tcp://playback:10601" - "--debug" + - "--uri" + - "tcp://0.0.0.0:10500" + + # Wake word detection + openwakeword: + container_name: openwakeword + image: rhasspy/wyoming-openwakeword + restart: unless-stopped + #user: 1001:1001 + network_mode: "host" + volumes: + - wakeword_data:/data + - wakeword_custom:/custom + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + environment: + - TZ=Europe/Berlin + command: "--preload-model 'hey_jarvis' --custom-model-dir /custom --threshold 0.3 --trigger-level 1" + + +volumes: + wakeword_data: + wakeword_custom: diff --git a/examples/requirements.txt b/examples/requirements.txt new file mode 100644 index 0000000..0ae925d --- /dev/null +++ b/examples/requirements.txt @@ -0,0 +1,4 @@ +gpiozero==2.0.1 +spidev==3.6 +pigpio==1.78 +RPi.GPIO==0.7.1