Add docker

This commit is contained in:
Michael Hansen
2023-12-04 15:56:56 -06:00
parent c49f5e9c5f
commit 07bebb8f7a
8 changed files with 105 additions and 8 deletions
+8
View File
@@ -0,0 +1,8 @@
*
!requirements.txt
!MANIFEST.in
!setup.py
!script/setup
!script/run
!wyoming_satellite/*.py
!docker/run
+22
View File
@@ -0,0 +1,22 @@
FROM python:3.11-slim-bookworm
ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install --yes --no-install-recommends avahi-utils
WORKDIR /app
COPY script/setup ./script/
COPY setup.py requirements.txt MANIFEST.in ./
COPY wyoming_satellite/ ./wyoming_satellite/
RUN script/setup
COPY script/run ./script/
COPY docker/run ./
EXPOSE 10700
ENTRYPOINT ["/app/run"]
+38
View File
@@ -0,0 +1,38 @@
version: "3.8"
services:
microphone:
image: "rhasspy/wyoming-mic-external"
ports:
- "10600:10600"
devices:
- /dev/snd:/dev/snd
group_add:
- audio
command:
- "--device"
- "sysdefault"
- "--debug"
playback:
image: "rhasspy/wyoming-snd-external"
ports:
- "10601:10601"
devices:
- /dev/snd:/dev/snd
group_add:
- audio
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"
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
/app/script/run \
--uri tcp://0.0.0.0:10700 "$@"
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
docker buildx build . \
-t 'rhasspy/wyoming-satellite' "$@"
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
docker run \
-it \
-p 10700:10700 \
--device /dev/snd \
'rhasspy/wyoming-satellite' "$@"
+3 -4
View File
@@ -5,7 +5,6 @@ import setuptools
from setuptools import setup from setuptools import setup
this_dir = Path(__file__).parent this_dir = Path(__file__).parent
module_dir = this_dir / "wyoming_handle_external"
requirements = [] requirements = []
requirements_path = this_dir / "requirements.txt" requirements_path = this_dir / "requirements.txt"
@@ -19,8 +18,8 @@ if requirements_path.is_file():
setup( setup(
name="wyoming_handle_external", name="wyoming_handle_external",
version="1.0.0", version="1.0.0",
description="Wyoming server for external intent handling", description="Wyoming server for remote voice satellite",
url="http://github.com/rhasspy/wyoming-handle-external", url="http://github.com/rhasspy/wyoming-satellite",
author="Michael Hansen", author="Michael Hansen",
author_email="mike@rhasspy.org", author_email="mike@rhasspy.org",
packages=setuptools.find_packages(), packages=setuptools.find_packages(),
@@ -35,5 +34,5 @@ setup(
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",
], ],
keywords="rhasspy wyoming intent handle", keywords="rhasspy wyoming satellite",
) )
+22 -4
View File
@@ -3,12 +3,13 @@ import argparse
import asyncio import asyncio
import logging import logging
import time import time
import uuid
from enum import Enum from enum import Enum
from functools import partial from functools import partial
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from wyoming.asr import Transcript from wyoming.asr import Transcript, Transcribe
from wyoming.audio import AudioChunk, AudioStart, AudioStop from wyoming.audio import AudioChunk, AudioStart, AudioStop
from wyoming.client import AsyncClient from wyoming.client import AsyncClient
from wyoming.event import Event from wyoming.event import Event
@@ -59,7 +60,7 @@ async def main() -> None:
) )
parser.add_argument( parser.add_argument(
"--zeroconf-name", "--zeroconf-name",
help="Name used for zeroconf discovery (default: satellite name)", help="Name used for zeroconf discovery (default: MAC from uuid.getnode)",
) )
# #
parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") parser.add_argument("--debug", action="store_true", help="Log DEBUG messages")
@@ -86,13 +87,16 @@ async def main() -> None:
if (not args.no_zeroconf) and isinstance(server, AsyncTcpServer): if (not args.no_zeroconf) and isinstance(server, AsyncTcpServer):
from wyoming.zeroconf import register_server from wyoming.zeroconf import register_server
if not args.zeroconf_name:
args.zeroconf_name = get_mac_address()
tcp_server: AsyncTcpServer = server tcp_server: AsyncTcpServer = server
await register_server( await register_server(
name=args.zeroconf_name or args.name, name=args.zeroconf_name,
port=tcp_server.port, port=tcp_server.port,
host=tcp_server.host, host=tcp_server.host,
) )
_LOGGER.debug("Zeroconf discovery enabled") _LOGGER.debug("Zeroconf discovery enabled (name=%s)", args.zeroconf_name)
try: try:
await server.run(partial(SatelliteEventHandler, wyoming_info, args)) await server.run(partial(SatelliteEventHandler, wyoming_info, args))
@@ -195,6 +199,7 @@ class SatelliteEventHandler(AsyncEventHandler):
elif ( elif (
Detect.is_type(event.type) Detect.is_type(event.type)
or Detection.is_type(event.type) or Detection.is_type(event.type)
or Transcribe.is_type(event.type)
or VoiceStarted.is_type(event.type) or VoiceStarted.is_type(event.type)
or VoiceStopped.is_type(event.type) or VoiceStopped.is_type(event.type)
or Synthesize.is_type(event.type) or Synthesize.is_type(event.type)
@@ -202,6 +207,7 @@ class SatelliteEventHandler(AsyncEventHandler):
# Other client events: # Other client events:
# - Detect for start of wake word detection # - Detect for start of wake word detection
# - Detection for when wake word is detected # - Detection for when wake word is detected
# - Transcribe for when STT starts
# - VoiceStarted/VoiceStopped for when user starts/stops speaking # - VoiceStarted/VoiceStopped for when user starts/stops speaking
# - Synthesize for TTS text # - Synthesize for TTS text
await self.forward_event(event) await self.forward_event(event)
@@ -322,6 +328,18 @@ class SatelliteEventHandler(AsyncEventHandler):
self.is_running = False self.is_running = False
# -----------------------------------------------------------------------------
def get_mac_address() -> str:
"""Return MAC address formatted as hex with no colons."""
return "".join(
["{:02x}".format((uuid.getnode() >> ele) & 0xFF) for ele in range(0, 8 * 6, 8)][
::-1
]
)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
if __name__ == "__main__": if __name__ == "__main__":