From e8c146cf4b707dd8eedd26b228b57c4cb531d4a1 Mon Sep 17 00:00:00 2001 From: radu Date: Fri, 17 Jul 2026 14:22:17 +0700 Subject: [PATCH] doi --- board/c6 | 4 + board/s3mb16 | 25 +++++ board/s3mb4 | 14 +++ bootLight.yaml | 9 ++ common.yaml | 80 +++++++++++++++- main.yaml | 6 +- services/ble.yaml | 9 ++ services/voices3mb4.yaml | 201 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 342 insertions(+), 6 deletions(-) create mode 100644 board/c6 create mode 100644 board/s3mb16 create mode 100644 board/s3mb4 create mode 100644 bootLight.yaml create mode 100644 services/ble.yaml create mode 100644 services/voices3mb4.yaml diff --git a/board/c6 b/board/c6 new file mode 100644 index 0000000..8ad92e3 --- /dev/null +++ b/board/c6 @@ -0,0 +1,4 @@ +esp32: + board: esp32-c6-devkitc-1 + framework: + type: esp-idf \ No newline at end of file diff --git a/board/s3mb16 b/board/s3mb16 new file mode 100644 index 0000000..81daa4b --- /dev/null +++ b/board/s3mb16 @@ -0,0 +1,25 @@ +esp32: + board: esp32-s3-devkitc-1 + cpu_frequency: 240MHz + variant: esp32s3 + flash_size: 16MB + framework: + type: esp-idf + version: recommended + sdkconfig_options: + CONFIG_ESP32S3_DATA_CACHE_64KB: "y" + CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y" + CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB: "y" + + CONFIG_SPIRAM_RODATA: "y" + CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y" + + CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST: "y" + CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY: "y" + + CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC: "y" + CONFIG_MBEDTLS_SSL_PROTO_TLS1_3: "y" + + #Bluetooth + CONFIG_BT_GATTC_MAX_CACHE_CHAR: "80" + CONFIG_BT_GATTC_NOTIF_REG_MAX: "20" \ No newline at end of file diff --git a/board/s3mb4 b/board/s3mb4 new file mode 100644 index 0000000..7cbb065 --- /dev/null +++ b/board/s3mb4 @@ -0,0 +1,14 @@ +esp32: + board: esp32-s3-devkitc-1 + cpu_frequency: 240MHz + variant: esp32s3 + flash_size: 4MB + framework: + type: esp-idf + version: recommended + sdkconfig_options: + CONFIG_ESP32_DEFAULT_CPU_FREQ_240: "y" + +psram: + mode: octal + speed: 80MHz \ No newline at end of file diff --git a/bootLight.yaml b/bootLight.yaml new file mode 100644 index 0000000..5e53377 --- /dev/null +++ b/bootLight.yaml @@ -0,0 +1,9 @@ + on_boot: + priority: 600 + then: + - light.turn_on: + id: led + brightness: 25% + red: 100% + green: 0% + blue: 100% \ No newline at end of file diff --git a/common.yaml b/common.yaml index 8bff186..7d0d77c 100644 --- a/common.yaml +++ b/common.yaml @@ -1,5 +1,77 @@ esphome: - name: ${NAME} - friendly_name: ESP Assistant VP -esp32: - board: esp32-s3-devkitc-1 \ No newline at end of file + name: ${NAME} + friendly_name: ${FRIENDLY_NAME} + +# Enable logging +logger: + level: ${LOGGER} + +# Enable Home Assistant API +api: + batch_delay: 120ms # Reduce latency for real-time applications + max_send_queue: 32 # Maximum queued messages per connection before disconnect + +ota: + - platform: esphome + +wifi: + id: wifi_id + # ssid: ow + # password: mata1234 + ssid: !secret wifiname + password: !secret wifipass + + manual_ip: + static_ip: ${IP} + gateway: 192.168.11.1 + subnet: 255.255.255.0 + dns1: 192.168.11.111 + power_save_mode: NONE + on_connect: + then: + - light.turn_on: + id: led + brightness: 25% + red: 0% + green: 100% + blue: 0% + + on_disconnect: + then: + - light.turn_on: + id: led + brightness: 25% + red: 100% + green: 0% + blue: 0% + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: ${FRIENDLY_NAME} + password: "12345678" +light: + - platform: esp32_rmt_led_strip + id: led + name: None + internal: true + disabled_by_default: true + entity_category: config + pin: ${LED} + default_transition_length: 0s + chipset: SK6812 + num_leds: 1 + rgb_order: grb + effects: + - pulse: + name: "slowpulse" + transition_length: 250ms + update_interval: 250ms + min_brightness: 50% + max_brightness: 100% + - pulse: + name: "fastpulse" + transition_length: 100ms + update_interval: 100ms + min_brightness: 50% + max_brightness: 100% +captive_portal: \ No newline at end of file diff --git a/main.yaml b/main.yaml index 802e6b7..ffb8736 100644 --- a/main.yaml +++ b/main.yaml @@ -1,9 +1,11 @@ substitutions: NAME: "esp-assistant-vp" FRIENDLY_NAME: ESP Assistant VP + LED: GPIO48 + LOGGER: DEBUG #ERROR #VERY_VERBOSE + IP: 192.168.11.52 + WS: GPIO5 SCK: GPIO6 SD: GPIO4 - LED: GPIO48 SPKR: media_player.bedroom_speakers - LOGS: DEBUG #ERROR #VERY_VERBOSE \ No newline at end of file diff --git a/services/ble.yaml b/services/ble.yaml new file mode 100644 index 0000000..2e4c64c --- /dev/null +++ b/services/ble.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + scan_parameters: + interval: 1100ms + window: 1100ms + active: true + +bluetooth_proxy: + active: true + # connection_slots: 3 \ No newline at end of file diff --git a/services/voices3mb4.yaml b/services/voices3mb4.yaml new file mode 100644 index 0000000..a1191f1 --- /dev/null +++ b/services/voices3mb4.yaml @@ -0,0 +1,201 @@ +globals: + # Global variable tracking the phase of the voice assistant (defined above). Initialized to not_ready + - id: voice_assistant_phase + type: int + restore_value: no + initial_value: "2" + - id: stt_vad_started + type: bool + restore_value: no + initial_value: "false" + +i2s_audio: + id: i2s_audio_bus + i2s_lrclk_pin: GPIO${WS} #WS + i2s_bclk_pin: GPIO${SCK} #sck + +microphone: + - platform: i2s_audio + id: echo_microphone + i2s_din_pin: GPIO${SD} #SD + adc_type: external + i2s_audio_id: i2s_audio_bus + #pdm: False + channel: right + sample_rate: 16000 + bits_per_sample: 16bit + #i2s_mode: primary + correct_dc_offset: true + +voice_assistant: + id: va + microphone: + microphone: echo_microphone + channels: 0 + gain_factor: 4 + noise_suppression_level: 2 + auto_gain: 31dBFS + on_start: + - light.turn_on: + id: led + red: 0% + green: 100% + blue: 0% + brightness: 15% + effect: none + + on_listening: + - light.turn_on: + id: led + blue: 100% + red: 0% + green: 0% + effect: none + - lambda: id(voice_assistant_phase) = 2; + - lambda: id(stt_vad_started) = false; + + on_stt_vad_start: + # Turn off the script if speech is detected + - lambda: id(stt_vad_started) = true; + + on_stt_vad_end: + #- logger.log: "===============================VAD is the END ==================================" + - light.turn_on: + id: led + blue: 100% + red: 0% + green: 100% + effect: none + + on_stt_end: + - logger.log: + format: "STT text: %s" + args: ["x.c_str()"] + + on_tts_start: + then: + - light.turn_on: + id: led + blue: 100% + red: 100% + green: 100% + brightness: 30% + effect: none + + on_tts_end: + - homeassistant.action: + action: media_player.play_media + data: + entity_id: ${SPKR} + media_content_id: !lambda "return x;" + media_content_type: music + announce: "false" + + on_end: + - lambda: id(voice_assistant_phase) = 1; + - lambda: id(stt_vad_started) = false; + - script.execute: start_wake_word + #- voice_assistant.start: + + on_error: + - if: + condition: + lambda: |- + return message.find("duplicate_wake_up_detected") != std::string::npos; + then: + - voice_assistant.stop: + - delay: 350ms + - script.execute: start_wake_word + else: + - lambda: id(voice_assistant_phase) = 4; + - light.turn_on: + id: led + red: 100% + green: 0% + blue: 0% + brightness: 100% + effect: "Slow Pulse" + - delay: 2s + - script.execute: rboot + #- script.execute: reset_led + on_client_connected: + - delay: 1s # Give the api server time to settle + - script.execute: start_wake_word + on_client_disconnected: + - lambda: id(voice_assistant_phase) = 4; + - script.execute: stop_wake_word + - script.execute: rboot + +interval: + - interval: 30s + then: + - if: + condition: + and: + - api.connected: + - not: + - voice_assistant.is_running: + then: + - script.execute: start_wake_word + +script: + - id: rboot + mode: restart + then: + - delay: 180s + - if: + condition: + lambda: |- + return id(voice_assistant_phase) == 4; + then: + - switch.turn_on: + id: rbt + - id: listening_timeout + mode: restart + then: + - delay: ${listenTimeout} + # - logger.log: + # format: "In Script >>>> C >>>> voice_assistant_phase=%d " + # args: [ 'id(voice_assistant_phase)' ] + - if: + condition: + lambda: |- + return id(voice_assistant_phase) == 2 && !id(stt_vad_started); + then: + - logger.log: "+++++++++++++++++++++++++ reset ==========================================" + - light.turn_off: + id: led + - voice_assistant.stop: + - delay: 1s + - script.execute: start_wake_word + + - id: start_wake_word + then: + - if: + condition: + #and: + - not: + - voice_assistant.is_running: + then: + - lambda: id(va).set_use_wake_word(true); + - voice_assistant.start_continuous: + + - id: stop_wake_word + then: + - lambda: id(va).set_use_wake_word(false); + - voice_assistant.stop: +switch: + - platform: restart + name: Restart + id: rbt + - platform: template + name: Stop Listen + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + #entity_category: config + on_turn_on: + - microphone.mute: echo_microphone + #- script.execute: stop_wake_word + on_turn_off: + - microphone.unmute: echo_microphone + #- script.execute: listening_timeout \ No newline at end of file