Bender Voice Assistant

Introducing my new assistant, a remix of an existing Thingiverse design, Bender:

https://drive.google.com/file/d/12IzneexG3fI87FeHmNLHvExuREUq2Jhm/view

Had to redesign the internals thanks to using some very different hardware. Lots of trial and error with different cables to get things to fit, and with acoustics to get solid performance out of the respeaker mic array (which I wanted to use primarily for the built in AEC).

Hardware

Software

  • Rhasspy
  • HomeAssistant
  • HermesLedControl
  • A bunch of my own glue code to handle everything from dimming media on wake word detection, cycling the on wake wav so Bender answers with a few different phrases, automatic generation of slots from my media library, and opening Kodi and playing that media.

Next Steps

  • TTS - really want to train a voice model off of some Bender audio clips
  • Wake word tweaking - I keep switching back to Snowboy, as I’ve had trouble getting consistent wake word detection on “hey bender”
9 Likes

is there any chance, i could get the actual code? I have been trying to make something, but as long as i have zero expiriences with stuff like this it would be much appreciated

I run an API on my home media center PC (windows) to control my Kodi instance (and do some automated browser stuff). This stuff is really specific to my own home setup, so I can’t recommend that you go trying to use it, but you might be able to parse out some concepts that are useful hopefully? It can be found here: https://github.com/repole/bender-mc

Then I run a rhasspy-hermes-app on my actual Pi to do some smart volume control: https://github.com/repole/bender-pi

Rhassy sentences (note that I use my API to generate the $tv_shows and $movies slots):

[PlayVideo]
play ($movies | $tv_shows){media_combo_id} [please]
put on [the] ($nba){media_combo_id} game [please]
play [the] ($nba){media_combo_id} game [please]
let's go ($mlb){media_combo_id}
here comes the ($mlb){media_combo_id}

[SwitchMediaMonitor]
(switch | change) (video | media) screen [please]

[SwitchMediaRoom]
[turn on] [the] ($rooms){room_id} [please]

[SetMediaVolume]
set [the] (volume | audio | sound) to (0..100){volume_level} [percent] [please]
(((lower | turn down | decrease):(decrease)) | ((raise | turn up | increase):(increase)) | ((mute | turn off | stop):(mute)) | ((unmute | turn on | resume):(unmute))){volume_level} [the] (volume | audio | sound) [please]
(((lower | turn down | decrease):(decrease)) | ((raise | turn up | increase):(increase))){volume_level} [the] (volume | audio | sound) (a lot | a little | 1..100){amount} [percent] [please]
turn the (volume | audio | sound) (((down | lower):(decrease)) | ((up | higher):(increase))){volume_level}
mute{volume_level} [please]
unmute{volume_level} [please]

[ResumeVideo]
resume video

[PauseVideo]
pause video

[NextVideo]
next (video | episode)

[QueueEpisode]
queue (1..100){number} episodes

Related parts of my Home Assistant configuration.yaml

rest_command:
  play_video:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/video/player/media'
    content_type: 'application/json; charset=utf-8'
    payload: '{"mediaComboId": "{{ media_combo_id }}"}'
  switch_media_monitor:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/mediaCenter/monitors/switch'
    content_type: 'application/json; charset=utf-8'
    payload: '{}'
  switch_media_room:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/mediaCenter/rooms/switch'
    content_type: 'application/json; charset=utf-8'
    payload: '{"roomId": "{{ room_id }}"}'
  set_media_volume:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/mediaCenter/speakers/volume'
    content_type: 'application/json; charset=utf-8'
    payload: '{"volumeLevel": "{{ volume_level }}", "amount": "{{ amount }}"}'
  pause_video:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/video/player/state'
    content_type: 'application/json; charset=utf-8'
    payload: 'pause'
  resume_video:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/video/player/state'
    content_type: 'application/json; charset=utf-8'
    payload: 'resume'
  next_video:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/video/player/state'
    content_type: 'application/json; charset=utf-8'
    payload: 'next'
  queue_episodes:
    method: 'post'
    url: 'http://192.168.1.99:5000/api/video/player/queue'
    content_type: 'application/json; charset=utf-8'
    payload: '{"number": "{{ number }}"}'

intent_script:
  PlayVideo:
    action:
      - service: rest_command.play_video
        data:
          media_combo_id: "{{ media_combo_id }}"
  ResumeVideo:
    action:
      - service: rest_command.resume_video
  PauseVideo:
    action:
      - service: rest_command.pause_video
  SwitchMediaMonitor:
    action:
      - service: rest_command.switch_media_monitor
  SwitchMediaRoom:
    action:
      - service: switch.turn_on
        data:
          entity_id: "switch.{{ room_id | replace('-', '_') }}"
  SetMediaVolume:
    action:
      - service: rest_command.set_media_volume
        data:
          volume_level: "{{ volume_level }}"
          amount: "{{ amount }}"

If you have any specific questions feel free, I’m happy to try and help.

1 Like