-
Notifications
You must be signed in to change notification settings - Fork 9
Customization
After adopting your device in ESPHome, you have full control over its configuration. This guide covers common customization scenarios.
- Editing Your Configuration
- Display Configuration
- Adding & Removing Pages
- Multiple Page Instances
- WizMote Remote Control
- Substitutions & Variables
- Secrets Management
- Package System
After adopting your device, you can customize it by editing its YAML configuration file in ESPHome.
Common Customizations:
- Display size and layout
- Weather entities and units
- Presence / alarm entities
- DDP / WebSocket streaming host/ports
- Device-specific toggles for pages/effects
- WizMote remote control
Accessing Your Configuration:
- Open Home Assistant
- Navigate to Settings → Add-ons → ESPHome
- Click OPEN WEB UI
- Find your device and click EDIT
Update the display dimensions in your device configuration:
substitutions:
DISPLAY_W: "64" # Display width in pixels
DISPLAY_H: "64" # Display height in pixels
DISPLAY_CHAIN_LEN: "1" # Number of chained panelsCommon Configurations:
- Single 64×64 panel:
W=64, H=64, CHAIN=1 - Two 64×32 panels (horizontal):
W=128, H=32, CHAIN=2 - Two 64×64 panels (horizontal):
W=128, H=64, CHAIN=2
Non-Horizontal Layouts (2×2, Vertical, etc.):
For non-horizontal panel layouts (like a 2×2 grid or vertical stack), uncomment the virtual matrix configuration at the bottom of your non-factory config file:
substitutions:
DISPLAY_W: "128" # Total width
DISPLAY_H: "128" # Total height
DISPLAY_CHAIN_LEN: "4" # Number of panels
# Uncomment this section in your config:
display:
- id: !extend matrix
virtual_matrix:
enabled: true
rows: 2 # Number of panel rows
cols: 2 # Number of panel columns
chain_type: CHAIN_TOP_LEFT_DOWN # Layout mapping type
scan_type: STANDARD_TWO_SCAN # Typical scan typeCommon chain_type values:
-
CHAIN_TOP_LEFT_DOWN- Starts top-left, goes down first column, then next -
CHAIN_BOTTOM_RIGHT_UP- Starts bottom-right, goes up -
CHAIN_TOP_RIGHT_DOWN- Starts top-right, goes down
Note: Virtual matrix maps your linear panel chain to a 2D grid. Adjust
rows,cols, andchain_typeto match your physical layout.
To add a new page to your configuration:
- Open your device config in ESPHome
- Locate the
packagessection withremote_package_files - Add a new page entry under
files:
packages:
remote_package_files:
url: https://github.com/stuartparmenter/hub75-studio
ref: main
files:
# ... existing pages ...
# Add new page
- path: packages/pages/clock.yaml
vars:
page_friendly_name: "Clock"- Click SAVE and INSTALL to apply changes
To remove a page, simply delete or comment out its entry:
# Removed Clock page
# - path: packages/pages/clock.yaml
# vars:
# page_friendly_name: "Clock"Some pages are included but commented out by default. To enable them, uncomment the entry and fill in required variables:
# Now Playing page (uncomment and configure)
- path: packages/pages/now-playing.yaml
vars:
uid: "living_room"
page_friendly_name: "Now Playing - Living Room"
ha_base_url: "http://homeassistant.local:8123"
media_player_entity: "media_player.living_room"Pages marked with ⚡ support multiple instances. Each instance requires a unique uid.
packages:
remote_package_files:
files:
# Atlanta Falcons
- path: packages/pages/teamtracker.yaml
vars:
uid: "falcons"
page_friendly_name: "Team Tracker - Falcons"
entity_id: "sensor.team_tracker_nfl_atl"
# Manchester United
- path: packages/pages/teamtracker.yaml
vars:
uid: "manutd"
page_friendly_name: "Team Tracker - Man United"
entity_id: "sensor.team_tracker_epl_manu"
# Boston Celtics
- path: packages/pages/teamtracker.yaml
vars:
uid: "celtics"
page_friendly_name: "Team Tracker - Celtics"
entity_id: "sensor.team_tracker_nba_bos"- path: packages/pages/now-playing.yaml
vars:
uid: "living_room"
page_friendly_name: "Now Playing - Living Room"
ha_base_url: "http://homeassistant.local:8123"
media_player_entity: "media_player.living_room"
- path: packages/pages/now-playing.yaml
vars:
uid: "bedroom"
page_friendly_name: "Now Playing - Bedroom"
ha_base_url: "http://homeassistant.local:8123"
media_player_entity: "media_player.bedroom"Pages Supporting Multiple Instances:
- Now Playing (unique
uidper media player) - Team Tracker (unique
uidper team) - Countdown Timer (unique
uidper timer) - QR Code (unique
uidper code)
Control your display with a WizMote remote using ESPHome's built-in ESP-NOW protocol (requires ESPHome 2025.8+).
-
Include WizMote Package in your configuration:
packages: remote_package_files: files: - path: packages/common/wizmote.yaml
-
Flash your device
-
Enable Auto-Discovery in Home Assistant:
- Find the "WizMote Auto-Discovery" switch
- Turn it ON
- Press any button on your WizMote
- MAC is auto-discovered and paired
-
Done! Check "WizMote Status" entity to confirm pairing
Power & Brightness:
- Buttons 1/2: Display on/off
- Buttons 8/9: Brightness down/up
- Button 3: Night mode (minimum brightness)
Page Navigation:
- Buttons 16-19: Jump to configured pages
Map buttons to your pages by setting page IDs:
- path: packages/common/wizmote.yaml
vars:
wizmote_page_1: "page_clock_dashboard" # Button 16
wizmote_page_2: "fx_page" # Button 17
wizmote_page_3: "page_pong" # Button 18
wizmote_page_4: "ddp_video" # Button 19Common Page IDs:
-
page_time_date,page_clock_dashboard,fx_page,fx_as_page,page_pong,page_balls,ddp_video,radar - Multi-instance pages:
page_now_playing_${uid},teamtracker_${uid},page_timer${uid},qr_${uid}
Adjust brightness behavior via substitutions:
substitutions:
WIZMOTE_BRIGHTNESS_STEP: "15" # Step percentage (default: 10)
WIZMOTE_BRIGHTNESS_MIN_STEP: "5" # Minimum step value (default: 5)
WIZMOTE_BRIGHTNESS_NIGHT: "30" # Night mode level (default: 20)
WIZMOTE_DEBOUNCE_MS: "300" # Debounce timeout (default: 200)WizMote not responding:
- Check "WizMote Status" entity (should show "✅ Paired: aa:bb:cc:dd:ee:ff")
- Verify ESPHome 2025.8+ installed
- Try clearing pairing (troubleshooting entity, disabled by default) and re-pairing
Buttons not working:
- Verify page IDs match your actual pages
- Check ESPHome logs for errors
Substitutions are device-wide configuration values defined at the top of your config:
substitutions:
# Device Info
devicename: "hub75-studio"
friendly_name: "HUB75 Matrix"
# Display Settings
DISPLAY_W: "64"
DISPLAY_H: "64"
DISPLAY_BRIGHTNESS: "128"
# Network
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_passwordEach page accepts specific variables via the vars section:
- path: packages/pages/clock-dashboard.yaml
vars:
page_friendly_name: "Clock Dashboard"
weather_entity: "weather.home"
high_entity: "sensor.weather_today_high"
low_entity: "sensor.weather_today_low"
# ... more page-specific varsSee the Pages & Applications guide for required variables for each page.
Sensitive information should be stored in secrets.yaml and referenced in your config.
- In ESPHome Dashboard, click the three dots (⋮) next to your device
- Select Show Secrets
- Add your secrets:
# secrets.yaml
wifi_ssid: "MyNetwork"
wifi_password: "MySecurePassword"
ha_api_token: "long_lived_access_token_here"Reference secrets in your configuration using !secret:
substitutions:
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
# Or in page vars
- path: packages/pages/now-playing.yaml
vars:
ha_base_url: !secret ha_base_url
media_player_entity: "media_player.living_room"Important:
- Never commit
secrets.yamlto version control - Keep entity IDs and personal information in your local device config
- ESPHome automatically excludes secrets from logs
HUB75 Studio uses ESPHome's package system for modularity. Understanding this helps with advanced customization.
hub75-studio/
├─ packages/
│ ├─ common/
│ │ ├─ theme.yaml # LVGL theme (fonts + colors)
│ │ ├─ ddp.yaml # DDP streaming functionality
│ │ ├─ utils.yaml # Common utilities
│ │ └─ wizmote.yaml # WizMote remote control
│ ├─ controllers/
│ │ ├─ apollo-automation-m1-rev4.yaml
│ │ ├─ apollo-automation-m1-rev6.yaml
│ │ └─ adafruit-matrix-portal-s3.yaml
│ └─ pages/ # Individual page implementations
HUB75 Studio configurations pull packages from GitHub:
packages:
remote_package_files:
url: https://github.com/stuartparmenter/hub75-studio
ref: main # Can be a branch, tag, or commit SHA
refresh: 1d # Refresh cache every day
files:
- path: packages/common/theme.yaml
- path: packages/common/ddp.yaml
# ... more packagesBest Practices:
- Use
ref: mainfor latest features (auto-updates) - Use
ref: v0.6.0for stable releases (no auto-updates) - Use commit SHAs for reproducible builds
You can also use local packages for custom modifications:
packages:
local_packages:
- !include packages/my-custom-page.yamlOverride theme colors and fonts by modifying the theme package or creating custom styles.
Add your own visual effects by creating a custom page package that uses the LVGL canvas effects library.
Run multiple HUB75 Studio devices and synchronize content using DDP streaming.
substitutions:
devicename: "home-dashboard"
friendly_name: "Home Dashboard"
DISPLAY_W: "128"
DISPLAY_H: "64"
packages:
remote_package_files:
url: https://github.com/stuartparmenter/hub75-studio
ref: main
files:
# Core packages
- path: packages/common/theme.yaml
- path: packages/common/wizmote.yaml
vars:
wizmote_page_1: "page_clock_dashboard"
wizmote_page_2: "fx_page"
wizmote_page_3: "teamtracker_falcons"
# Pages
- path: packages/pages/clock-dashboard.yaml
vars:
page_friendly_name: "Dashboard"
weather_entity: "weather.home"
high_entity: "sensor.weather_today_high"
low_entity: "sensor.weather_today_low"
alarm_entity: "alarm_control_panel.home"
person_a: "person.alice"
person_b: "person.bob"
person_a_icon: "\U000F040A"
person_b_icon: "\U000F0B8F"
- path: packages/pages/fx.yaml
vars:
page_friendly_name: "Effects"
- path: packages/pages/teamtracker.yaml
vars:
uid: "falcons"
page_friendly_name: "Falcons"
entity_id: "sensor.team_tracker_nfl_atl"- Installation: See Installation Guide
- Page Reference: See Pages & Applications
- Problems: See Troubleshooting
- Questions: Visit GitHub Discussions