ESPHome offers a "no-code" solution for LEGO smart home integration. By defining your project in a YAML configuration file, you can create BLE clients that connect to LEGO hubs and expose them as Home Assistant entities—enabling voice control, automation routines, and integration with your entire smart home ecosystem.

Table of Contents

How It Works


┌──────────────┐      BLE      ┌──────────────┐
│ LEGO Powered │ ←──────────── │    ESP32     │
│   Up Hub     │               │  (ESPHome)   │
└──────────────┘               └──────┬───────┘
                                      │ WiFi
                                      ▼
                               ┌──────────────┐
                               │    Home      │
                               │  Assistant   │
                               └──────┬───────┘
                                      │
                      ┌───────────────┼───────────────┐
                      ▼               ▼               ▼
                 ┌────────┐     ┌──────────┐    ┌─────────┐
                 │ Alexa  │     │  Google  │    │ Automations │
                 │        │     │ Assistant│    │  & Scenes   │
                 └────────┘     └──────────┘    └─────────┘

Key Benefits

  • No Code: YAML configuration only
  • Auto-Discovery: Devices appear automatically in Home Assistant
  • Voice Control: "Alexa, start the LEGO train"
  • Automations: Time-based schedules, sensor triggers
  • OTA Updates: Update firmware over WiFi

ESPHome Setup

Install ESPHome

# Option 1: Home Assistant Add-on (easiest)
# Go to Supervisor → Add-on Store → ESPHome → Install

# Option 2: Command line
pip install esphome

# Verify installation
esphome version

Create New Device

# Create configuration file
esphome wizard lego-train.yaml

# Or use the ESPHome dashboard in Home Assistant

YAML Configuration

Basic LEGO Train Controller

# lego-train.yaml
esphome:
  name: lego-train-controller
  platform: ESP32
  board: m5stack-atom  # or your ESP32 board

wifi:
  ssid: "YourWiFiSSID"
  password: "YourWiFiPassword"

# Enable Home Assistant API
api:
  password: "your_api_password"

# Enable OTA updates
ota:
  password: "your_ota_password"

# Enable logging
logger:

# BLE Client for LEGO Hub
esp32_ble_tracker:

ble_client:
  - mac_address: "XX:XX:XX:XX:XX:XX"  # Your LEGO hub MAC address
    id: lego_hub

# Output for motor control
output:
  - platform: template
    id: train_motor
    type: float
    write_action:
      - lambda: |-
          // Send BLE command to LEGO hub
          // Motor speed: state * 100 (-1.0 to 1.0 → -100 to 100)
          int speed = (int)(state * 100);
          ESP_LOGD("lego", "Setting speed to %d", speed);

# Fan component (provides speed control UI)
fan:
  - platform: speed
    name: "LEGO Train"
    output: train_motor
    speed_count: 10

# Switch for simple on/off
switch:
  - platform: template
    name: "LEGO Train Power"
    id: train_power
    turn_on_action:
      - fan.turn_on:
          id: lego_train_fan
          speed: 50
    turn_off_action:
      - fan.turn_off: lego_train_fan

Finding Your Hub's MAC Address

# Add this to scan for nearby BLE devices
esp32_ble_tracker:
  scan_parameters:
    interval: 1100ms
    window: 1100ms

# Check ESPHome logs for discovered devices
# Look for "LEGO" in the device name

Advanced: Multiple Motors

# For Technic Hub with multiple ports
output:
  - platform: template
    id: motor_a
    type: float
    write_action:
      - lambda: |-
          // Port A motor control

  - platform: template
    id: motor_b
    type: float
    write_action:
      - lambda: |-
          // Port B motor control

fan:
  - platform: speed
    name: "Drive Motor"
    output: motor_a
    
  - platform: speed
    name: "Steering Motor"
    output: motor_b

Home Assistant Integration

Automatic Discovery

Once ESPHome is configured and connected, devices appear automatically in Home Assistant under Configuration → Integrations → ESPHome.

Dashboard Card

# Lovelace card for train control
type: entities
title: LEGO Train Control
entities:
  - entity: switch.lego_train_power
    name: Power
  - entity: fan.lego_train
    name: Speed Control
  - type: button
    name: Emergency Stop
    tap_action:
      action: call-service
      service: fan.turn_off
      target:
        entity_id: fan.lego_train

Voice Control

Alexa Integration

With Home Assistant Cloud (Nabu Casa) or manual Alexa skill:

  • "Alexa, turn on LEGO Train Power"
  • "Alexa, set LEGO Train to 50 percent"
  • "Alexa, turn off LEGO Train"

Google Assistant Integration

With Home Assistant Cloud or manual Google Actions:

  • "Hey Google, start the LEGO train"
  • "Hey Google, set LEGO train speed to 70%"
  • "Hey Google, stop the LEGO train"

Siri Shortcuts (iOS)

# Create a script in Home Assistant
script:
  start_lego_train:
    alias: "Start LEGO Train"
    sequence:
      - service: fan.turn_on
        target:
          entity_id: fan.lego_train
        data:
          percentage: 50

# Expose to Siri via HomeKit integration

Automation Ideas

1. Museum Display Schedule

# Run train during business hours
automation:
  - alias: "Start LEGO display at opening"
    trigger:
      - platform: time
        at: "09:00:00"
    condition:
      - condition: time
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.lego_train
        data:
          percentage: 40

  - alias: "Stop LEGO display at closing"
    trigger:
      - platform: time
        at: "17:00:00"
    action:
      - service: fan.turn_off
        target:
          entity_id: fan.lego_train

2. Motion-Activated Display

# Start train when someone approaches
automation:
  - alias: "Motion activates LEGO display"
    trigger:
      - platform: state
        entity_id: binary_sensor.display_motion
        to: "on"
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.lego_train
        data:
          percentage: 50
      - delay: "00:02:00"  # Run for 2 minutes
      - service: fan.turn_off
        target:
          entity_id: fan.lego_train

3. Holiday Train Schedule

# Christmas train runs in December
automation:
  - alias: "Holiday train schedule"
    trigger:
      - platform: time_pattern
        hours: "/1"  # Every hour
    condition:
      - condition: template
        value_template: "{{ now().month == 12 }}"
      - condition: time
        after: "08:00:00"
        before: "22:00:00"
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.christmas_train
        data:
          percentage: 35
      - delay: "00:10:00"  # Run 10 minutes
      - service: fan.turn_off
        target:
          entity_id: fan.christmas_train

4. Interactive LEGO City

# When doorbell rings, activate LEGO fire station
automation:
  - alias: "Doorbell triggers LEGO fire station"
    trigger:
      - platform: state
        entity_id: binary_sensor.doorbell
        to: "on"
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.lego_firetruck
      - service: light.turn_on
        target:
          entity_id: light.lego_fire_station_lights
        data:
          effect: "strobe"
      - delay: "00:00:30"
      - service: fan.turn_off
        target:
          entity_id: fan.lego_firetruck

Practical Use Cases

  • Automated Museum Displays: Train runs on schedule, no staff needed
  • Holiday Decorations: Christmas village with automated train
  • LEGO Store Displays: Motion-activated product demos
  • Interactive Dioramas: City responds to smart home events
  • Accessibility: Voice control for builders with mobility limitations

Resources