Skip to main content

Section 4: Extending ESPHome Configurations

Building on Section 3, this section covers how to extend ESPHome configurations for your own hardware: from consulting the official component documentation and adding new components, to configuration file organization and reusing community configurations.

1. Reading the ESPHome Official Documentation

Most ESPHome capabilities are provided by Components. For configuration details on each component, refer to the official documentation at esphome.io.

ESPHome Official Docs

1.1 Documentation Structure

The main entry point is the component index page esphome.io/components (page title: ESPHome Docs), which aggregates configuration guides, chip support information, and all components. The left sidebar is divided into several sections:

  • Getting Started — Installation, introduction, FAQ.
  • Components / All Components — Component index and full component list — used most frequently.
  • Automations — Automations, actions / triggers / conditions, templates, lambda.
  • Guides — YAML configuration, configuration types, and other basics.
  • Cookbook — Complete examples of combined usage.

On the component index page, components are grouped by functional category. Commonly used categories for beginners include:

CategoryYAML Top-Level KeyAppears in HA as
Sensor Componentssensor:Temperature, voltage, and other numeric entities
Binary Sensor Componentsbinary_sensor:Buttons, touch, and other "on/off" entities
Switch Componentsswitch:Relays, GPIO outputs
Light Componentslight:The RGB LED from Section 3
Display Componentsdisplay:Displays (don't directly generate entities — content drawn via lambda)
Climate / Cover / Fan …climate: / cover: / fan:Corresponding device cards

Categories are further subdivided. For example, Binary Sensor Components is split into Core, Capacitive Touch, Mechanical, NFC/RFID, and other subcategories — the GPIO button we'll use in Section 2.1 is under Binary Sensor → Core → GPIO.

1.2 How to Read a Component Page

Open a component page (e.g., esp32_rmt_led_strip used in Section 3). Component pages follow a consistent structure:

ESPHome Component Page Structure
  1. YAML example at the top — Can be used with minimal modifications; the fastest starting point.
  2. Configuration variables — Field-by-field descriptions, each noting:
    • Required or Optional;
    • Field type (e.g., Pin, Time — see Configuration Types) and default value.
  3. See Also — Related components and further reading.
tip

The official documentation is only available in English. Community translations exist but are typically behind on updates. Configuration field names should always follow the English originals. When translations are ambiguous, refer to the YAML examples on the English page.

2. Extending Configuration by Component Type

Below, we use the onboard BOOT button as an example to demonstrate the process from consulting documentation to writing a complete configuration. We then briefly introduce configuration patterns for other common component types.

2.1 BOOT Button

The ESP32-S3-Zero's BOOT button is connected to GPIO0. It is normally used to enter download mode, but can also function as a regular input button after firmware boots.

Here we use the gpio platform under binary_sensor (documentation).

Append the following to the end of the esp32-s3-zero device YAML created in Section 3:

binary_sensor:
- platform: gpio
name: "BOOT Button"
pin:
number: GPIO0
mode:
input: true
pullup: true
inverted: true

Field descriptions:

  • platform: gpio — Reads the high/low level of a GPIO pin.
  • pin.number: GPIO0 — The pin where the BOOT button is connected.
  • mode.pullup: true — Enables the internal pull-up; the pin stays high when the button is not pressed.
  • inverted: true — The BOOT button pulls the pin low when pressed; inverting makes "pressed = on," which is more intuitive.

After saving, flash via OTA (INSTALL → Wirelessly). After flashing, a BOOT Button entity will automatically appear on the HA device page, toggling between "off" and "on" when the BOOT button is pressed.

BOOT Button Entity in HA

The same approach applies to external buttons: simply change pin.number to the GPIO where the button is connected — all other fields remain the same.

note

GPIO0 is a strapping pin on the ESP32-S3: the chip samples its level at power-on to decide whether to enter run or download mode. Reading it as a normal input after boot is safe, but do not connect circuitry that pulls it low during reset, as this may cause the device to enter download mode instead of running firmware.

2.2 Common Component Types

Below are configuration snippets for other common peripheral types. The workflow for adding new peripherals follows the same pattern as the BOOT button in Section 2.1: find the corresponding component in the Components Directory → fill in required fields → name the entity with name. Replace pins and specific models according to your actual hardware.

Digital Output — Relay / Level Control (switch: gpio)

switch:
- platform: gpio
name: "Relay"
pin: GPIO2 # Replace with actual pin

Controls a GPIO's high/low level; appears as a switch in HA. See GPIO Switch.

Analog Input — Voltage Sensing (sensor: adc)

sensor:
- platform: adc
name: "Battery Voltage"
pin: GPIO1 # Replace with actual ADC pin
attenuation: 12db # Range — affects maximum measurable voltage
update_interval: 60s

Reads the pin voltage; appears as a numeric sensor in HA. See ADC Sensor.

I²C Sensors (Bus Declaration + Device)

Most temperature/humidity, barometric pressure, and light sensors use the I²C bus. Configuration has two steps: first declare an i2c: bus, then attach sensors under the corresponding platform.

# Step 1: Declare I²C bus (typically one per board)
i2c:
sda: GPIO8 # Replace with actual SDA pin
scl: GPIO9 # Replace with actual SCL pin
scan: true # Scans bus at boot, prints detected device addresses in LOGS

# Step 2: Attach device under sensor component (replace platform with actual sensor model)
sensor:
- platform: <sensor_component_name>
address: 0x40
update_interval: 60s
temperature:
name: "Temperature"
humidity:
name: "Humidity"

Which fields a specific sensor supports (address, which measurements to expose) is documented in its entry in the Sensor Components List. If scan: true doesn't detect the device, first check wiring, pull-up resistors, and the I²C address.

Display (display:)

Displays come in many varieties (OLED, LCD, e-Paper, etc.). They generally do not directly generate HA entities — content is drawn via lambda. Configuration is relatively complex. This section won't go into detail — look up your display's driver model in the Display Components documentation; Section 5 provides a complete RLCD display example.

3. Configuration File Organization

As you add more components, YAML files get longer and duplication increases. ESPHome provides several mechanisms for parameterization and splitting configurations.

3.1 substitutions: Parameterization

substitutions defines a set of variables, referenced in the configuration body via ${variable_name}. Change once, apply everywhere — ideal for values like pins and device names that appear repeatedly.

substitutions:
device_name: esp32-s3-zero
led_pin: GPIO21

esphome:
name: ${device_name}

light:
- platform: esp32_rmt_led_strip
pin: ${led_pin}
# …other fields same as Section 3

3.2 YAML Anchors: Snippet Reuse

YAML natively supports defining anchors with &name, referencing with *name, and using the merge key <<: to insert a set of fields into multiple locations — ideal for reusing "a group of identical fields."

sensor:
- platform: adc
pin: GPIO1
<<: &adc_defaults # Define anchor
update_interval: 60s
accuracy_decimals: 2
- platform: adc
pin: GPIO2
<<: *adc_defaults # Reuse the same set of fields

3.3 packages and !include: Multi-file Organization

!include inserts the contents of another YAML file verbatim at the current position; packages splits configurations into reusable "packages," especially useful when sharing the same base configuration across multiple devices.

# Device main configuration
packages:
wifi: !include common/wifi.yaml
base: !include common/base.yaml

Extract Wi-Fi, logging, OTA, and other sections that are identical across devices into a common/ directory. New devices simply reference them, avoiding duplication. See Packages and YAML Configuration.

3.4 external_components: Third-Party Components

When a hardware driver has not yet been merged into the official ESPHome release, you can use external_components to pull in community-written components from GitHub or other sources.

external_components:
- source: github://username/repo@branch
components: [ component_name ]

The RLCD-4.2 display used in Section 5, with its ST7305 driver, is introduced this way — a complete example will be provided there.

4. Introduction to Lambda

ESPHome's YAML is declarative — it describes "what exists," not "how to do it." When declarative syntax cannot express certain logic (e.g., custom conversions on readings, conditional triggering of actions), a small lambda snippet fills the gap.

Inside lambda, you write C++ code. The most common introductory use case is value conversion in sensor filters::

sensor:
- platform: adc
pin: GPIO1
name: "Light Level"
filters:
- lambda: |-
// x is the raw reading received at this stage; the return value is the converted result
return x * 100.0;
note

lambda is the gateway to advanced ESPHome usage, but it is essentially C++ — in-depth use requires some programming knowledge, which is beyond the scope of this introductory tutorial. Refer to Automations & Templates when needed.

5. devices.esphome.io and Community Configurations

devices.esphome.io is a community-maintained device configuration index with many ready-made ESPHome configurations for development boards and commercial devices — a good starting point when looking for existing configs.

When using community configurations, please note:

  • These configurations are community-contributed and not officially maintained by Waveshare. Quality varies and some may be outdated.
  • Pin definitions and component versions may not match your actual hardware or current ESPHome version.

Treat community configurations as references rather than drop-in solutions: after copying, review each component's fields against the official docs (Section 1), run Validate to check for errors, then flash and test.

6. Common Issues in This Section

  • Changed substitutions but no effect: Confirm the body uses ${variable_name} and the variable name spelling matches; the substitutions block must be at the configuration top level.
  • !include reports file not found: Paths are relative to the main configuration file's directory — note the common/wifi.yaml subdirectory syntax.
  • I²C sensor not detected in LOGS scan: Check if SDA/SCL are swapped, if pull-up resistors are missing, and if the address matches documentation. Enable scan: true first and check the actual addresses reported in logs.
  • external_components pull failed: Most likely the network cannot access GitHub, or the repository/branch name in source is incorrect.
  • Added component but no new entity appears in HA: Confirm flashing succeeded and the device is online. Only components with a name field generate entities — pure bus declarations (like i2c:) do not.

7. References