-
-
Save EverythingSmartHome/055fbdde31a607ef9d695d5cac780e94 to your computer and use it in GitHub Desktop.
esphome: | |
name: esp32-mic-speaker | |
friendly_name: esp32-mic-speaker | |
on_boot: | |
- priority: -100 | |
then: | |
- wait_until: api.connected | |
- delay: 1s | |
- if: | |
condition: | |
switch.is_on: use_wake_word | |
then: | |
- voice_assistant.start_continuous: | |
esp32: | |
board: esp32dev | |
framework: | |
type: esp-idf | |
version: recommended | |
# Enable logging | |
logger: | |
# Enable Home Assistant API | |
api: | |
ota: | |
wifi: | |
ssid: !secret wifi_ssid | |
password: !secret wifi_password | |
# Enable fallback hotspot (captive portal) in case wifi connection fails | |
ap: | |
ssid: "Esp32-Mic-Speaker" | |
password: "9vYvAFzzPjuc" | |
i2s_audio: | |
i2s_lrclk_pin: GPIO27 | |
i2s_bclk_pin: GPIO26 | |
microphone: | |
- platform: i2s_audio | |
id: mic | |
adc_type: external | |
i2s_din_pin: GPIO13 | |
pdm: false | |
speaker: | |
- platform: i2s_audio | |
id: big_speaker | |
dac_type: external | |
i2s_dout_pin: GPIO25 | |
mode: mono | |
voice_assistant: | |
microphone: mic | |
use_wake_word: false | |
noise_suppression_level: 2 | |
auto_gain: 31dBFS | |
volume_multiplier: 2.0 | |
speaker: big_speaker | |
id: assist | |
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(assist).set_use_wake_word(true); | |
- if: | |
condition: | |
not: | |
- voice_assistant.is_running | |
then: | |
- voice_assistant.start_continuous | |
on_turn_off: | |
- voice_assistant.stop | |
- lambda: id(assist).set_use_wake_word(false); |
Regarding high pitch sounds during playback clicks are typically caused by signal integrity issues since these are relatively high speed signals. Especially if the distortion stops if you touch the high speed lines with your hand, move things. You should be able to so solve such issues by using better quality dupont lines with higher load spring mechanisms, soldering the dupont lines without the plastic cases, twisting the high speed lines together with gnd or even adding some grounded tinfoil around the signal wires. Another thing I noticed the INMP441 can pick up alot of noise if the PCB touches a surface that is vibrating. A good solution probably is to use some polyester fiber like in pillows to make sure the MEMS microphone does touch any hard surfaces in casing that you have.
Longer pauses like over 300ms are most likely caused by buffering issues, which is another story altogether.
I'm trying to build this project with a wemos d1 mini, max98357, ICS43434, and adafruit 1314 speaker. I'm having trouble getting the project to build when I have gotten it to build I get constant static/crackle on the speaker. Any help or advice would be greatly appreciated. Thanks!
I resolved this (thanks to another community member) by pulling the speaker pin low on boot using a simple output, haven't heard the crackle since.
Can I ask how? I find this helps but doesn't eliminate it...
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
on_boot:
- priority: -100
then:
- output.turn_off: speaker_pin #suppress crackling during boot
speaker:
- platform: i2s_audio
id: spk
dac_type: external
i2s_dout_pin:
number: ${din}
allow_other_uses: true
i2s_audio_id: i2s
mode: mono
output:
- platform: gpio
pin:
number: ${din}
allow_other_uses: true
id: speaker_pin
Thanks!
Edit: I find I get crackling and static until the device gets to DETECTING_WAKE_WORD state.
Edit2: I actually found separating out lrclk and bclk resolved it for me.
i2s_audio:
- id: i2s_in
i2s_lrclk_pin: ${lrclk_mic}
i2s_bclk_pin: ${bclk_mic}
- id: i2s_out
i2s_lrclk_pin: ${lrclk_amp}
i2s_bclk_pin: ${bclk_amp}
I'm getting an error when installing the .yaml onto the ESP32 I have. I've pared it down to just the minimums to try and isolate the issue.
When I do a basic, bare-bones install of the ESP-WROOM-32 into Home Assistant using ESPHome, it works fine. I can see the wifi connecting on boot. But with the bare-bones .yaml, that's all it does.
Then I started adding some of the .yaml above in. I first tried changing the framework from Arduino to esp-idf by adding only this section:
esp32:
board: esp32dev
framework:
type: esp-idf
version: recommended
and trying to install. But I get this error that my sub-novice brain doesn't know how to troubleshoot:
INFO ESPHome 2024.11.1
INFO Reading configuration /config/esphome/voice-assistant.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing voice-assistant (board: esp32dev; framework: espidf; platform: platformio/espressif32@5.4.0)
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
- framework-espidf @ 3.40408.0 (4.4.8)
- tool-cmake @ 3.16.9
- tool-ninja @ 1.10.2
- toolchain-esp32ulp @ 2.35.0-20220830
- toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Reading CMake configuration...
-- Component directory /data/cache/platformio/packages/framework-espidf/components/expat does not contain a CMakeLists.txt file. No component will be added
-- Building ESP-IDF components for target esp32
-- Configuring incomplete, errors occurred!
See also "/data/build/voice-assistant/.pioenvs/voice-assistant/CMakeFiles/CMakeOutput.log".
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
CMake Error at /data/cache/platformio/packages/framework-espidf/tools/cmake/build.cmake:201 (message):
Failed to resolve component 'freertos'.
Call Stack (most recent call first):
/data/cache/platformio/packages/framework-espidf/tools/cmake/build.cmake:236 (__build_resolve_and_add_req)
/data/cache/platformio/packages/framework-espidf/tools/cmake/build.cmake:237 (__build_expand_requirements)
/data/cache/platformio/packages/framework-espidf/tools/cmake/build.cmake:518 (__build_expand_requirements)
/data/cache/platformio/packages/framework-espidf/tools/cmake/project.cmake:476 (idf_build_process)
CMakeLists.txt:3 (project)
========================= [FAILED] Took 12.33 seconds =========================
I'm having success with this setup, but noticing that the INMP441/ESP32S3 doesn't seem to be multiplying the volume of the mic even when "volume_multiplier: 15.0" is uncommented. I've tried 4x, all the way to 128x and the audio files that are passed to HA sound the same (that is, very low). This affects HA's ability to correctly do STT. I find that if I manually multiply the recorded sample, it is not at all distorted and relatively high quality, so there seems to be plenty of headroom to increase the mic volume, I just can't make the setup actually do it.
Any ideas? This is really the final sticking point for me being able to use these regularly in the house.
I have been trying to get a voice assistant setup on an esp32 for months now with the ability to also have the media player. Is this possible? I also would like to use the same pin for both speaker and media player
I have been trying to get a voice assistant setup on an esp32 for months now with the ability to also have the media player. Is this possible? I also would like to use the same pin for both speaker and media player
It is possible with the nabu media player...
substitutions:
# Phases of the Voice Assistant
# The voice assistant is ready to be triggered by a wake word
voice_assist_idle_phase_id: '1'
# The voice assistant is waiting for a voice command (after being triggered by the wake word)
voice_assist_waiting_for_command_phase_id: '2'
# The voice assistant is listening for a voice command
voice_assist_listening_for_command_phase_id: '3'
# The voice assistant is currently processing the command
voice_assist_thinking_phase_id: '4'
# The voice assistant is replying to the command
voice_assist_replying_phase_id: '5'
# The voice assistant is not ready
voice_assist_not_ready_phase_id: '10'
# The voice assistant encountered an error
voice_assist_error_phase_id: '11'
device_name: "assist-media-player-kitchen"
friendly_name: "assist-media-player-kitchen"
device_description: "assist-media-player-kitchen"
din: "GPIO11" # MAX98357A - DIN
lrclk_mic: "GPIO15" # MAX98357A & ICS43434 - LRC/LRCL
lrclk_amp: "GPIO9" # MAX98357A & ICS43434 - LRC/LRCL
bclk_mic: "GPIO6" # MAX98357A & ICS43434 - BCLK
bclk_amp: "GPIO10" # MAX98357A & ICS43434 - BCLK
dout: "GPIO7" # ICS43434 - DOUT
# ICS43434 - SEL low = left, high = right
duck: "30" # db reduction for audio ducking
vol: "90%" # volume level at boot
pwr: "GPIO37" # charger output
tablet_battery: "sensor.kitchen_tablet_battery_level"
external_components:
- source:
type: git
url: https://github.com/esphome/voice-kit
ref: dev
components:
- media_player
- micro_wake_word
- microphone
- nabu
- voice_assistant
refresh: 0s
- source:
type: git
url: https://github.com/formatBCE/home-assistant-voice-pe
ref: 48kHz_mic_support
components:
- nabu_microphone
refresh: 0s
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
platformio_options:
board_build.flash_mode: dio
on_boot:
priority: 375
then:
- media_player.volume_set: ${vol}
- delay: 10min
- if:
condition:
lambda: return id(init_in_progress);
then:
- lambda: id(init_in_progress) = false;
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
flash_size: 8MB
framework:
type: esp-idf
version: recommended
sdkconfig_options:
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB: "y"
CONFIG_ESP32_S3_BOX_BOARD: "y"
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY: "y"
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP: "y"
# Settings based on https://github.com/espressif/esp-adf/issues/297#issuecomment-783811702
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM: "16"
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM: "512"
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER: "y"
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE: "0"
CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM: "8"
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM: "32"
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED: "y"
CONFIG_ESP32_WIFI_TX_BA_WIN: "16"
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED: "y"
CONFIG_ESP32_WIFI_RX_BA_WIN: "32"
CONFIG_LWIP_MAX_ACTIVE_TCP: "16"
CONFIG_LWIP_MAX_LISTENING_TCP: "16"
CONFIG_TCP_MAXRTX: "12"
CONFIG_TCP_SYNMAXRTX: "6"
CONFIG_TCP_MSS: "1436"
CONFIG_TCP_MSL: "60000"
CONFIG_TCP_SND_BUF_DEFAULT: "65535"
CONFIG_TCP_WND_DEFAULT: "65535" # Adjusted from linked settings to avoid compilation error
CONFIG_TCP_RECVMBOX_SIZE: "512"
CONFIG_TCP_QUEUE_OOSEQ: "y"
CONFIG_TCP_OVERSIZE_MSS: "y"
CONFIG_LWIP_WND_SCALE: "y"
CONFIG_TCP_RCV_SCALE: "3"
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE: "512"
CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST: "y"
CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY: "y"
psram:
mode: quad # quad for N8R2 and octal for N16R8
speed: 80MHz
globals:
# Global initialization variable. Initialized to true and set to false once everything is connected. Only used to have a smooth "plugging" experience
- id: init_in_progress
type: bool
restore_value: no
initial_value: 'true'
# 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: ${voice_assist_not_ready_phase_id}
# Global variable storing the first active timer
- id: first_active_timer
type: voice_assistant::Timer
restore_value: false
# Global variable storing the timer finished TTS
- id: timer_tts_str
type: std::string
restore_value: false
logger:
captive_portal:
web_server:
api:
encryption:
key: !secret assist_kitchen_api
ota:
- platform: esphome
password: "36e011a812d79f51cb886ff8d171eda2"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Esp32-Mic-Speaker"
password: "9vYvAFzzPjuc"
i2s_audio:
- id: i2s_in
i2s_lrclk_pin: ${lrclk_mic}
i2s_bclk_pin: ${bclk_mic}
- id: i2s_out
i2s_lrclk_pin: ${lrclk_amp}
i2s_bclk_pin: ${bclk_amp}
microphone:
- platform: nabu_microphone
i2s_din_pin: ${dout}
adc_type: external
pdm: false
sample_rate: 48000
bits_per_sample: 32bit
i2s_audio_id: i2s_in
channel_0:
id: mic0
channel_1:
id: mic1
speaker:
- platform: i2s_audio
id: spk
sample_rate: 48000
i2s_dout_pin: ${din}
bits_per_sample: 32bit
i2s_audio_id: i2s_out
dac_type: external
channel: mono
timeout: never
buffer_duration: 100ms
media_player:
- platform: nabu
id: nabu_media_player
name: Media Player
internal: false
speaker:
sample_rate: 48000
volume_increment: 0.05
volume_min: 0.4
volume_max: 1
on_announcement:
- nabu.set_ducking:
decibel_reduction: ${duck}
duration: 0.0s
on_state:
if:
condition:
and:
- switch.is_off: timer_ringing
- not:
voice_assistant.is_running:
- not:
lambda: return id(nabu_media_player)->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING;
then:
- nabu.set_ducking:
decibel_reduction: 0
duration: 1.0s
files:
- id: timer_finished_sound
file: https://github.com/esphome/home-assistant-voice-pe/raw/dev/sounds/timer_finished.flac
- id: wake_word_triggered_sound
file: https://github.com/esphome/home-assistant-voice-pe/raw/dev/sounds/wake_word_triggered.flac
- id: jack_connected_sound
file: https://github.com/esphome/home-assistant-voice-pe/raw/dev/sounds/jack_connected.flac
- id: jack_disconnected_sound
file: https://github.com/esphome/home-assistant-voice-pe/raw/dev/sounds/jack_disconnected.flac
micro_wake_word:
id: mww
microphone: mic0
models:
- model: hey_jarvis
id: hey_jarvis
- model: https://github.com/kahrendt/microWakeWord/releases/download/stop/stop.json
id: stop
internal: true
vad:
on_wake_word_detected:
# If a timer is ringing: Stop it, do not start the voice assistant (We can stop timer from voice!)
- if:
condition:
switch.is_on: timer_ringing
then:
- switch.turn_off: timer_ringing
# Start voice assistant, stop current announcement.
else:
- if:
condition:
lambda: return id(nabu_media_player)->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING;
then:
lambda: |-
id(nabu_media_player)
->make_call()
.set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_STOP)
.set_announcement(true)
.perform();
else:
- script.execute:
id: play_sound
priority: true
sound_file: !lambda return id(wake_word_triggered_sound);
- delay: 500ms
- voice_assistant.start:
voice_assistant:
id: va
microphone: mic1
media_player: nabu_media_player
micro_wake_word: mww
noise_suppression_level: 1
auto_gain: 31dBFS
volume_multiplier: 4.0
on_client_connected:
- lambda: id(init_in_progress) = false;
- script.execute:
id: play_sound
priority: true
sound_file: !lambda return id(jack_connected_sound);
- micro_wake_word.start:
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
on_client_disconnected:
- voice_assistant.stop:
- script.execute:
id: play_sound
priority: true
sound_file: !lambda return id(jack_disconnected_sound);
- lambda: id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
on_error:
- if:
condition:
and:
- lambda: return !id(init_in_progress);
- lambda: return code != "duplicate_wake_up_detected";
then:
- lambda: id(voice_assistant_phase) = ${voice_assist_error_phase_id};
# When the voice assistant starts: Play a wake up sound, duck audio.
on_start:
- nabu.set_ducking:
decibel_reduction: ${duck} # Number of dB quieter; higher implies more quiet, 0 implies full volume
duration: 0.0s # The duration of the transition (default is 0)
on_listening:
- lambda: id(voice_assistant_phase) = ${voice_assist_waiting_for_command_phase_id};
on_stt_vad_start:
- lambda: id(voice_assistant_phase) = ${voice_assist_listening_for_command_phase_id};
on_stt_vad_end:
- lambda: id(voice_assistant_phase) = ${voice_assist_thinking_phase_id};
on_tts_start:
- lambda: id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
# Start a script that would potentially enable the stop word if the response is longer than a second
- script.execute: activate_stop_word_if_tts_step_is_long
# When the voice assistant ends ...
on_end:
- wait_until:
not:
voice_assistant.is_running:
# Stop ducking audio.
- nabu.set_ducking:
decibel_reduction: 0 # 0 dB means no reduction
duration: 1.0s
# Stop the script that would potentially enable the stop word if the response is longer than a second
- script.stop: activate_stop_word_if_tts_step_is_long
# Disable the stop word (If the timer is not ringing)
- if:
condition:
switch.is_off: timer_ringing
then:
- lambda: id(stop).disable();
# If the end happened because of an error, let the error phase on for a second
- if:
condition:
lambda: return id(voice_assistant_phase) == ${voice_assist_error_phase_id};
then:
- delay: 1s
# Reset the voice assistant phase id and reset the LED animations.
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
on_timer_finished:
- switch.turn_on: timer_ringing
button:
- platform: restart
id: restart_btn
name: "${friendly_name} REBOOT"
switch:
# Internal switch to track when a timer is ringing on the device.
- platform: template
id: timer_ringing
optimistic: true
internal: true
restore_mode: ALWAYS_OFF
on_turn_off:
# Disable stop wake word
- lambda: id(stop).disable();
# Stop any current annoucement (ie: stop the timer ring mid playback)
- if:
condition:
lambda: return id(nabu_media_player)->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING;
then:
lambda: |-
id(nabu_media_player)
->make_call()
.set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_STOP)
.set_announcement(true)
.perform();
# Set back ducking ratio to zero
- nabu.set_ducking:
decibel_reduction: 0
duration: 1.0s
on_turn_on:
# Duck audio
- nabu.set_ducking:
decibel_reduction: ${duck}
duration: 0.0s
# Enable stop wake word
- lambda: id(stop).enable();
# Ring timer
- script.execute: ring_timer
# If 15 minutes have passed and the timer is still ringing, stop it.
- delay: 15min
- switch.turn_off: timer_ringing
# switch to charge tablet
- platform: gpio
name: ${device_name} charger
pin: ${pwr}
id: pwr
icon: mdi:charging_station
sensor:
- platform: homeassistant
entity_id: ${tablet_battery}
id: battery
internal: true
filters:
- heartbeat: 10s
on_value:
- if:
condition:
- lambda: "return id(battery).state < 30;" # '70' is the lower level, change if needed
then:
- switch.turn_on: pwr
else:
- if:
condition:
- lambda: "return id(battery).state > 80 ;" # '80' is the upper level, change if needed
then:
- switch.turn_off: pwr
script:
# Script executed when the timer is ringing, to playback sounds.
- id: ring_timer
then:
- script.execute:
id: timer_tts
- while:
condition:
switch.is_on: timer_ringing
then: # this is required to play the output on a media player
- script.execute:
id: play_sound
priority: true
sound_file: !lambda return id(timer_finished_sound);
- delay: 4s
- homeassistant.service:
service: assist_satellite.announce
data:
entity_id: assist_satellite.assist_media_player_kitchen_assist_satellite
message: !lambda return id(timer_tts_str);
- wait_until:
lambda: |-
return id(nabu_media_player)->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING;
- wait_until:
not:
lambda: |-
return id(nabu_media_player)->state == media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING;
# Script executed when we want to play sounds on the device.
- id: play_sound
parameters:
priority: bool
sound_file: "media_player::MediaFile*"
then:
- lambda: |-
if (priority) {
id(nabu_media_player)
->make_call()
.set_command(media_player::MediaPlayerCommand::MEDIA_PLAYER_COMMAND_STOP)
.set_announcement(true)
.perform();
}
if ( (id(nabu_media_player).state != media_player::MediaPlayerState::MEDIA_PLAYER_STATE_ANNOUNCING ) || priority) {
id(nabu_media_player)
->make_call()
.set_announcement(true)
.set_local_media_file(sound_file)
.perform();
}
# Script used to fetch the first active timer (Stored in global first_active_timer)
- id: fetch_first_active_timer
then:
- lambda: |
const auto timers = id(va).get_timers();
auto output_timer = timers.begin()->second;
for (auto &iterable_timer : timers) {
if (iterable_timer.second.is_active && iterable_timer.second.seconds_left <= output_timer.seconds_left) {
output_timer = iterable_timer.second;
}
}
id(first_active_timer) = output_timer;
# Script used to create TTS string for timer
- id: timer_tts
then:
- script.execute:
id: fetch_first_active_timer
- lambda: |-
std::string finished_timer_name = id(first_active_timer).name;
int total_seconds = id(first_active_timer).total_seconds;
// Variables for hours, minutes, and seconds
int hours = total_seconds / 3600;
int minutes = (total_seconds % 3600) / 60;
int seconds = total_seconds % 60;
std::string finished_timer_duration;
std::string result;
// If more than 1 hour
if (hours > 0) {
finished_timer_duration = std::to_string(hours) + " hour" + (hours > 1 ? "s" : "");
if (minutes > 0) {
finished_timer_duration += " " + std::to_string(minutes) + " minute" + (minutes > 1 ? "s" : "");
}
if (seconds > 0) {
finished_timer_duration += " " + std::to_string(seconds) + " second" + (seconds > 1 ? "s" : "");
}
}
// If less than 1 hour but more than 1 minute
else if (minutes > 0) {
finished_timer_duration = std::to_string(minutes) + " minute" + (minutes > 1 ? "s" : "");
if (seconds > 0) {
finished_timer_duration += " " + std::to_string(seconds) + " second" + (seconds > 1 ? "s" : "");
}
}
// If less than 1 minute
else {
finished_timer_duration = std::to_string(seconds) + " second" + (seconds > 1 ? "s" : "");
}
// Construct the final message
if (finished_timer_name.empty()) {
result = finished_timer_duration + "timer finished";
}
else {
result = finished_timer_name + "timer finished";
}
id(timer_tts_str) = result;
# Script used activate the stop word if the TTS step is long.
# Why is this wrapped on a script?
# Becasue we want to stop the sequence if the TTS step is faster than that.
# This allows us to prevent having the deactivation of the stop word before its own activation.
- id: activate_stop_word_if_tts_step_is_long
then:
- delay: 1s
# Enable stop wake word
- lambda: id(stop).enable();
It requires an ESP32S3
For my build I'm also using a MAX98357A with 2 Adafruit ICS43434. There should be enough GPIO to run everything on separate pins which is also necessary for proper operation.
That seems to have solved the issue. Thank you!