Configs are maps, not code
Open any solution config and you will find the same skeleton. Learn to recognize five blocks and no YAML will scare you again:
1. Identity & chip
esphome: # name, friendly_name, boot hooks
esp32: # board model + framework (esp-idf or arduino)
The sdkconfig_options under the framework are low-level chip switches — for example CONFIG_ESP_WIFI_CSI_ENABLED: "y" is the single line that unlocks WiFi sensing.
2. Connectivity
wifi: # credentials via !secret, power_save_mode
captive_portal: # fallback hotspot when WiFi fails
Watch for power_save_mode: none in sensing configs — CSI capture dies with power saving on.
3. Hardware buses
i2c: / spi: / uart: / i2s_audio:
These declare pins. When a config and your wiring disagree, the config wins — rewire, do not edit pins, unless you know the board differs.
4. Components (the actual features)
sensor:, camera:, display:, light: — and sometimes external_components: pointing at custom code shipped with the project (like latentfield_csi). If a config references external components, you need that folder next to the YAML.
5. Behavior
interval:, script:, on_boot: — small lambdas of C++ that run on a schedule. In the CSI node config, one 20 ms interval broadcasts mesh beacons and another streams JSON — that is the whole device behavior, readable in one screen.
The habit
Before flashing anything from the community: skim blocks 1–3 to check board + pins match your hardware, glance at block 5 to see what it does. Thirty seconds, every time.