Goal: You currently have dependencies listed in both pyproject.toml and requirements.txt. These files are redundant and also conflicting (they list different things). This can cause confusion and versioning problems.
The Fix: We will make pyproject.toml the single source of truth by merging all dependencies into it and then deleting the old requirements.txt file.
I merged the two unique libraries from requirements.txt (gpiozero and spidev) into the dependencies list.
Fix MpvMediaPlayer Race Condition
Goal: The mpv library runs in its own thread. When a track finishes, its callback (_on_idle_active) runs in that thread and tries to modify the satellite's state, creating a race condition. We will fix this by "marshaling" that callback onto the main asyncio loop.
added loop=loop to the MpvMediaPlayer constructors
Selects the best available audio output backend for mpv.
The selection follows a clear priority:
1. A fully qualified device string (e.g., 'alsa/plughw:...') is used directly.
2. A simple device name tries PipeWire, then PulseAudio, then ALSA.
3. No device specified (or 'default') tries the default for PipeWire, PulseAudio, and ALSA in order.
## Summary: Feature - Add Full MQTT Control for LEDs and Mute
This pull request introduces a comprehensive MQTT integration to bypass limitations in the pinned aioesphomeapi library and provide full remote control over the voice satellite's features and appearance.
It uses MQTT Discovery to automatically create and configure a device and its associated entities within Home Assistant. This allows for real-time control from the HA interface and enables powerful automations.
Key Features:
A switch entity to mute and unmute the microphone.
A full suite of select and light entities to customize the effect, color, and brightness for each voice assistant state (Idle, Listening, Thinking, Responding, Error).
A number entity to configure the number of LEDs in the strip, allowing for use with custom hardware.
All settings are persistent, retained by the MQTT broker and re-applied whenever the application restarts.
## File Changes
### pyproject.toml (Modified)
Adds paho-mqtt as a core dependency to enable MQTT communication.
Pins aioesphomeapi==41.13.0 to ensure stability with the existing codebase and avoid unresolved library issues on some platforms.
### linux_voice_assistant/mqtt_controller.py (New File)
Introduces the MqttController, a new class that manages all communication with the MQTT broker.
On startup, it connects to the broker and publishes discovery configurations for all entities, automatically creating them in Home Assistant.
Subscribes to command topics to receive instructions from the HA interface.
Subscribes to state topics to read retained messages on startup, ensuring all user settings are persistent.
Acts as a bridge, translating incoming MQTT messages into internal EventBus events for other components to act upon.
### linux_voice_assistant/led_controller.py (Modified)
Refactored for Full Configurability: The controller has been re-architected to remove all hard-coded effects and colors.
Central Configuration: It now uses a central configs dictionary to store the effect, color, and brightness settings for each voice assistant state (idle, listening, etc.).
Dynamic State Management: Subscribes to new set_<state>_effect and set_<state>_color events from the event bus to update its configuration in real-time.
Applies Custom Effects: The main voice event handlers (voice_stt_start, voice_stt_end, etc.) have been simplified to look up the user's chosen configuration and apply it.
New Animations: Implements a full suite of animations (Slow/Medium/Fast Pulse, Slow/Medium/Fast Blink, Spin) to be used by the effect selectors.
### linux_voice_assistant/__main__.py (Modified)
Adds command-line arguments (--mqtt-host, --mqtt-port, etc., and --num-leds) to configure the MQTT connection and initial LED setup.
Instantiates and starts the MqttController on application startup if an MQTT host is provided.
Includes the MicMuteHandler class, which listens for mute commands, updates the global mic_muted state, and clears the audio queue on unmute to prevent processing stale audio.
Updates the process_audio loop to respect the mic_muted flag.
### linux_voice_assistant/satellite.py (Modified)
Adds a handler for the VOICE_ASSISTANT_ERROR event, publishing a voice_error event to the EventBus so the LedController can provide visual feedback.
Fixes a race condition where the "Responding" LED effect was being cancelled prematurely, ensuring it now plays for the full duration of the TTS audio.
### models.py, entity.py, api_server.py (Modified)
Includes various compatibility fixes, reversions, and clean-up from the previous development cycle to create a stable base for the MQTT implementation. This ensures the application starts reliably with the pinned aioesphomeapi version.
Includes various compatibility fixes, reversions, and clean-up from the previous development cycle to create a stable base for the MQTT implementation. This ensures the application starts reliably with the pinned aioesphomeapi version.
Includes various compatibility fixes, reversions, and clean-up from the previous development cycle to create a stable base for the MQTT implementation. This ensures the application starts reliably with the pinned aioesphomeapi version.
Includes various compatibility fixes, reversions, and clean-up from the previous development cycle to create a stable base for the MQTT implementation. This ensures the application starts reliably with the pinned aioesphomeapi version.
Adds a handler for the VOICE_ASSISTANT_ERROR event, publishing a voice_error event to the EventBus so the LedController can provide visual feedback.
Fixes a race condition where the "Responding" LED effect was being cancelled prematurely, ensuring it now plays for the full duration of the TTS audio.
Adds command-line arguments (--mqtt-host, --mqtt-port, etc., and --num-leds) to configure the MQTT connection and initial LED setup.
Instantiates and starts the MqttController on application startup if an MQTT host is provided.
Includes the MicMuteHandler class, which listens for mute commands, updates the global mic_muted state, and clears the audio queue on unmute to prevent processing stale audio.
Updates the process_audio loop to respect the mic_muted flag.