A far-field microphone that actually hears you across a room, wired into Home Assistant’s voice pipeline with ESPHome — and a device file only forty lines long, because a community packages architecture carries everything else. This is the build we run in three rooms: the hardware, the config, the flash, and the lessons that only show up once two of them share a ceiling.
The ReSpeaker XVF3800 pairs a four-microphone circular array with an XMOS voice DSP that does echo cancellation, beamforming and noise suppression in hardware, before the audio ever reaches the microcontroller. In practice that is the difference between a satellite that hears the wake word over its own music and one that goes deaf the moment anything plays. The attached XIAO ESP32-S3 runs ESPHome, so the whole thing shows up in Home Assistant as a native voice assistant device — wake word on the device, audio streamed to whatever speech-to-text your pipeline uses, reply played back through a speaker on the board’s amplifier output. Nothing leaves the building.
Driving the XVF3800 from ESPHome takes real code — custom components for the DSP, the LED ring, timers, the voice-assistant glue. None of it belongs in your config. The formatBCE Respeaker-XVF3800-ESPHome-integration project packages all of it as remote ESPHome packages: your device file names the repository, a list of package files, and a commit hash — and ESPHome assembles the rest at build time. The hash is the discipline that makes this safe: one ref selects the YAML packages, the C++ components and the XMOS DFU firmware together, so every satellite builds reproducibly from the same upstream state, and upstream can refactor all it likes without touching your rooms until you choose to move the pin.
# =============================================================================
# ReSpeaker satellite — device file (formatBCE packages architecture)
# Everything except the settings below comes from the upstream packages.
# =============================================================================
substitutions:
name: respeaker-living-room
friendly_name: ReSpeaker Living Room
# Pin to an exact upstream commit. This one ref selects the YAML packages,
# the C++ components AND the XMOS DFU firmware together, so every satellite
# builds reproducibly from this exact upstream state. To take a future
# upstream update: check the repo's commits page, replace the hash,
# reflash ONE satellite first and live with it for a day.
respeaker_ref: d52dd1acc740c1ceeb2c61ce1299341f808c808c
packages:
respeaker:
url: https://github.com/formatBCE/Respeaker-XVF3800-ESPHome-integration
ref: ${respeaker_ref}
refresh: 1d
files:
- packages/base.yaml
- packages/hardware.yaml
- packages/voice-assistant.yaml
- packages/leds.yaml
- packages/timers-alarm.yaml
# A remote package cannot read your secrets, so credentials live here.
# ESPHome merges these blocks with the packages' own wifi/api/ota blocks.
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# api encryption can be added once the build is settled — one change per
# flash. When everything works, add:
# api:
# encryption:
# key: !secret api_key
# (generate a key, add api_key to secrets.yaml, reflash, re-enter in HA)
ota:
- platform: esphome
id: ota_esphome
password: !secret ota_passwordwifi_ssid: "YourNetwork"
wifi_password: "your-wifi-password"
ota_password: "a-long-random-string"name and friendly_name — the pin keeps
every room on the same build.