EsphoMaTrix
A simple DIY status display with an 8x32 RGB LED panel implemented with esphome.io and Home Assistant
Install / Use
/learn @lubeda/EsphoMaTrixREADME
Important news
Take a look at the new version of the improved EspHoMaTriXv2!!!
This version is read-only!!!!
EspHoMaTriX (ehmtx)
Breaking changes in esphome 2023.7.0
Since the update ehmtx only compiles if you add some code to your yaml. See here: https://github.com/lubeda/EspHoMaTriXv2/issues/62#issuecomment-1643052894
Important information
If you like my work, please donate me a star on GitHub and consider sponsoring me!!
Introduction
A simple DIY status display, built with a flexible 8x32 RGB LED panel implemented with esphome.io

There are some “RGB-matrix” status displays/clocks out there, the commercial one from LaMetric and some excellent DIY-alternatives.
- LaMetric commercial ~ €199
- Ulanzi TC001 commercial ~ €50
- Awtrix (project has been discontinued after more than 4 years now in August 2022)
- PixelIt (project is under active development)
- Awtrix-Light From the developer of Awtrix, optimized for the Ulanzi TC001 Hardware
The other DIY solutions have their pros and cons. I tried some and used AwTrix for a long time. But the cons are so big (in my opinion) that I started an esphome.io variant targeted to an optimized Home Assistant integration. The main reason, for me, is the Home Assistant integration!
There is a little hype around the Ulanzi TC001 pixel clock. This hardware can be used with EspHoMaTriX (with some limitations). You can connect the device and flash it via USB-C. As a starting point, you can use the
UlanziTC001.yaml. Yet, the LDR and battery sensor are not perfectly supported. For another use of the hardware, see PixelIT_Ulanzi or AWTRIX-LIGHT firmware.
ehmtx in the media
See this German tutorial video with information on setting up your display RGB-LED Status Display für Home Assistant mit ESPHome | ESPHoMaTrix. Another german tutorial video focused at the Ulanzi Smarte Pixel Clock über Home Assistant steuern - Entitäten / Icons und mehr in der Ulanzi See this nice article about EsphoMaTrix on an Ulanzi TC001 from blakadder. Short video on Instagram @blak_adder https://www.instagram.com/reel/CpYVByRIaSI See these English discussions: Share your projects ESPHOME Or in German: Showroom
State
It is a working solution with core functionality coded. Advanced features, like automatic brightness control, can be done with esphome actions and automations. The possibilities are endless.
Features
Based on a 8x32 RGB flexible matrix, it displays a clock, the date and up to 24 other 'screens' provided by Home Assistant. Each screen (value/text) can be associated with a 8x8 bit RGB icon or GIF animation (see installation). The values/text can be updated or deleted from the display queue. Each screen has a lifetime, if not refreshed in its lifetime, it will disappear. When a screen is active, it is displayed so that the text can scroll twice (scroll_count) or even longer for screen_time seconds.
You can use the fullfeature.yaml as a sample for an ESP8266. As mentioned, you have to edit to your needs. So check font, icons, board and the GPIO pins for your display.
The file ulanziTC001.yaml uses the functions ehmtx provides, optimized for the Ulanzi Hardware.
See it in action on YouTube (no sound but subtitles).
Installation
EsphoMaTrix custom component
EsphoMaTrix is a custom component, you have to include it in your YAML configuration. To always use the newest features, you should use the repo, to use a stable version you copy a working version to your esphome installation.
local use
If you download the components-folder from the repo and install it in your esphome you have a stable installation. But if there are new features, you won't see them. If needed, customize the YAML to your folder structure.
external_components:
- source:
type: local
path: components # e.g. /config/esphome/components
use from repo
Use the GitHub repo as a component. Esphome refreshes the external components “only” once a day, perhaps you have to refresh it manually. In this mode, there may be breaking changes, so read the changelog and check the logs while installing the firmware.
external_components:
- source:
type: git
url: https://github.com/lubeda/EsphoMaTrix
ref: main # optional select a special branch or tag
Addressable_light component
The EsphoMaTrix component requires a 8x32 pixel addressable_light, it is referenced by the ID matrix_component.
See the default options
There are some different matrices-types on the market, to adapt them to EspHoMaTriX you have to find the proper pixel mapper. If there is garbage on your display, try the other pixel_mapper. Here are the most common types for flexible 8x32 matrices:
Type 1
under the display tag, specify this pixel mapper:
display:
- platform: addressable_light
.....
pixel_mapper: |-
if (x % 2 == 0) {
return (x * 8) + y;
}
return (x * 8) + (7 - y);
.....
Type 2 (e.g., Ulanzi TC001)
Under the display tag, specify this pixel mapper:
display:
- platform: addressable_light
.....
pixel_mapper: |-
if (y % 2 == 0) {
return (y * 32) + x;
}
return (y * 32) + (31 - x);
.....
You have to configure this lambda under the display: section to use the EsphoMaTrix component
display:
- platform: addressable_light
id: ehmtx_display
.....
auto_clear_enabled: true
lambda: |-
id(rgb8x32)->tick();
id(rgb8x32)->draw();
Light component
The light component is used by the addressable_light component and referenced by ID under addressable_light_id:.
To use the light component directly from home assistant, add the sample lambdason_turn_on and on_turn_off to the light component.
Sample
light:
- platform: neopixelbus
id: ehmtx_light
....
on_turn_on:
lambda: |-
id(rgb8x32)->set_enabled(false);
on_turn_off:
lambda: |-
id(rgb8x32)->set_enabled(true);
To hide the light component from home assistant use: internal: true
light:
- platform: neopixelbus
id: ehmtx_light
internal: true
...
Time component
Since it is a clock, you need a time component, e.g., homeassistant. It is referenced by its ID under time_component: The display shows !t! until the time source is synchronized and valid.
Font
Download a small “pixel” TTF-font, I use "monobit.ttf". You can modify this font with FontForge and add € on base of a E and so on. Due to copyright, I can't provide my modified version :-(. Not all fonts are suitable for this minimalistic display. There are public domain fonts which work well on the display, e.g., DMDSmall, details on alternative fonts are here. DarkPoet78 is providing special fonts for 8x32 matrices in his repo
font:
- file: monobit.ttf
id: EHMTX_font
size: 16
glyphs: |
!"%()+*=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz€@
Icons and Animations
Download and install all needed icons (.jpg/.png) and animations (.gif) under the ehmtx: key. All icons have to be 8x8 or 8x32 pixels in size. If necessary, scale them with gimp, check “as animation” for GIFs.
You can also specify a URL to directly download the image file. The URLs will only be downloaded once at compile time, so there is no additional traffic on the hosting website.
There are maximum 90 icons possible.
Sample
emhtx:
icons:
- id: boot
file: icons/rocket.gif
duration: 75
- id: temp
file: temperature.png
- id: yoga
file: icons/yoga-bridge.gif
pingpong: true
- id: garage
file: garage.gif
duration: 100
- id: homeassistant
url: https://github.com/home-assistant/assets/raw/master/logo/logo-small.png
The ID of the icons is used later to configure the screens to display. So, you should name them wisely. If you like to group icons, you should prefix them e.g., with "weather_" (see Service del_screen) The first defined icon will be used as a fallback icon, in case of an error, e.g., if you use a non-existing icon ID. GIFs are limited to 110 frames to limit the used amount of flash space. All othe
