AI assistant for ESPHome IoT firmware development with YAML configuration, C++ code generation, and multi-platform microcontroller support (ESP32, ESP8266, RP2040, LibreTiny).
An AI assistant for working with ESPHome, a system to configure microcontrollers (ESP32, ESP8266, RP2040, LibreTiny) using YAML configuration files that generate C++ firmware for home automation.
This skill helps you develop ESPHome components, write configuration schemas, generate C++ code, and maintain consistency with ESPHome's architectural patterns and coding standards.
When working with ESPHome code, follow these guidelines:
ESPHome uses a **code-generation architecture**:
**Core components:**
**Python:**
**C++:**
- Functions/methods/variables: `lower_snake_case`
- Classes/structs/enums: `UpperCamelCase`
- Top-level constants: `UPPER_SNAKE_CASE`
- Function-local constants: `lower_snake_case`
- Protected/private fields: `lower_snake_case_with_trailing_underscore_`
**Field Visibility:**
- Pointer lifetime issues (when setters validate pointers)
- Invariant coupling (synchronized fields like buffer size/data)
- Resource management (cleanup operations)
Standard component file structure:
```
components/[component_name]/
├── __init__.py # Configuration schema and code generation
├── [component].h # C++ header
├── [component].cpp # C++ implementation
└── [platform]/ # Platform-specific implementations
├── __init__.py
├── [platform].h
└── [platform].cpp
```
**Component metadata** (in `__init__.py`):
```python
DEPENDENCIES = ["required_component"]
AUTO_LOAD = ["auto_loaded_component"]
CONFLICTS_WITH = ["conflicting_component"]
CODEOWNERS = ["@github_username"]
MULTI_CONF = True # Allow multiple instances
```
```python
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_KEY, CONF_ID
CONF_PARAM = "param" # New constant not in esphome/const.py
my_component_ns = cg.esphome_ns.namespace("my_component")
MyComponent = my_component_ns.class_("MyComponent", cg.Component)
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(MyComponent),
cv.Required(CONF_KEY): cv.string,
cv.Optional(CONF_PARAM, default=42): cv.int_,
}).extend(cv.COMPONENT_SCHEMA)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
cg.add(var.set_key(config[CONF_KEY]))
cg.add(var.set_param(config[CONF_PARAM]))
```
**Common validators:**
```cpp
namespace esphome::my_component {
class MyComponent : public Component {
public:
void setup() override;
void loop() override;
void dump_config() override;
void set_key(const std::string &key) { this->key_ = key; }
void set_param(int param) { this->param_ = param; }
protected:
std::string key_;
int param_{0};
};
} // namespace esphome::my_component
```
**Sensor:**
```python
from esphome.components import sensor
CONFIG_SCHEMA = sensor.sensor_schema(MySensor).extend(
cv.polling_component_schema("60s")
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
```
**Binary Sensor:**
```python
from esphome.components import binary_sensor
CONFIG_SCHEMA = binary_sensor.binary_sensor_schema().extend({ ... })
async def to_code(config):
var = await binary_sensor.new_binary_sensor(config)
```
**Switch:**
```python
from esphome.components import switch
CONFIG_SCHEMA = switch.switch_schema().extend({ ... })
async def to_code(config):
var = await switch.new_switch(config)
```
**Setup:**
**Testing:**
**Key files:**
**Creating a new sensor component:**
1. Create directory structure under `esphome/components/`
2. Write Python configuration schema with proper validators
3. Implement C++ class inheriting from appropriate base class
4. Add component metadata (DEPENDENCIES, CODEOWNERS, etc.)
5. Test with `script/test_build_components -c your_component`
**Adding platform-specific code:**
1. Create platform subdirectory (e.g., `esp32/`)
2. Use platform validators: `cv.only_on_esp32` or `esp32.only_on_variant(...)`
3. Implement platform-specific C++ in separate files
4. Test on target platform
**Validating configuration:**
1. Use appropriate validators from `esphome.config_validation`
2. Extend schemas: `.extend(cv.COMPONENT_SCHEMA)`, `.extend(uart.UART_DEVICE_SCHEMA)`
3. Add custom validation with `cv.All()` or `cv.Any()`
4. Test with component tests in `tests/components/`
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/esphome-copilot-assistant/raw