Quantcast
Channel: Configuration - Home Assistant Community
Viewing all articles
Browse latest Browse all 107830

Voice Assistant esphome with Esp32-s3 - Max98357 - Inmp441

$
0
0

i like to share my code for a voice assistant , is been hard to actually make it work, i modify a bluetooth speaker and add it inside for more appeal case.

media player
timer
wake word
fisical volume control

whats inside is a
ESP32-S3 N16R8
Max98357
Inmp441
2 buttons to control volume of media player
led strip of 4 segments ( already on the speaker)

https://www.youtube.com/shorts/MtxsIECVvgI



substitutions:
  micro_wake_word_model: okay_nabu  # alexa, hey_jarvis, hey_mycroft are also supported

esphome:
  name: asistente-oficina
  friendly_name: asistente oficina
  platformio_options:
    board_build.flash_mode: dio
  on_boot:
    - light.turn_on:
        id: led_strip           
        red: 80%
        green: 0%
        blue: 10%
        brightness: 80%
        effect: Slow Pulse

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf
    version: 4.4.8
    platform_version: 5.4.0
   
psram:
  mode: octal # Please change this to quad for N8R2 and octal for N16R8
  speed: 80MHz


# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "T15i5nnXt34zuu96/K2+vq+ebksy9ybLNi2/Oe9RR7A="


ota:
  - platform: esphome
    password: "48e0a97ecb956d919c184a0bb26a6f14"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Asistente-Oficina"
    password: "oFGhWSeTJ4aq"

captive_portal:


button:
  - platform: restart
    name: "Restart"
    id: but_rest

  - platform: template
    name: "Volume Up"
    id: volume_up
    on_press:
      - delay: 30ms
      - media_player.volume_up:
  - platform: template
    name: "Volume Down"
    id: volume_down
    on_press:
      - delay: 30ms
      - media_player.volume_down:     

switch:
  - platform: template
    id: timer_ringing
    name: "Timer Ringing"
    optimistic: true
    restore_mode: ALWAYS_OFF
    on_turn_off:
      # Turn off the repeat mode and disable the pause between playlist items
      - lambda: |-
              id(echo_media_player)
                ->make_call()
                .set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_REPEAT_OFF)
                .set_announcement(true)
                .perform();
              id(echo_media_player)->set_playlist_delay_ms(speaker::AudioPipelineType::ANNOUNCEMENT, 0);
      # Stop playing the alarm
      - media_player.stop:
          announcement: true
    on_turn_on:
      # Turn on the repeat mode and pause for 1000 ms between playlist items/repeats
      - lambda: |-
            id(echo_media_player)
              ->make_call()
              .set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_REPEAT_ONE)
              .set_announcement(true)
              .perform();
            id(echo_media_player)->set_playlist_delay_ms(speaker::AudioPipelineType::ANNOUNCEMENT, 1000);
      - media_player.speaker.play_on_device_media_file:
          media_file: timer_finished_wave_file
          announcement: true
      - delay: 15min
      - switch.turn_off: timer_ringing


# GPIO Mute Button Config
binary_sensor:
  - platform: gpio
    pin:
      number: GPIO21
      mode:
        input: true
        pullup: true
    id: btn_vol_up
    on_press:
      then:
        - delay: 30ms
        - button.press: volume_up
  - platform: gpio
    pin:
      number: GPIO47
      mode:
        input: true
        pullup: true
    id: btn_vol_down
    on_press:
      then:
        - delay: 30ms
        - button.press: volume_down         

          
 # Audio and Voice Assistant Config          
i2s_audio:
  - id: i2s_in # For microphone
    i2s_lrclk_pin: GPIO6 # lrc/WS
    i2s_bclk_pin: GPIO7 #blck/sck


microphone:
  - platform: i2s_audio
    id: va_mic
    adc_type: external
    i2s_din_pin: GPIO4 #SD
    channel: left
    pdm: false
    i2s_audio_id: i2s_in
    bits_per_sample: 32bit
    
speaker:
    platform: i2s_audio
    id: va_speaker
    i2s_audio_id: i2s_in
    i2s_dout_pin: GPIO8   #  DIN Pin of the MAX98357A Audio Amplifier
    dac_type: external
    channel: right
    bits_per_sample: 16bit
    sample_rate: 16000
    buffer_duration: 80ms    

media_player:
  - platform: speaker
    name: None
    id: echo_media_player
    announcement_pipeline:
      speaker: va_speaker
      format: WAV
    codec_support_enabled: false
    buffer_size: 6000
    volume_min: 0.5
    files:
      - id: timer_finished_wave_file
        file: https://github.com/esphome/wake-word-voice-assistants/raw/main/sounds/timer_finished.wav    
    on_volume:
      then:
        - light.turn_on:
            id: led_strip
            effect: "Volume Level Display"
        - delay: 1s
        - light.turn_off:
            id: led_strip
    on_announcement:
      - if:
          condition:
            - microphone.is_capturing:
          then:
            - if:
                condition:
                  lambda: return id(wake_word_engine_location).state == "On device";
                then:
                  - micro_wake_word.stop:
                else:
                  - voice_assistant.stop:
      - light.turn_on:
          id: led_strip
          blue: 100%
          red: 0%
          green: 0%
          brightness: 100%
          effect: none
    on_idle:
      - script.execute: start_wake_word
      - light.turn_off:
          id: led_strip
    
voice_assistant:
  id: va
  microphone: va_mic
  auto_gain: 31dBFS
  noise_suppression_level: 2
  volume_multiplier: 4.0
  media_player: echo_media_player

        
  on_listening: 
    - light.turn_on:
        id: led_strip
        effect: "Fast Pulse"
        brightness: 80%
        red: 2%
        green: 13%
        blue: 90%   

  on_stt_vad_end:
    - light.turn_on:
        id: led_strip
        effect: "Slow Pulse"
        brightness: 80%
        red: 0%
        green: 100%
        blue: 0%   

  on_tts_start:
    - light.turn_on:
        id: led_strip
        blue: 100%
        red: 0%
        green: 0%
        brightness: 100%
        effect: none

  on_end:
    - delay: 100ms
    - script.execute: start_wake_word
  on_error:
    - light.turn_on:
        id: led_strip
        red: 100%
        green: 0%
        blue: 0%
        brightness: 100%
        effect: none  
  on_client_connected:
    - delay: 2s  # Give the api server time to settle
    - script.execute: start_wake_word
  on_client_disconnected:
    - voice_assistant.stop:
    - micro_wake_word.stop:
  on_timer_finished:
    - voice_assistant.stop:
    - micro_wake_word.stop:
    - wait_until:
        not:
          microphone.is_capturing:
    - switch.turn_on: timer_ringing
    - light.turn_on:
        id: led_strip
        red: 0%
        green: 100%
        blue: 0%
        brightness: 100%
        effect: "Fast Pulse"
    - wait_until:
        - switch.is_off: timer_ringing
    - light.turn_off: led_strip
    - switch.turn_off: timer_ringing  


 

light:
  - platform: esp32_rmt_led_strip
    rgb_order: GRB
    pin: GPIO9
    num_leds: 30
    chipset: ws2812
    disabled_by_default: true
    rmt_channel: 0
    name: "status light"
    id: led_strip
    effects:
        - pulse:
            name: "Slow Pulse"
            transition_length: 250ms
            update_interval: 250ms
            min_brightness: 50%
            max_brightness: 100%
        - pulse:
            name: "Fast Pulse"
            transition_length: 100ms
            update_interval: 100ms
            min_brightness: 50%
            max_brightness: 100%
        - addressable_scan:
            name: Scan Effect With Custom Values
            move_interval: 50ms
            scan_width: 2
        - addressable_lambda:
            name: Volume Level Display
            update_interval: 500ms
            lambda: |-
              float volume = id(echo_media_player).volume;
              int num_leds_on = round(volume * 4);
              for (int i = 0; i < it.size(); i++) {
                if (i < num_leds_on) {
                  it[i] = ESPColor(0, 0, 255); // Blue
                } else {
                  it[i] = ESPColor::BLACK;
                }
              }    

script:
  - id: start_wake_word
    then:
      - wait_until:
          and:
            - media_player.is_idle:
            - speaker.is_stopped:
      - if:
          condition:
            lambda: return id(wake_word_engine_location).state == "On device";
          then:
            - voice_assistant.stop
            - micro_wake_word.stop:
            - delay: 1s
            - micro_wake_word.start:
          else:
            - if:
                condition: voice_assistant.is_running
                then:
                  - voice_assistant.stop:
            - voice_assistant.start_continuous:


select:
  - platform: template
    entity_category: config
    name: Wake word engine location
    id: wake_word_engine_location
    optimistic: true
    restore_value: true
    options:
      - In Home Assistant
      - On device
    initial_option: On device
    on_value:
      - if:
          condition:
            lambda: return x == "In Home Assistant";
          then:
            - micro_wake_word.stop
            - delay: 500ms
            - lambda: id(va).set_use_wake_word(true);
            - voice_assistant.start_continuous:
      - if:
          condition:
            lambda: return x == "On device";
          then:
            - lambda: id(va).set_use_wake_word(false);
            - voice_assistant.stop
            - delay: 500ms
            - micro_wake_word.start

micro_wake_word:
  on_wake_word_detected:
    - voice_assistant.start:
        wake_word: !lambda return wake_word;
  vad:
  models:
    - model: ${micro_wake_word_model}

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 107830


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>