Leds and buttons events (#266)
Use events and commands to control custom onboard leds and buttons. Can be used to communicate with an external Python script via a WebSocket API running in a container alongside LVA.
This commit is contained in:
1 parent
e1770d071c
commit
2d460b6728
51 files changed
+9251
-117
No files matched your search
@@ -0,0 +1,144 @@
|
||||
---
|
||||
# Jabra Speak 410 – peripheral controller
|
||||
#
|
||||
# Runs alongside the linux-voice-assistant container.
|
||||
# Controls the Jabra Speak 410's LED ring and buttons via USB HID,
|
||||
# and optionally integrates with PipeWire for volume control and mute detection.
|
||||
#
|
||||
# Credit: https://github.com/machineonamission/lva-jabra-speak-410
|
||||
#
|
||||
# See hardware notes at the bottom of this file before first run.
|
||||
|
||||
services:
|
||||
jabra-peripheral:
|
||||
image: ghcr.io/machineonamission/lva-jabra-speak-410:main
|
||||
container_name: jabra-peripheral
|
||||
restart: unless-stopped
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# USB device access — required for HID LED and button control
|
||||
# -----------------------------------------------------------------------
|
||||
devices:
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# PipeWire socket — required for mute detection and optional volume control
|
||||
#
|
||||
# The mute detect bodge reads from the microphone stream via pw-record to
|
||||
# detect when the hardware mute engages (all-zero audio = hardware muted).
|
||||
# Without this, mute/unmute from the Jabra button will not work.
|
||||
#
|
||||
# Replace /run/user/1000 with your actual XDG_RUNTIME_DIR if different.
|
||||
# For the correct path run: echo $XDG_RUNTIME_DIR
|
||||
# -----------------------------------------------------------------------
|
||||
volumes:
|
||||
- /run/user/1000/pipewire-0:/run/user/1000/pipewire-0:ro
|
||||
- /run/user/1000/pulse:/run/user/1000/pulse:ro
|
||||
|
||||
group_add:
|
||||
- audio
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Environment variables
|
||||
# -----------------------------------------------------------------------
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
|
||||
# LVA peripheral API WebSocket URL.
|
||||
# If LVA runs on the same host with network_mode: host this default works.
|
||||
- LVA_WS_URL=ws://localhost:6055
|
||||
|
||||
# PipeWire runtime directory — must match the volume mount path above.
|
||||
- XDG_RUNTIME_DIR=/run/user/1000
|
||||
- PULSE_SERVER=unix:/run/user/1000/pulse/native
|
||||
|
||||
# PipeWire sink for volume control.
|
||||
# Leave as @DEFAULT_SINK@ or set to a specific sink name.
|
||||
# Find sink names with: wpctl status
|
||||
- PW_SINK=@DEFAULT_SINK@
|
||||
|
||||
# Volume control mode. Options:
|
||||
# pipewire – adjust PipeWire volume directly on button press
|
||||
# (recommended with LVA pipewire volume control PR #272)
|
||||
# lva – send volume_up / volume_down commands to LVA
|
||||
# (WARNING: may double-trigger if system also handles HID)
|
||||
# (unset) – ignore volume button presses entirely
|
||||
# - VOLUME_CONTROL=pipewire
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Network — host mode so "localhost" reaches the LVA container directly
|
||||
# -----------------------------------------------------------------------
|
||||
network_mode: host
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "pgrep", "-f", "main.py"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# HARDWARE NOTES
|
||||
# =============================================================================
|
||||
#
|
||||
# 1. USB ACCESS — udev rule (recommended)
|
||||
#
|
||||
# Add a udev rule on the HOST so the container can access the Jabra device
|
||||
# without needing additional privileges:
|
||||
#
|
||||
# sudo tee /etc/udev/rules.d/99-jabra.rules << 'EOF'
|
||||
# SUBSYSTEM=="usb", ATTR{idVendor}=="0b0e", MODE="0666", GROUP="plugdev"
|
||||
# EOF
|
||||
# sudo udevadm control --reload-rules
|
||||
# sudo udevadm trigger
|
||||
#
|
||||
# Verify the device is visible:
|
||||
# lsusb | grep 0b0e
|
||||
#
|
||||
# 2. PIPEWIRE — required for mute detection
|
||||
#
|
||||
# The Jabra Speak 410 does not expose its mute button state over HID when
|
||||
# not in an active call. As a workaround, the controller reads raw audio
|
||||
# from PipeWire and detects hardware mute by observing all-zero audio chunks
|
||||
# (digitally muted audio is impossible in real conditions).
|
||||
#
|
||||
# Expose the PipeWire socket from the host to the container as shown in the
|
||||
# volumes section above. See the LVA audio server documentation for the
|
||||
# full procedure:
|
||||
# https://github.com/OHF-Voice/linux-voice-assistant/blob/main/docs/install_audioserver.md
|
||||
#
|
||||
# If pw-record is not available inside the container, install wireplumber:
|
||||
# apt-get install wireplumber
|
||||
# (already included in the pre-built image)
|
||||
#
|
||||
# 3. VOLUME CONTROL
|
||||
#
|
||||
# The hidapi library takes full control of the USB HID interface, which
|
||||
# means external tools like alsa_volume_from_usb_hid will stop working
|
||||
# while this container is running.
|
||||
#
|
||||
# Set VOLUME_CONTROL=pipewire to handle volume buttons via wpctl.
|
||||
# Set VOLUME_CONTROL=lva to send volume commands to LVA instead.
|
||||
# Leave unset to ignore volume buttons entirely.
|
||||
#
|
||||
# Avoid VOLUME_CONTROL=lva if your system is also processing HID volume
|
||||
# events at the OS level — this will result in double volume changes.
|
||||
#
|
||||
# 4. MICROPHONE INPUT
|
||||
#
|
||||
# The Jabra Speak 410 enumerates as a standard USB audio device.
|
||||
# No driver install is required. Pass it to LVA via:
|
||||
#
|
||||
# --audio-input-device "Jabra SPEAK 410"
|
||||
#
|
||||
# Or in LVA's compose environment:
|
||||
# AUDIO_INPUT_DEVICE=Jabra SPEAK 410
|
||||
#
|
||||
# =============================================================================
|
||||
Reference in new issue
Block a user