Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Add assist_satellite.ask_question and assist_satellite.start_conversation capabilities#318

Open
RemyRoux wants to merge 2 commits intorhasspy:masterfrom
RemyRoux:patch-1
Open

Add assist_satellite.ask_question and assist_satellite.start_conversation capabilities#318
RemyRoux wants to merge 2 commits intorhasspy:masterfrom
RemyRoux:patch-1

Conversation

@RemyRoux
Copy link

@RemyRoux RemyRoux commented Jul 20, 2025

Proposed change

This PR introduces a new capability to the WakeStreamingSatellite to allow a connected server (like Home Assistant) to remotely trigger the satellite's listening state.

Currently, the WakeStreamingSatellite can only begin streaming microphone audio after it has locally detected a wake word. This makes it impossible for the server to initiate an interaction, such as asking the user a question via TTS and then waiting for a spoken response.

This change modifies the event_from_server method to handle a Detection event received from the server. This event acts as a command, instructing the satellite to immediately start streaming audio, just as if a local wake word had been detected. This enables powerful new services like assist_satellite.start_conversation and assist_satellite.ask_question in server-side applications.

To avoid conflicts with real wake words, the logic is designed to respond to a specific, non-standard wake word name (e.g., command_start), and it correctly bypasses the local refractory period logic. The existing local wake word detection behavior is completely unchanged.

Type of change

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Code quality improvements to existing code or addition of tests

Additional information

This PR is the satellite-side implementation that complements the new AssistSatelliteEntity support in Home Assistant Core (see home-assistant/core#149149). Both pieces are required for the new services to function.

@RemyRoux
Copy link
Author

Closes: #316, home-assistant/core#148055

s-heppner added a commit to s-heppner/wyoming-satellite that referenced this pull request Aug 9, 2025
Since the development is so slow, I added them myself, based on this PR:
github[.]com/rhasspy/pull/318
@fikretsengul
Copy link

Thanks, I've needed this for my automations for a while now. I forked your PR and tried by patching the home assistant. assist_satellite.start_conversation works perfectly (without affecting the wake word), but I couldn't get assist_satellite.ask_question to work. Do you have any idea why? (By the way, I'm using the wyoming-openai plugin as the AI.)

@RemyRoux
Copy link
Author

Because there are some changes also required on the home assistant side as well.

You need this: home-assistant/core@dev...RemyRoux:core:patch-1
And this: home-assistant/core@dev...RemyRoux:core:patch-2

The code needs to be loaded as a custom component in home assistant and voila.
Feel free to let me know if something doesn't work as expected.

I have prepared a pull request to add it formally into HA but it's taking a while and it looks like the authors of the wyoming satellite are switching toward a esphome solution. home-assistant/core#149149

@xertux
Copy link

xertux commented Sep 13, 2025

I have been following your progress for the merge but i lost hope when linux-voice-assistant showed up untill today. Thank you a lot for your work. I didn't know i can use your work as custom component. But as a beginner i had hard time swithching, could you help me?

-I deleted my old wyoming-satellite folder on my remote pi,
-I installed wyoming-satellite from your github with the same installation guide;
https://github.com/RemyRoux/wyoming-satellite
https://github.com/rhasspy/wyoming-satellite/blob/master/docs/tutorial_2mic.md
-used this line of code and my old settings were already there, then i started the satellite;
sudo systemctl edit --force --full wyoming-satellite.service
-On the home assistant side, i created a folder; /config/custom_components/wyoming
-I downloaded core components from this link, and copied contents of wyoming to the custom_components/wyoming
https://codeload.github.com/home-assistant/core/zip/refs/tags/2025.9.3
-I manually downloaded the changed files from patch-1 and patch-2 you linked, which are;
manifest.json
const.py
assist_satellite.py
init.py
-But there are two assist_satellite.py file. One from patch-1 and one from patch-2. What to do here?
-I copied and overwrited these files to my /config/custom_components/wyoming, removed old satellite under devices and rebooted
-I then added appeared wyoming satellite under devices,
-Main functions work but start, ask or continued converstaion doesn't seem working. I don't see my satellite entity on those actions.
-The files i overwrited to /config/custom_components/wyoming are seems like changing after hass reset. When i try to copy paste your files "again" i saw their sizes aren't the same even tho i pasted them there just before the restart, weird? I have write access to the folder.

@cloudomate
Copy link

cloudomate commented Sep 14, 2025

Any idea when this PR willl be merged ? its not even allocated for review ? @RemyRoux if i need only start conversation will your fork work or it also has some dependecny on the core i looked at the PR you have created both for wyonming-sattelite and homeassistant core. What do you mean they are inclined towards esphome ? I have a Atom Echo running esphome which already supports start conversation.

@fikretsengul
Copy link

fikretsengul commented Sep 16, 2025

Because there are some changes also required on the home assistant side as well.

You need this: home-assistant/core@dev...RemyRoux:core:patch-1 And this: home-assistant/core@dev...RemyRoux:core:patch-2

The code needs to be loaded as a custom component in home assistant and voila. Feel free to let me know if something doesn't work as expected.

I have prepared a pull request to add it formally into HA but it's taking a while and it looks like the authors of the wyoming satellite are switching toward a esphome solution. home-assistant/core#149149

Thank you for your response. I use https://github.com/amitfin/patch to patch home assistant files. Before seeing your message, I had only patched the patch-2 changes you sent to the home assistant repository. Now, the only change in patch-1 that you refactored is this. So I deleted this line from patch-2:

    async def async_start_conversation(
        self, start_announcement: AssistSatelliteAnnouncement
    ) -> None:
        """Start a conversation from the satellite by playing an announcement and then listening."""
        if start_announcement.preannounce_media_id:
            await self._play_media(start_announcement.preannounce_media_id)

        await self._play_media(start_announcement.media_id)

        if self._client is None:
            _LOGGER.warning("Not connected to satellite for start_conversation")
            return

        assert self._client is not None
        await self._client.write_event(Detection(name="command_start").event())

and replaced it with the one that you changed in patch-1:

    async def async_start_conversation(self) -> None:
        """Signal the satellite to start a conversation by streaming audio."""
        if self._client is None:
            # Not connected
            _LOGGER.warning("Not connected to satellite")
            return

        _LOGGER.debug("Requesting satellite to start conversation")
        await self._client.write_event(
            RunPipeline(
                start_stage=PipelineStage.STT,
            ).event()
        )

Long story short, I replaced the async_start_conversation method in patch-2 with your async_start_conversation method in patch-1. As a result, the list of the 3 files I patched is as follows:

patch:
  delay: 180
  restart: true

  files:
    - name: "const.py"
      base: "/share/wyoming_patcher/base"
      destination: "{homeassistant}/components/wyoming"
      patch: "/share/wyoming_patcher/patch"
    - name: "assist_satellite.py"
      base: "/share/wyoming_patcher/base"
      destination: "{homeassistant}/components/wyoming"
      patch: "/share/wyoming_patcher/patch"
    - name: "__init__.py"
      destination: "{homeassistant}/components/assist_satellite"
      base: "/share/wyoming_patcher/base"
      patch: "/share/wyoming_patcher/patch"

However, even though I pressed the button in the script I created for assist_satellite.start_conversation, the satellite does not start talking and then listening. Here is the script:

alias: Mutfak Fırın
description: ""
triggers:
  - device_id: 78697c63e64848f04d440c7640b48b8c
    domain: zha
    type: remote_button_short_press
    subtype: button
    trigger: device
conditions: []
actions:
  - action: assist_satellite.start_conversation
    metadata: {}
    data:
      preannounce: true
      start_message: Button is pressed, what should I do?
    target:
      device_id: 67dc401cbf0dcb6f8a730a4f5259d5e1
mode: single

The Wyoming satellite logs say the following:

Kitchen Assistant changed to Idle triggered by automation Kitchen Oven triggered by event 'zha_event'.

System logs shows two errors:

Logger: homeassistant.components.automation.mutfak_firin
Source: helpers/script.py:524
integration: Automation ([documentation](https://www.home-assistant.io/integrations/automation), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+automation%22))
First occurred: 2:01:33 PM (1 occurrence)
Last logged: 2:01:33 PM

Mutfak Fırın: Error executing script. Unexpected error for call_service at pos 1: WyomingAssistSatellite.async_start_conversation() takes 1 positional argument but 2 were given
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 524, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1012, in _async_step_call_service
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<9 lines>...
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 624, in _async_run_long_action
    return await long_task
           ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2835, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2878, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 850, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
        hass, entity, func, data, call.context
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 922, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/assist_satellite/entity.py", line 315, in async_internal_start_conversation
    await self.async_start_conversation(announcement)
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
TypeError: WyomingAssistSatellite.async_start_conversation() takes 1 positional argument but 2 were given
Logger: homeassistant.components.automation.mutfak_firin
Source: components/automation/__init__.py:717
integration: Automation ([documentation](https://www.home-assistant.io/integrations/automation), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+automation%22))
First occurred: 2:01:33 PM (1 occurrence)
Last logged: 2:01:33 PM

While executing automation automation.mutfak_firin
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/automation/__init__.py", line 717, in async_trigger
    return await self.action_script.async_run(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        variables, trigger_context, started_action
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1836, in async_run
    return await asyncio.shield(create_eager_task(run.async_run()))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 460, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 526, in _async_step
    self._handle_exception(
    ~~~~~~~~~~~~~~~~~~~~~~^
        ex, continue_on_error, self._log_exceptions or log_exceptions
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 556, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 524, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1012, in _async_step_call_service
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<9 lines>...
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 624, in _async_run_long_action
    return await long_task
           ^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2835, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2878, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 850, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
        hass, entity, func, data, call.context
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 922, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/assist_satellite/entity.py", line 315, in async_internal_start_conversation
    await self.async_start_conversation(announcement)
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
TypeError: WyomingAssistSatellite.async_start_conversation() takes 1 positional argument but 2 were given

Actually, the function parameters in patch-2 look correct. This is the source of the error. I fixed the parameters and tried again. Now, after the announcement, the satellite listens to me and responds, but it doesn't switch to listening again. Doesn't this development attempt to achieve this with the assist_satellite.start_conversation action? Isn't this the difference between it and the assist_satellite.ask_question action? Or have I completely misunderstood?

@xertux
Copy link

xertux commented Oct 14, 2025

@RemyRoux Hi, i have been using linux-voice-assistant for a few weeks but i want to switch back to wyoming. I really want to install it via your fork but i had questions. Do you have spare time to help me? I would like to have continued and start convertsation on wyoming.

#318 (comment)

@KGS501
Copy link

KGS501 commented Dec 31, 2025

This would be very cool, especially considering the almost perfect implementation with the just recently jailbroken Amazon Echo Shows Gen. 1 and Gen.2. I set them up with LineagueOS and wyoming protocol and those device work like a charm as a dashboard plus assist_satellite. I am now waiting for this feature to get implemented before I fully switch from Google Assistant to Voice Assist.

@omaramin-2000
Copy link
Contributor

omaramin-2000 commented Jan 1, 2026

This would be very cool, especially considering the almost perfect implementation with the just recently jailbroken Amazon Echo Shows Gen. 1 and Gen.2. I set them up with LineagueOS and wyoming protocol and those device work like a charm as a dashboard plus assist_satellite. I am now waiting for this feature to get implemented before I fully switch from Google Assistant to Voice Assist.

Wyoming Satellite will be replaced by Linux Voice Assistant which already supports the newest features.

@KGS501
Copy link

KGS501 commented Jan 2, 2026

Wyoming Satellite will be replaced by Linux Voice Assistant which already supports the newest features.

I have now checked but as far as I am aware the unlocked and rooted Echo Show devices are all armeabi-v7a (32-bit) and thus not compatible with Linux Voice Assistant. So I assume there is no realistic chance of those devices being able to handle start_conversation or ask_question anytime soon?

@omaramin-2000
Copy link
Contributor

omaramin-2000 commented Jan 2, 2026

Wyoming Satellite will be replaced by Linux Voice Assistant which already supports the newest features.

I have now checked but as far as I am aware the unlocked and rooted Echo Show devices are all armeabi-v7a (32-bit) and thus not compatible with Linux Voice Assistant. So I assume there is no realistic chance of those devices being able to handle start_conversation or ask_question anytime soon?

Perhaps a modified version for LVA could be developed to work on 32-bit, I was thinking of it, actually, and I am pretty sure that it's possible theoretically. Anyways, wyoming satellite will no longer be maintained as it will be replaced by LVA.

@RemyRoux
Copy link
Author

RemyRoux commented Jan 2, 2026

To be honest, I have been using LVA (the imonlinux fork) on 2 raspberry pis, and it's been pretty stable, I don't really want to dive back into this code as it's been a while and even the original authors have moved to LVA.

Regarding the Amazon Echo Show, I was able to successfully use it as an assist satellite by loading View Assist on it.
The issue is that, as mentioned on the thread of the mod of the echo show, the mic quality is terrible.

So I am using the raspberry pi with a jabra speak 710 and I'm pretty sure that it's the best possible setup available currently. The mic is catching my voice extremely well. There are still issues with the wake word though, I'm going to try training my own and see if that helps.

@KGS501
Copy link

KGS501 commented Jan 11, 2026

I see. But I assume wyoming protocol will then not be developed any further? So I could try to fork this repo and make my own edits to try to get this to work without risking having to do this all over when a new version of wyoming gets released?

@omaramin-2000
Copy link
Contributor

I see. But I assume wyoming protocol will then not be developed any further? So I could try to fork this repo and make my own edits to try to get this to work without risking having to do this all over when a new version of wyoming gets released?

Try developing a dedicated version of LVA for 32-bit.

@KGS501
Copy link

KGS501 commented Jan 11, 2026

I am a novice, which is why I am so hesitant to go into even forking wyoming. Since most of my coding adventures require extensive help from OpenAIs Codex, I am pretty sure any code I (and Codex) will produce, do not meet any standards which would make them fit for online publication.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants