Commit Graph
115 Commits
Author SHA1 Message Date
litinoveweedleandFlorian Asche 201896196f fix Respeaker USB Mic Array v2 LEDs (#357)
Fix ReSpeaker USB LED control and suppress stale peripheral disconnect replay

---------

Co-authored-by: Florian Asche <github@florian-asche.de>
2026-07-21 19:16:10 +03:00
Willian WangandFlorian Asche a66c0e4f28 feat: add --listen-during-wake-sound argument (#273)
* feat: add --listen-during-wake-sound argument

---------

Co-authored-by: Florian Asche <github@florian-asche.de>
2026-07-18 19:16:11 +02:00
Omar Amin 4a0695ab57 Switch between MWW/OWW models from the UI (#348)
This PR adds the ability to select microWakeWord/openWakeWord models using the wake word dropdown selection via the HA device page at any time without the need for restarting the app/container to change the wake word path.
2026-07-16 03:57:51 +03:00
Omar Amin 2c9c1d2b8a Fix lint_mypy (#352)
* Add type ignore for stop_word attribute assignment

Added type ignore comment for stop_word attribute.

* Refactor exception handling in disconnect process

Updated exception handling to use pylint directive for broad exceptions.

* Fix callback lambda for broadcasting state
2026-07-16 03:38:40 +03:00
d811ae75d4 Broadcast entity state to all API clients; don't desync on a second connection (#329)
The ESPHome API server delivered asynchronous entity-state changes to a single
connection (the entity's `server`), which every new connection reassigns. A
second API client — a diagnostic tool, a second dashboard, or Home Assistant's
own overlapping reconnect — therefore stole state delivery, leaving Home
Assistant stuck on a stale state (e.g. `media_player` showing `playing` after
playback had finished). `connection_lost` also stopped the shared music/TTS
players for *any* dropped connection.

- models.py: add a per-server connection registry and a `broadcast()` helper.
- satellite.py: register/deregister connections in connection_made/_lost; only
  stop shared playback when the last client disconnects; handle the standard
  `SubscribeStatesRequest` by replaying current entity state to the subscriber.
- entity.py: push playback-completion state via broadcast to all clients.

Co-authored-by: Omar Amin <65174210+omaramin-2000@users.noreply.github.com>
Co-authored-by: Florian Asche <github@florian-asche.de>
2026-07-15 19:11:54 +02:00
Florian Asche 2ccb1fb597 perf(player): limit cache to 32 MiB (#309)
* Update libmpv initialization to use demuxer_max_bytes and cache_secs
instead of the deprecated cache-size property. This ensures more
predictable memory usage and better buffering behavior during
playback.
2026-07-15 18:21:58 +02:00
Omar Amin 2d460b6728 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.
2026-07-03 19:58:45 +03:00
Omar Amin 1d84fa0898 Add delay to continue conversation before listening (#342)
Add a configurable amount of delay (defaulting to 0.5s) after the TTS playback is finished to avoid the mic to capture the end of response during start/continue conversation.

Fixes #313
2026-06-19 22:47:01 +03:00
Omar Amin eb29a00386 Enable dual audio input channel (#334)
This PR adds the ability to choose the microphone stream that works best with a particular STT engine using the new dual audio input channel feature.
2026-06-19 02:46:02 +03:00
aryanhasgithub ec70b3b58d Add volume arg to parser (#335)
This PR adds the mic volume to the arg parser and makes the value range from 1-100
2026-06-07 18:15:05 +03:00
Omar Amin 3ea32895ee Wake word sensitivity (#207)
## Summary
- Introduces configurable wake word and stop word sensitivity
- Adds UI-controllable thresholds for wake word detection
- Refactors wake word loading and handling logic
- Improves audio preprocessing and runtime behavior

## Key Features
- Per-wake-word sensitivity configuration (Wake Word 1 & 2)
- Configurable stop word sensitivity
- Fine-grained numeric control (0.0 – 1.0, step 0.001)
- Sensitivity values exposed as Number Entities for Home Assistant
- Persistent storage of user-defined sensitivity values

## Wake Word Handling
- Support for model-specific default thresholds (`probability_cutoff`)
- Automatic fallback to defaults if no user value is set
- Separate thresholds for:
  - Wake Word 1
  - Wake Word 2
  - Stop Word
- Unified handling for MicroWakeWord and OpenWakeWord models

## UI / API Integration
- Adds new Home Assistant entities:
  - `WakeWord1SensitivityNumberEntity`
  - `WakeWord2SensitivityNumberEntity`
  - `StopWordSensitivityNumberEntity`
- Entities support:
  - Live updates
  - Persistence via preferences
  - Synchronization with runtime state
- Pushes updated values to Home Assistant on startup

## Refactoring
- Extracted wake word logic into `wake_word.py`
  - Model discovery
  - Model loading
  - Stop word handling
- Simplified `__main__.py` by delegating wake word responsibilities
- Improved separation between configuration and runtime state

## Additional Changes
- Improved debug logging across initialization and runtime

## Impact
- Enables fine-tuning of wake word detection accuracy
- Reduces false positives and missed triggers
- Improves usability via UI-based configuration
- Provides better flexibility across different environments and microphones
2026-04-21 02:04:11 +02:00
Omar Amin 4c9d92f499 Fix audio cuts and playback issues (#296)
Increase the audio-buffer seconds to initialise the sink stream.
2026-04-17 18:43:32 +02:00
Omar Amin c284806b73 Add the ability to control microphone volume (#287)
Control microphone volume via UI in device page. Set to the maximum by default and saved in preferences to restore upon restarts.
2026-04-10 01:33:34 +02:00
aryanhasgithub 4ee7bb04bc Add support for WebRTC Auto Gain and Noise Suppression (#250)
## WebRTC Auto Gain & Noise Suppression
 
This PR adds support for WebRTC Auto Gain and Noise Suppression as previously implemented in the Wyoming Satellite project.
 
### What's New
 
Two new entities have been created a number slider for gain and another one for noise suppression. The processing happens inside of the `webrtc.py` file and is implemented in the `__main__.py` file's `process_audio` function. The slider for gain has a limit of 0-31 and noise suppression has a limit of 0-4.
 
The Auto Gain and Noise Suppression persist through restarts and are saved as preferences. The values are dynamically chnged without needing a restart.
 
CLI flags called `--mic-auto-gain` and `--mic-noise-suppression` have also been added.
 
>  When both values are 0, WebRTC processing is bypassed entirely with no performance overhead.

Closes #25 
 
### Testing
 
When saving the audio recorded by LVA there is a noticeable increase. The following two files have been recorded with similar audio being played through them with these results (Gain-31 and NS-4):
 
| Metric | With AGC+NS | Without |
|---|---|---|
| Max amplitude | 0.329 | 0.054 |
| RMS amplitude | 0.008905 | 0.002862 |
| Volume adjustment needed | 3.034x | 13.479x |
| Rough frequency | 916 Hz | 705 Hz |
2026-04-09 00:43:11 +02:00
Florian Asche 341e3dcb9c Output only satellite - part 2 (#278)
Introduce a new `--output-only` command-line flag and corresponding `ENABLE_OUTPUT_ONLY` environment variable. This allows users to run the assistant in output-only mode, where it only supports announcements. The change includes updates to configuration examples, documentation, and the Docker entrypoint script.
2026-03-31 01:57:47 +02:00
JaminandFlorian Asche 7732be0de8 Output only satellite (#182)
Output only satellite for nodes with only speakers and no microphone.
Supports announcements and playing media only.

---------

Co-authored-by: Florian Asche <github@florian-asche.de>
2026-03-31 01:56:16 +02:00
Omar Amin 88fb2c5a49 Start listening after stopping ringing timer using wake word (#275)
Wake-up after stopping ringing timer using wake words such as "Okay Nabu", "Hey Jarvis" rather than "Stop" to get another command instead of the need to repeat the wake word.
2026-03-31 00:11:25 +02:00
Martin WeineltandFlorian Asche 9067648c87 Expose linux-voice-assistant console script (#268)
Co-authored-by: Florian Asche <github@florian-asche.de>
2026-03-30 21:04:01 +02:00
Omar Amin 412035e6b2 Fix lint formatting (#262) 2026-03-26 14:54:40 +02:00
Omar Amin 4194aa42ec Add maximum seconds for ringing timer (#261)
Auto stop ringing timer if the determined time (default 15 mins) has passed without manually stopping. This max time can be modified using the command `--timer-max-ring-seconds`.
2026-03-25 01:46:53 +02:00
Vlad Gaevsky ede3785539 Add debug logging for stop word detection (#257) 2026-03-23 16:35:06 +01:00
Vlad GaevskyandOmar Amin 96fd54a008 Fix double _tts_finished() call when stop word interrupts TTS (#256)
tts_player.stop() already invokes its done_callback which is
_tts_finished(), so the explicit self._tts_finished() call immediately
after was a duplicate. This caused double 'Unducking music' and double
'TTS response finished' log entries on every stop-word-triggered stop.

Also move _pipeline_active = False inside the 'if not self._tts_played'
branch in VOICE_ASSISTANT_RUN_END, so it is not cleared while TTS is
still playing.

Co-authored-by: Omar Amin <65174210+omaramin-2000@users.noreply.github.com>
2026-03-23 16:24:38 +01:00
NP v/d Spek 8bb118b411 Cleanup mac address (#249) 2026-03-19 02:27:32 +01:00
Omar Amin 735731b63e Fix typo in line 176 2026-03-11 03:01:00 +02:00
Florian Asche 1fc29241b4 Add linting scripts and pipeline (#201)
* Add linting scripts and pipeline
2026-03-05 01:58:39 +01:00
Florian Asche a62800f5ad fix typo (#200) 2026-03-04 01:47:18 +01:00
Florian Asche 29f11c7dbc improved help output on application parameters (#188) 2026-03-04 01:09:10 +01:00
Florian Asche f2e3d8e7d3 Feature: move portcheck into python application (#187)
* moved port check from shell script into the python application
* fixed pulseaudio check console output
* portcheck has now 15 chances to get the port before abort
2026-03-04 01:08:45 +01:00
Florian Asche 68d2890fdd fix: ensure wake word state is set after the wake sound (#198) 2026-03-04 01:07:19 +01:00
Ethan Kiczek a30a10c95a Prevent wake word from interrupting active voice pipeline (#151)
* Prevent wake word from interrupting active voice pipeline
2026-03-04 00:54:19 +01:00
Florian Asche ecace7011f bugfix: start listening after wakeup sound (#185) 2026-03-01 21:01:35 +01:00
Florian Asche 80e0d6254e Fix: Suppress spurious end-file event when starting playback and tts.speak (#179)
* bugfix: supress first end of file event and only callback on second one
* add some notes on testing
* fixed tts.speak
* fix unduck after timer end
* use custom docker-entrypoint on dev container
* change mv to copy in the docs when using .env file
2026-02-26 01:31:18 +01:00
Omar Amin 9dcc4542a4 Enhance play method for playlist support (#172)
Refactor play method to support playlists and sequential playback.
2026-02-24 00:24:14 +01:00
Omar Amin 15b87942c5 Merge branch 'main' into Volume-Persistence-Across-Restarts 2026-02-22 05:34:57 +02:00
Omar Amin c4e444f8ca Refactor volume setting and add persistence
Refactor volume handling to use _apply_volume method and persist volume settings if server state is available.
2026-02-22 00:50:17 +02:00
Omar Amin c81a707c6a Enhance volume persistence with logging
Add logging for volume persistence and conditionally skip saving if unchanged.
2026-02-22 00:43:32 +02:00
Omar Amin 981a786a46 Merge branch 'main' into Volume-Persistence-Across-Restarts 2026-02-21 22:19:05 +02:00
Florian Asche 1ae6b18475 Merge branch 'main' into fix/timer-loop-suppress 2026-02-21 21:01:13 +01:00
Florian Asche 7de510cb1f Add version and hash to docker container (#167)
* Add version and git hash to image
* Add version reporting to HA via api
2026-02-21 20:38:46 +01:00
Omar Amin 38c064fc68 Update media player entity volume handling
Set the volume and previous volume for the media player entity based on the current state.
2026-02-21 16:27:06 +02:00
Omar Amin 0d34e67823 Enhance volume management in entity.py
Added initial volume parameter and volume control methods.
2026-02-21 16:26:13 +02:00
Omar Amin ac69618d29 Add volume handling to Preferences and persistence method
Added volume attribute to Preferences and implemented persist_volume method to save normalized media volume.
2026-02-21 16:25:16 +02:00
Omar Amin c91511c93e Initialize volume from preferences on startup
Load initial volume from preferences and constrain it between 0.0 and 1.0. Set volume for music and TTS players based on initial volume.
2026-02-21 16:24:40 +02:00
Ethan Kiczek 3834f51179 Fix timer finished sound not looping
Check if player is actually playing before calling stop(for_replacement=True)
in MpvMediaPlayer.play(). When the player was already idle,
stop(for_replacement=True) would set _suppress_end_event=True with no
end-file event to consume it. The next track's end-file callback would
then be incorrectly suppressed, breaking the timer loop.

- Import PlayerState to check player state
- Only call stop(for_replacement=True) when player is not IDLE
2026-02-18 18:13:51 -05:00
Florian AscheandFlorian Asche 05356acb3e fix bug in network-interface parameter usage
Co-authored-by: Florian Asche <git@florian-asche.de>
2026-02-14 22:14:53 +01:00
Florian Asche 4052daae01 hotfix for mac-detection and various variable names (#139)
* Change Client-Name: The client name inside LVA is not capable of having spaces in the name. Fixed the example.
* Add first version of Docker-Compose for developers
* Add variable for network-interface and auto detection by default
* Added autodetection for the MAC-Address based on the detected or specified network-interface.
* Switched from listening on all IP-Addresses to the IP of the default interface, usually u set the correct network-interface and it will automatically detect the right IP-Address.
* Added missing variables, fixed variables names
* Fixed not working variables for example sound-files.
* Moved the auto-name creation from shell to python. The name is no longer mandatory, it will be generated if no name is given.
2026-02-13 19:50:20 +01:00
Florian Asche f8c7501fa4 Merge branch 'main' into issue_128 2026-02-11 00:34:28 +01:00
Florian Asche d4edbc8333 Merge branch 'main' into feature/add-docker 2026-02-10 21:20:19 +01:00
Omar Amin 72dfc6db35 Merge branch 'main' into issue_128 2026-02-10 20:39:06 +02:00
Philipp Grafe 72c7d4dff4 media_player: handle STOP command correctly (fixes #128)
Home Assistant sends MEDIA_PLAYER_COMMAND_STOP when the queue is cleared.
The MediaPlayer entity did not handle this command, causing playback to
continue without media metadata and leaving the UI in an inconsistent state.

This change adds explicit handling for the STOP command:
- stop playback via the music player
- reset the media player state to IDLE

This aligns the behavior with the original player and Home Assistant’s
expected media player semantics.
2026-02-10 18:58:55 +01:00