Text to speech throws error

I’m a happy newbee user of Rhasspy and have a Jabra 410 connected and working as both microphone and speaker. I’m now trying to add text to speech capabilities to it and understand that this can be done through the websocket. I’m trying to follow this guide:

https://dev.to/jeikabu/home-assistant-voice-recognition-with-rhasspy-1jb2

So the first test is using the command line from another computer in the network:

curl -X POST -d "hello world" http://pi3.local:12101/api/text-to-speech

Where I changed pi3.local to the local ip address of the Raspberry Pi running the Rhasspy server.

The Rhasspy log then shows this:

[ERROR:53207605] APlayAudioPlayer: on_receive
Traceback (most recent call last):
  File "/usr/share/rhasspy/rhasspy/actor.py", line 175, in on_receive
    self._state_method(message, sender)
  File "/usr/share/rhasspy/rhasspy/audio_player.py", line 70, in in_started
    self.play_data(message.wav_data)
  File "/usr/share/rhasspy/rhasspy/audio_player.py", line 102, in play_data
    subprocess.run(aplay_cmd, input=wav_data, check=True)
  File "/usr/lib/python3.7/subprocess.py", line 512, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['aplay', '-q', '-D', 'dmix:CARD=USB,DEV=0']' returned non-zero exit status 1.
[DEBUG:53207533] APlayAudioPlayer: ['aplay', '-q', '-D', 'dmix:CARD=USB,DEV=0']
[DEBUG:53207531] EspeakSentenceSpeaker: ready -> speaking
[DEBUG:53207429] EspeakSentenceSpeaker: ['espeak', '-v', 'en', '--stdout', 'hello world']

I’m assuming, from the log, that at first espeak is used to create a sound file which is then played using aplay. I’ve tested both espeak and aplay using a ssh terminal to the raspberry pi and both work as expected.

Another hint may be that the ‘Speak’ button in the ‘Speech’ tab of the Rhasspy web interface also doesn’t work.

Maybe someone can point me in the right direction on how to solve this.

After some digging and investigating I partly solved the problem.

The correct settings for using the Jabra 410 with a Raspberry Pi can be found at:

https://gist.github.com/ScottJWalter/3ec644d2eb180d145db2b42c6ad13b53

I backed up the original .asoundrc file (pi home directory) and changed the contents to:

pcm.jabra {
    type hw
    card 1
    device 0
    rate 48000
}
pcm.!sysdefault {
  type asym
  playback.pcm {
    type plug
    slave.pcm "jabra"
  }
  capture.pcm {
    type plug
    slave.pcm "hw:1,0"
  }
}
pcm.!default {
  type asym
  playback.pcm {
    type plug
    slave.pcm "jabra"
  }
  capture.pcm {
    type plug
    slave.pcm "hw:1,0"
  }
}

In Rhasspy I changed the setting for ‘Sounds’ to ‘sysdefault:CARD=USB: Default Audio Device’.

curl -X POST -d "hello world" http://pi3.local:12101/api/text-to-speech

Now results in hearing the text spoken from the Rhasspy server. Pushing the ‘Speak’ button also works.

What doesn’t work yet is getting text from Home Assistant to the Rhasspy server. The log shows no error but I cannot hear any sound. The log output when sending service data ‘message: “hello”’ using the service ‘rest_command.tts’ shows:

[INFO:6788735] quart.serving: 192.168.178.68:42138 POST /api/text-to-speech 1.1 200 0 209030
[DEBUG:6788730] InboxActor:  -> stopped
[DEBUG:6788728] EspeakSentenceSpeaker: speaking -> ready
[DEBUG:6788613] APlayAudioPlayer: ['aplay', '-q', '-D', 'sysdefault:CARD=USB']
[DEBUG:6788611] EspeakSentenceSpeaker: ready -> speaking
[DEBUG:6788531] EspeakSentenceSpeaker: ['espeak', '-v', 'en', '--stdout', '']

I’ve noticed that the lowest entry has an empty text, so the call from Home assistant is faulty. I will need to further investigate, but I’m getting close to resolving this.

Finally solved it, using the above way of correctly configuring the Jabra device and using this post as inspiration:

https://community.home-assistant.io/t/solved-send-command-from-ha-to-rhasspy/180704

The service data should not be:

{message: 'hello world'}

but

{payload: "hello world"}

As an example, this automation should notify you via Rhasspy of the hour, every hour. Works on my configuration.

- id: hourlynotification
  alias: hourly notification
  trigger:
  - minutes: '0'
    platform: time_pattern
  action:
  - data_template:
      payload: '{{ now().hour }}'
    service: rest_command.tts