Thanks to Smart Home Junkie’s video (invidious link), I had my Atom Echos as voice recognition boxes with all audio output redirected to a media player of my choice (because the audio on the Echo is super quiet).

Whenever ESPHome updated, I updated my Echos to get the recent ESPHome updates, and then reinstalled the custom yaml for audio redirection.

However, with ESPHome’s recent 2024.6.4 update, trying to install the yaml triggers errors that don’t seem to make sense. For example, here’s a section of the yaml:

microphone:
  - platform: i2s_audio
    id: echo_microphone_kitchen
    i2s_din_pin: GPIO23
    adc_type: external
    pdm: true

speaker:
  - platform: i2s_audio
    id: echo_speaker_kitchen
    i2s_dout_pin: GPIO21
    dac_type: external
    mode: mono

voice_assistant:
  id: va
  microphone: echo_microphone_kitchen
  speaker: echo_speaker_kitchen
  noise_suppression_level: 2
  auto_gain: 31dBFS
  volume_multiplier: 2.0
  vad_threshold: 3
  on_listening:
    - light.turn_on:
        id: led
        blue: 100%
        red: 0%
        green: 0%
        effect: "Slow Pulse"
  on_stt_vad_end:
    - light.turn_on:
        id: led
        blue: 100%
        red: 0%
        green: 0%
        effect: "Fast Pulse"
  on_tts_start:
    - light.turn_on:
        id: led
        blue: 100%
        red: 0%
        green: 0%
        brightness: 100%
        effect: none
  on_tts_end:
    - homeassistant.service:
        service: media_player.play_media
        data:
          entity_id: media_player.${media_player}
          media_content_id: !lambda 'return x;'
          media_content_type: music
          announce: "false"
  on_end:
    - delay: 100ms
    - wait_until:
        not:
          speaker.is_playing:
    - script.execute: reset_led
  on_error:
    - light.turn_on:
        id: led
        red: 100%
        green: 0%
        blue: 0%
        brightness: 100%
        effect: none
    - delay: 1s
    - script.execute: reset_led
  on_client_connected:
    - if:
        condition:
          switch.is_on: use_wake_word
        then:
          - voice_assistant.start_continuous:
          - script.execute: reset_led
  on_client_disconnected:
    - if:
        condition:
          switch.is_on: use_wake_word
        then:
          - voice_assistant.stop:
          - light.turn_off: led

external_components:
  - source: github://pr#5230
    components:
      - esp_adf
    refresh: 0s

esp_adf:

On lines 3 and 10 I define unique IDs for the device’s microphone and speaker.

But ESPHome won’t compile, telling me:

  • on line 46: Too many candidates found for ‘id’ type ‘speaker::Speaker’ Some are ‘echo_speaker’, ‘echo_speaker_kitchen’.
  • on line 57: Too many candidates found for ‘id’ type ‘speaker::Speaker’ Some are ‘echo_speaker’, ‘echo_speaker_kitchen’.
  • on line 77: Too many candidates found for ‘id’ type ‘microphone::Microphone’ Some are ‘echo_microphone’, ‘echo_microphone_kitchen’.
  • on line 90: Too many candidates found for ‘id’ type ‘speaker::Speaker’ Some are ‘echo_speaker’, ‘echo_speaker_kitchen’.

There are no other occurrences of the word “speaker” or “microphone” in the conf yaml (and I’m not including other yaml files).

I’m assuming most of this config is default, and the only things I care about are forcing pin 21 for the speaker (line 11) and redirecting audio to my media player (lines 45-52).

  • JustEnoughDucks@feddit.nl
    link
    fedilink
    English
    arrow-up
    1
    ·
    4 months ago

    Sorry, I misunderstood what you are trying to do here. I thought you were trying to use the Atom Echo itself as a media player. Disregard that arduino library comment, it isn’t relevant. I just watched the video since I couldn’t earlier.

    Indeed what you are doing should work. Are you certain that the upload was successful? With GPIO21 set as the speaker output, the speaker data should absolutely not work. The fact that it does means that somewhere along the line, the GPIO22 is set as the speaker output.

    • Mike Wooskey@lemmy.thewooskeys.comOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      4 months ago

      (sorry about my delayed response, @JustEnoughDucks@feddit.nl )

      I’m sure that the install is successful because there are no errors during/after install, the Echo recognizes speech and interacts with Home Assistant, and when I change something in the yaml (e.g., which media player to pipe the audio to) the change takes effect.

      Here’s something weird: I believe the default pin for “speaker” should be GPIO22, and when I switch it to GPIO21 it should not work. This works on some of my Echos, but not all of them!

      Also weird: I think the standard pinout is:

      • GPIO0: Button (Boot)
      • GPIO19: LED (RGB)
      • GPIO21: I2C SDA
      • GPIO22: I2C SCL
      • GPIO23: Speaker (PWM output)
      • GPIO25: Microphone (Analog input)

      Though I don’t know what these mean, I tried setting “speaker” to GPIO18 - which apparently isn’t used- and still the audio comes out of the Echo speaker! But again, only on some of my Echos.

      I’d think that maybe some of these Echos are ignoring the GPIO setting for “speaker” and using a default, but these Echos used to work! (that is, they used to not play audio out of the Echo speaker when “speaker” was GPIO21). And so I want to think that maybe the ESPHome upgrade made them stop working, but all my Echos have the same upgrade and yet still some of them work.

      Is there a way to config the Echo speaker to have zero volume? If so, I could just set that and then who cares if the audio is piped to it.

    • Mike Wooskey@lemmy.thewooskeys.comOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      4 months ago

      FYI, here’s the config yaml I’m copy-pasting for all my Echos. The only thing that changes are in the “substitutions” section:

      substitutions:
        name: m5stack-echo-kitchen
        friendly_name: M5Stack Atom Echo - Kitchen
        media_player: kitchen_speaker
        encryption_key: !secret kitchen_encryption_key
        speaker_i2s_dout_pin: "GPIO21"
      
      esphome:
        name: ${name}
        name_add_mac_suffix: false
        friendly_name: ${friendly_name}
        project:
          name: m5stack.atom-echo-voice-assistant
          version: "1.0"
        min_version: 2024.6.0
      
      esp32:
        board: m5stack-atom
        framework:
          type: esp-idf
      
      api:
        encryption:
          key: ${encryption_key}
      
      ota:
        - platform: esphome
          id: ota_esphome
      
      dashboard_import:
        package_import_url: github://esphome/firmware/voice-assistant/m5stack-atom-echo.yaml@main
      
      wifi:
        ssid: !secret wifi_ssid
        password: !secret wifi_password
        on_connect:
          - delay: 5s  # Gives time for improv results to be transmitted
          - ble.disable:
        on_disconnect:
          - ble.enable:
        ap:
      
      improv_serial:
      
      esp32_improv:
        authorizer: none
      
      button:
        - platform: factory_reset
          id: factory_reset_btn
          name: Factory reset
      
      i2s_audio:
        - id: i2s_audio_bus
          i2s_lrclk_pin: GPIO33
          i2s_bclk_pin: GPIO19
      
      microphone:
        - platform: i2s_audio
          id: echo_microphone
          i2s_din_pin: GPIO23
          adc_type: external
          pdm: true
      
      speaker:
        - platform: i2s_audio
          id: echo_speaker
          i2s_dout_pin: ${speaker_i2s_dout_pin}
          dac_type: external
          mode: mono
      
      voice_assistant:
        id: va
        microphone: echo_microphone
        speaker: echo_speaker
        noise_suppression_level: 2
        auto_gain: 31dBFS
        volume_multiplier: 2.0
        on_listening:
          - light.turn_on:
              id: led
              blue: 100%
              red: 0%
              green: 0%
              effect: "Slow Pulse"
        on_stt_vad_end:
          - light.turn_on:
              id: led
              blue: 100%
              red: 0%
              green: 0%
              effect: "Fast Pulse"
        on_tts_start:
          - light.turn_on:
              id: led
              blue: 100%
              red: 0%
              green: 0%
              brightness: 100%
              effect: none
        on_tts_end:
          - homeassistant.service:
              service: media_player.play_media
              data:
                entity_id: media_player.${media_player}
                media_content_id: !lambda 'return x;'
                media_content_type: music
                announce: "false"
        on_end:
          - delay: 100ms
          - wait_until:
              not:
                speaker.is_playing:
          - script.execute: reset_led
        on_error:
          - light.turn_on:
              id: led
              red: 100%
              green: 0%
              blue: 0%
              brightness: 100%
              effect: none
          - delay: 1s
          - script.execute: reset_led
        on_client_connected:
          - if:
              condition:
                switch.is_on: use_wake_word
              then:
                - voice_assistant.start_continuous:
                - script.execute: reset_led
        on_client_disconnected:
          - if:
              condition:
                switch.is_on: use_wake_word
              then:
                - voice_assistant.stop:
                - light.turn_off: led
        on_timer_finished:
          - voice_assistant.stop:
          - switch.turn_on: timer_ringing
          - wait_until:
              not:
                microphone.is_capturing:
          - light.turn_on:
              id: led
              red: 0%
              green: 100%
              blue: 0%
              brightness: 100%
              effect: "Fast Pulse"
          - while:
              condition:
                switch.is_on: timer_ringing
              then:
                - lambda: id(echo_speaker).play(id(timer_finished_wave_file), sizeof(id(timer_finished_wave_file)));
                - delay: 1s
          - wait_until:
              not:
                speaker.is_playing:
          - light.turn_off: led
          - switch.turn_off: timer_ringing
          - if:
              condition:
                switch.is_on: use_wake_word
              then:
                - voice_assistant.start_continuous:
                - script.execute: reset_led
      
      binary_sensor:
        - platform: gpio
          pin:
            number: GPIO39
            inverted: true
          name: Button
          disabled_by_default: true
          entity_category: diagnostic
          id: echo_button
          on_multi_click:
            - timing:
                - ON for at least 50ms
                - OFF for at least 50ms
              then:
                - if:
                    condition:
                      switch.is_on: timer_ringing
                    then:
                      - switch.turn_off: timer_ringing
                    else:
                      - if:
                          condition:
                            switch.is_off: use_wake_word
                          then:
                            - if:
                                condition: voice_assistant.is_running
                                then:
                                  - voice_assistant.stop:
                                  - script.execute: reset_led
                                else:
                                  - voice_assistant.start:
                          else:
                            - voice_assistant.stop
                            - delay: 1s
                            - script.execute: reset_led
                            - script.wait: reset_led
                            - voice_assistant.start_continuous:
            - timing:
                - ON for at least 10s
              then:
                - button.press: factory_reset_btn
      
      light:
        - platform: esp32_rmt_led_strip
          id: led
          name: None
          disabled_by_default: true
          entity_category: config
          pin: GPIO27
          default_transition_length: 0s
          chipset: SK6812
          num_leds: 1
          rgb_order: grb
          rmt_channel: 0
          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%
      
      script:
        - id: reset_led
          then:
            - if:
                condition:
                  - switch.is_on: use_wake_word
                  - switch.is_on: use_listen_light
                then:
                  - light.turn_on:
                      id: led
                      red: 100%
                      green: 89%
                      blue: 71%
                      brightness: 60%
                      effect: none
                else:
                  - light.turn_off: led
      
      switch:
        - platform: template
          name: Use wake word
          id: use_wake_word
          optimistic: true
          restore_mode: RESTORE_DEFAULT_ON
          entity_category: config
          on_turn_on:
            - lambda: id(va).set_use_wake_word(true);
            - if:
                condition:
                  not:
                    - voice_assistant.is_running
                then:
                  - voice_assistant.start_continuous
            - script.execute: reset_led
          on_turn_off:
            - voice_assistant.stop
            - lambda: id(va).set_use_wake_word(false);
            - script.execute: reset_led
        - platform: template
          name: Use listen light
          id: use_listen_light
          optimistic: true
          restore_mode: RESTORE_DEFAULT_ON
          entity_category: config
          on_turn_on:
            - script.execute: reset_led
          on_turn_off:
            - script.execute: reset_led
        - platform: template
          id: timer_ringing
          optimistic: true
          internal: true
          restore_mode: ALWAYS_OFF
          on_turn_on:
            - delay: 15min
            - switch.turn_off: timer_ringing
      
      external_components:
        - source: github://pr#5230
          components:
          refresh: 0s
        - source: github://jesserockz/esphome-components
          components: [file]
          refresh: 0s
      
      file:
        - id: timer_finished_wave_file
          file: https://github.com/esphome/firmware/raw/main/voice-assistant/sounds/timer_finished.wav
      
      logger:
      
    • Mike Wooskey@lemmy.thewooskeys.comOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      4 months ago

      Well, I wasn’t able to figure this out and was just living with duplicate audio coming from the echo and the media player mostly simultaneously. But today I upgraded ESPHome from 2024.6.6 to 2024.7.0 and the problem is gone. Sheesh! :)