Commit Graph
148 Commits
Author SHA1 Message Date
imonlinux ada83bdfbb Update satellite.py
Re-added the self.state.satellite = self link, which is necessary for the main loop to be reachable from the audio thread.
2025-11-17 21:51:34 -08:00
imonlinux b62d07be7d Update event_bus.py
The EventHandler base class was modified to support the new decoupled __init__ pattern.
2025-11-17 21:50:53 -08:00
imonlinux f39df8a40a Update mqtt_controller.py
__init__ was completely rewritten to be decoupled. It now listens for mic_muted/mic_unmuted events to manage its own state instead of reading from ServerState.
2025-11-17 21:50:08 -08:00
imonlinux 37922351f6 Update led_controller.py
__init__ was completely rewritten to be decoupled. It now receives loop, event_bus, config, and preferences directly and no longer has any reference to ServerState.
2025-11-17 21:49:21 -08:00
imonlinux 64e2657824 Update models.py
ServerState is now a pure data container, no longer holding controller instances. The satellite reference was re-added, as it's required by the audio thread to call satellite.wakeup(). Fixed a TypeError by re-ordering non-default fields.
2025-11-17 21:48:08 -08:00
imonlinux 8c6df9b245 Update __main__.py
(Major change) main() function completely refactored into helpers. _init_controllers now handles decoupled initialization. _process_audio loop logic was fixed to correctly initialize wake words on startup.
2025-11-17 21:46:42 -08:00
imonlinux 52e5fb374e Update models.py
fixed wrong file uploaded
2025-11-17 20:37:46 -08:00
imonlinux 4d8f5c97b7 Update util.py
Removed the unused is_arm function
2025-11-17 20:22:54 -08:00
imonlinux c9be5fc026 Update satellite.py
Added all the logic for downloading external wake words
2025-11-17 20:22:05 -08:00
imonlinux a4fa7b8631 Update __main__.py
Replaced sounddevice with soundcard, removed the audio Queue, added the new download directory to the search path, and added the device listing arguments
2025-11-17 20:21:24 -08:00
imonlinux 005900b2ae Update models.py
Replaced sounddevice with soundcard, removed the audio Queue, added the new download directory to the search path, and added the device listing arguments
2025-11-17 20:19:30 -08:00
imonlinux 324881ca8b Update models.py
Removed audio_queue, added download_dir, and updated AvailableWakeWord to use the new libraries
2025-11-17 20:18:38 -08:00
imonlinux f033595649 Update config.py
Added download_dir and removed old oww_ model paths
2025-11-17 20:17:44 -08:00
imonlinux d2a9057dde Update config.py
Updated for the new soundcard library
2025-11-17 20:17:08 -08:00
imonlinux 82c02e9db9 Delete linux_voice_assistant/openwakeword.py 2025-11-17 20:12:33 -08:00
imonlinux 9bc2830a2d Delete linux_voice_assistant/microwakeword.py 2025-11-17 20:12:18 -08:00
imonlinux 3507074698 Delete linux_voice_assistant/wakeword.py 2025-11-17 20:12:04 -08:00
imonlinux 70e51148bf Update satellite.py
Fixed LED startup state bug.
2025-11-17 18:05:06 -08:00
imonlinux 9d27b016ca Update models.py
Fixed LED startup state bug.
2025-11-17 18:04:34 -08:00
imonlinux 77c2530657 Add config.json
This is the minimum configuration needed to start the LVA. 

{
  "app": {
    "name": "Linux Voice Assistant"
  }
}
2025-11-17 17:42:40 -08:00
imonlinux ebd74c1e80 Update __main__.py
Removed all argparse.add_argument() calls, except for the new --config flag.  The main() function now calls load_config_from_json() at startup.  All internal logic now references the config object (e.g., config.app.name) instead of the old args object.
2025-11-17 17:20:18 -08:00
imonlinux ce5418a27a Add linux_voice_assistant/config.json.example
Here is a complete config.json file showing all available options and explanations.
2025-11-17 17:18:36 -08:00
imonlinux 94e13f2c13 Add linux_voice_assistant/config.py
Adds new dataclasses (AppConfig, AudioConfig, LedConfig, etc.) to define the application's configuration structure. Includes a load_config_from_json() helper to parse the JSON file and provide default values for any omitted sections
2025-11-17 17:13:02 -08:00
imonlinux bd21743c49 Update mpv_player.py
Fix bug with audio backend detection. ALSA was not being detected correctly.
2025-11-17 16:46:15 -08:00
imonlinux 474ddfbaa4 Merge pull request #33 from imonlinux/normalize-satellite-state-machine
Normalize satellite state machine
2025-11-17 15:31:06 -08:00
imonlinux 208e7baec6 Merge pull request #32 from imonlinux/fix-mqtt-race-condition
Update mqtt_controller.py
2025-11-17 15:29:59 -08:00
imonlinux a1c1336ba2 Update led_controller.py
Update led_controller.py to subscribe to the new, normalized state events being published by satellite.py
2025-11-17 15:09:36 -08:00
imonlinux f1137232e0 Update satellite.py
This is the major change. All the _is_speaking, _run_finished, etc. flags are gone, replaced by a single self._state variable and a _set_state method. The logic is now much cleaner.
2025-11-17 15:08:10 -08:00
imonlinux 0f1ceefc5c Update models.py
Goal: satellite.py currently uses a set of boolean flags (_is_streaming_audio, _tts_played, _run_finished, _is_speaking) to figure out what it's doing. This is hard to read and easy to break. Replaced this with a clean, formal state machine (using an Enum). This makes the logic explicit and much easier to manage.

added the SatelliteState Enum at the top and removed the media_player_entity from ServerState as it's better managed by the satellite itself
2025-11-17 15:05:35 -08:00
imonlinux 2cdabdad30 Update mqtt_controller.py
Goal: We'll apply the exact same pattern to the MqttController. The paho-mqtt library runs its _on_message callback in a separate thread. We'll stop it from modifying state directly and instead schedule a new function to run on the main asyncio loop.

Here is the complete file. The key changes are:

The _on_message function is now tiny. It just gets the topic/payload and uses self.state.loop.call_soon_threadsafe to schedule a new function.

A new function _handle_message_on_loop contains all the logic that used to be in _on_message. This new function will run safely on the main asyncio loop, eliminating the race condition.
2025-11-17 14:44:41 -08:00
imonlinux 64c46fce2d Update mpv_player.py
added loop: asyncio.AbstractEventLoop to __init__ and used self.loop.call_threadsafe in _run_done_callback
2025-11-17 14:42:06 -08:00
imonlinux 943a8a0d5c Update __main__.py
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
2025-11-17 14:40:42 -08:00
imonlinux 61bf13ca98 Update api_server.py 2025-11-11 20:33:59 -08:00
imonlinux a74bf2ca1d Update api_server.py 2025-11-11 19:56:29 -08:00
imonlinux 8bef7e0f7a Add Support for NEOPixel via SPI 2025-10-15 20:34:12 -07:00
imonlinux d427d138e6 Add Support for NEOPixel via SPI 2025-10-15 20:33:24 -07:00
imonlinux ce4486896a Regression Bug for LED Event
Continued conversation listening was showing Idle effect instead of Listening.
2025-10-15 09:31:26 -07:00
imonlinux 31ea2762a3 Add support for PipeWire, PulseAudio, and Alsa
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.
2025-10-14 18:35:30 -07:00
imonlinux d98ed168a4 Simplify mpv_player.py Backend dection logic code cleanup 2025-10-14 15:45:26 -07:00
imonlinux 8cd9ffc0d5 Fix issue where Stop was not detected during playback 2025-10-14 15:44:22 -07:00
imonlinux 24c0d30540 Fix bug effecting Scenes 2025-10-12 20:24:14 -07:00
imonlinux c067f6de99 Fix bug in LED Color Entity that Affected Scenes 2025-10-12 19:53:00 -07:00
imonlinux 6077a31baa Bug Identified With GPIO LEDs (Grove) 2025-10-12 16:15:22 -07:00
imonlinux dbc371ce8f Bug Identified With GPIO LEDs (Grove) 2025-10-12 16:14:52 -07:00
imonlinux 798c371943 Bug Identified With GPIO LEDs (Grove) 2025-10-12 16:14:21 -07:00
imonlinux 7d4edbf369 Delete linux_voice_assistant/led_controller_marvin.py
Deprecated. All LED effects are configurable via MQTT controls.
2025-10-12 13:12:36 -07:00
imonlinux 6958b09f4d Delete linux_voice_assistant/led_controller_hal.py
Deprecated. All LED controls are configurable via MQTT.
2025-10-12 13:11:52 -07:00
imonlinux 1eef4ba917 Implement MQTT for Advanced LVA Controls
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.
2025-10-12 13:00:52 -07:00
imonlinux a435cc97e7 Implement MQTT for Advanced LVA Controls
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.
2025-10-12 12:59:42 -07:00
imonlinux 402a6d1855 Implement MQTT for Advanced LVA Controls
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.
2025-10-12 12:58:24 -07:00