Skip to content

iBrewerRoot/ESPanelHA

Repository files navigation

ESPanelHA logo

ESPanelHA

ESP32 AMOLED touch panel for Home Assistant

Turn a Waveshare AMOLED touch display into a polished, real‑time Home Assistant wall panel.

WiFi + HA onboarding, automatic entity discovery, a WYSIWYG web editor to design your screens, and tactile control with live state — all from a single multi‑board firmware.


Platform MCU UI Home Assistant Status

ESPanelHA running on a Waveshare ESP32-S3 AMOLED panel


✨ Features

  • Real‑time control over Home Assistant's native WebSocket API. Tap a tile and HA reacts instantly; changes made elsewhere reflect on screen.
  • 🔍 Automatic entity discovery — lights, switches and sensors show up on their own.
  • 🖱️ WYSIWYG web editor — design multi‑page screens from your browser; the canvas is a pixel‑faithful, drag‑and‑drop replica of the actual panel.
  • 📱 Swipeable multi‑page dashboard and a pull‑down settings menu with quick‑settings tiles.
  • 🔁 Orientation & adaptive grid — pick any of the 4 screen orientations (portrait or landscape for wall mounting), rotate it live from the settings menu or auto‑rotate via the motion sensor (IMU); the grid's column count is configurable per orientation, capped to what the panel size allows.
  • 🧩 Multi‑board HAL — the same app runs across different Waveshare panels; only a board profile changes.
  • 🔐 ws:// or wss:// (TLS) — insecure TLS mode for trusted LANs, self‑signed HA certs and Nabu Casa.
  • 🔄 Browser OTA updates from the config portal.
  • 🧵 Cooperative, non‑blocking loop — runs on single‑core C6 and dual‑core S3 alike.

🖼️ Screenshots

Dashboard Web editor (WYSIWYG) Settings
Dashboard Web editor Settings

🧰 Supported hardware

Board Resolution Display Touch Status
ESP32‑S3 Touch AMOLED 1.8" 368×448 CO5300 (QSPI) CST816 @0x15 ✅ Reference (validated)
ESP32‑C6 Touch AMOLED 1.8" 368×448 SH8601 (QSPI) FT3168 @0x38 🟡 Profile ready (untested)
2.16" / 1.75" / 2.41" 480×480 / 466×466 / 536×240 CO5300 / RM690B0 TBD 🔭 Planned
Hardware notes (pins, reset, board revisions)
  • Pins, controllers and the I/O‑expander mapping are verified against Waveshare's official demo code (pin_config.h + GFX examples). The S3 and C6 1.8" boards differ on both controllers (display and touch) and on pinout — the HAL absorbs this through per‑board profiles.
  • Screen/touch reset is not on a GPIO but on a TCA9554 I/O expander (@0x20, EXIO 0/1/2, shared I²C bus). Tca9554 issues the reset sequence before panel init (Display.cppresetPanel()).
  • The S3 1.8" carries a QMI8658 6‑axis IMU (@0x6B, shared I²C bus) used for auto‑rotation (Imu.cpp). It's board‑gated (BOARD_HAS_IMU): boards without a sensor compile to no‑op stubs and simply hide the auto‑rotate control.
  • These QSPI AMOLED controllers don't support hardware rotation (the driver only flips axes), so the panel stays native and the firmware rotates pixels in software in the flush callback, with touch remapped to match. Flush areas are even‑aligned (the panels address pixels in pairs) to avoid shearing while scrolling in landscape.
  • ⚠️ A v1 revision of the S3 1.8" uses SH8601 + FT3168 (@0x38). The boot‑time I²C scan (-D DEBUG_I2C_SCAN, on by default for S3) tells them apart: 0x15 ⇒ CST816 (current profile), 0x38 ⇒ FT3168 (switch DISPLAY_DRIVER_* and TOUCH_I2C_ADDR).

🏗️ Architecture

Independent layers — the application never depends on a specific board:

ui/    (LVGL)         boot / setup / dashboard / settings screens, responsive
ha/    (HAClient)     native HA WebSocket API + EntityStore (state model)
net/   (WiFi/portal)  WiFiManager + web config portal + NVS/LittleFS storage
board/ (HAL)          BoardConfig + Display (Arduino_GFX) + Touch (ITouch)
core/                 shared config types

Single source of truth: dashboard geometry and style live in ui::DashboardSpec (UiTheme.h). The device renders from it and the config portal serves the same values at GET /api/device, so the browser preview can never drift from the real screen.

Generated assets: the Material Design icon font, the web SVG icon sprite, and the accented Montserrat text fonts are all produced from scripts/mdi-font (npm run gen) — see Regenerating icons & fonts.


🚀 Build & flash

Platform: pioarduino (Arduino‑ESP32 3.x / IDF 5.x, required for the C6).

# Reference board (S3 1.8")
pio run -e s3_amoled_18
pio run -e s3_amoled_18 -t upload -t monitor

# Other board
pio run -e c6_amoled_18 -t upload

💡 Dev shortcut: create include/secrets.h (gitignored, see secrets.h.example) with WIFI_SSID/WIFI_PASS (and optionally HA_HOST/HA_PORT/HA_TOKEN) to skip the portal and connect directly — handy for hidden SSIDs and iterating quickly.


📲 First‑time setup

  1. On first boot the screen shows “Setup required” and the board opens a WiFi access point: ESPanelHA‑Setup.
  2. Connect to it — the captive portal opens. Enter your WiFi, then your Home Assistant host/IP, port, a long‑lived access token, and tick “Use HTTPS/WSS (TLS)” if HA is exposed over HTTPS. (Token: HA profile → Long‑lived access tokens → Create token.)
  3. The panel connects to HA and discovers light / switch / sensor entities.
  4. Open http://<panel-ip>/ to design your screens in the web editor (pick entities, arrange tiles, set sizes and labels).
  5. Save — the dashboard appears. Toggles and sliders drive HA in real time; pull down for the settings menu (rotate the screen, toggle IMU auto‑rotate).

🎛️ Web editor

The config portal hosts a WYSIWYG dashboard editor: the canvas is a scaled, pixel‑faithful replica of the device screen that adapts to each board's resolution. Click an entity to place it, drag tiles to reorder (with a live ghost + re‑pack), pick tile sizes (1×1 / 2×1 / 1×2 / 2×2), set per‑tile labels, and manage swipe pages — all rendered exactly as the panel will show them, even offline in AP mode.

A Display card in Settings sets the orientation and the column count per orientation (bounded by the auto‑detected maximum), plus the IMU auto‑rotate toggle. The preview rotates and re‑flows to match, so the editor always mirrors the live screen.


➕ Adding a board

  1. src/board/profiles/<name>.h — geometry, pins, display/touch drivers, expander.
  2. A branch in src/board/BoardConfig.h.
  3. An [env:<name>] in platformio.ini with -D BOARD_<NAME>.
  4. New touch controller? Add an ITouch implementation in Touch.cpp.

No changes to ui/, ha/ or net/ are required.


🎨 Regenerating icons & fonts

Icons and accented text fonts are generated, not hand‑edited. After changing the icon set or text sizes:

cd scripts/mdi-font
npm install        # first time
npm run gen        # regenerates the MDI font, name↔glyph headers,
                   # the web SVG sprite, and the Montserrat FR fonts

To add an icon, append its MDI name to scripts/mdi-font/icons.txt and re‑run npm run gen.


🗺️ Roadmap

  • MVP — lights (on/off + brightness), switches, and sensors (read‑only); real‑time WebSocket; multi‑page WYSIWYG editor; settings menu; OTA.
  • Orientation & adaptive grid — 4 orientations, live rotation, IMU auto‑rotate, configurable columns per orientation.
  • 🔭 Next — color picker for RGB lights, scenes & scripts, more settings‑menu controls, additional Waveshare panels, single‑TLS refactor & portal auth hardening.

🙌 Built with

LVGL · Arduino_GFX · ArduinoJson · WiFiManager · ESPAsyncWebServer · Material Design Icons · Montserrat


📄 License

This project's source code is released under the MIT License — see LICENSE.

Bundled fonts and icons keep their own licenses: Montserrat under the SIL Open Font License (OFL.txt) and Material Design Icons under Apache-2.0. Full attribution for these and all dependencies is in THIRD_PARTY_NOTICES.md.

About

Control panel for Home Assistant with an ESP32 touchscreen. Multi-board firmware for Waveshare AMOLED touchscreens.

Resources

License

MIT, OFL-1.1 licenses found

Licenses found

MIT
LICENSE
OFL-1.1
OFL.txt

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors