Touch Panel Manager — Dynamic multi-page mobile panel using Waveshare ESP32-S3 3.49" LCD

Hi everyone,

I've been building a smart-home control panel based on the Waveshare ESP32-S3-Touch-LCD-3.49 (that long thin 172×640 portrait display), and I'm at a point where it's stable enough to share for feedback.

The piece I'm most happy with: everything is configured from the Home Assistant UI — no YAML editing, no re-flashing. You pick entities for each slot in a normal HA config flow, save, and the panel updates in real time. Add a new page in HA, swipe on the device → there it is.

What it does

  • :artist_palette: Up to 50 pages × 8 slots per panel, all configured via HA UI
  • :radio_button: Drop in any light, switch, scene, script, automation, fan, cover, media_player — service dispatch is auto (toggle vs turn_on by domain)
  • :thermometer: Drop in any sensor or binary_sensor and the slot becomes a live value display with auto-formatted units (22.3°C, 45%)
  • :bullseye: MDI icons chosen automatically by domain + device_class (lightbulb / switch / thermometer / humidity drop / motion / flash …)
  • :yellow_circle: Buttons turn yellow when entity is on; lights also show brightness % in the sub-line
  • :triangular_ruler: Auto rotation via the onboard QMI8658 IMU — portrait shows the controller, landscape shows a big clock + outdoor/indoor temps dashboard
  • :backhand_index_pointing_up: Tap or swipe between pages (with motion-aware click guard so swipes don't trigger buttons)
  • :battery: Battery operation — 18650 with hardware power latch (TCA9554 pin 6), live voltage + %, color-coded bar (green / yellow / red)
  • :globe_showing_europe_africa: English UI, Turkish translation included, easy to add more

The integration

This is a proper HA custom integration (touch_panel_manager), not just an ESPHome YAML. It exposes:

  • One sensor.<panel>_config with all per-slot attributes (entity, label, icon, text, type)
  • Two temperature proxies that mirror the configured outdoor/indoor sensors
  • Eight binary_sensor.<panel>_slot_N_state that proxy the on/off of whatever entity is in that slot, on the current page
  • A panel_action(entity_id) dispatcher service used by the panel for taps
  • A set_current_page(config_entity_id, page_index) service used by the panel for navigation

ESPHome just subscribes to attributes and renders. The panel never stores config locally → editing in HA propagates in milliseconds.

Screenshots & demo

Repo has SVG mockups of both views and a short demo video showing the live UI:

Install

Full instructions in the GitHub repo. Briefly:

  1. Add the custom_components/touch_panel_manager folder to your HA config (or install via HACS custom repo)
  2. Add a "Touch Panel Manager" device in HA, configure pages
  3. Flash the ESPHome YAML to the Waveshare board, point its panel_config_entity substitution to your device's config sensor
  4. HA auto-discovers the ESPHome device, you're done

Feedback I'd love

  • Anyone else running this hardware — do the AXS15231 display config and the I2C bus assignments work on yours? (The display chip is a bit finicky with 172-wide; I use full_refresh: true to dodge the tearing)
  • HA integration patterns — is exposing the config as sensor.attributes reasonable, or would you do this differently? Considered SubConfigEntry but went with menu-driven options flow for max compatibility
  • UI suggestions — long-press → brightness slider, status bar on portrait, and more dashboard widgets (weather/calendar) are on the roadmap. What would you add?
  • Bugs and edge cases — multi-page with empty slots, page reordering, etc. There's a known minor pixel artifact at column 171 (panel width 172 isn't 8-divisible).

Repo: GitHub - cryptooth/homeassistant-waveshare-lcd349: Multi-page touch control panel for Home Assistant on Waveshare ESP32-S3 3.49 inch display · GitHub

MIT licensed, PRs welcome. Built over a weekend of late-night ESPHome + LVGL + Python wrangling :slightly_smiling_face:

Thanks for taking a look!

1 Like