A Home Assistant custom integration for Trinity Hub75 LED matrix displays, built around automation-driven image display. Pushes images over MQTT as raw RGB565 pixel data with no cloud dependencies.
- Moon phase display — renders a real-time moon phase image using your HA home location
- Now playing — shows album art with track/artist overlay from any HA media player
- Display any image — send a PNG, JPG, or camera snapshot; automatically cropped and resized to 64×64
- Emoji display — fetch any Twemoji and show it at 64×64, with optional text overlay; cached on disk
- Camera streaming — stream live camera snapshots at ~6 FPS via
trinity.display_stream, or stream HLS via the media player entity - Media player entity — exposes
media_player.trinityso any HA service that targets a media player (e.g.camera.play_stream) works out of the box - Crop control — nine crop anchors (
center,top,bottom,left,right,top_left,top_right,bottom_left,bottom_right); works with both stream paths - Automation-friendly — all display modes are triggered by service calls; schedule and combine them however you like
- Temporary displays —
display_forreverts back to the previous default after a set number of seconds - Persistent default — the last permanent display call is saved to disk and replayed on HA restart
Moon phase — new moon through to waning crescent, rendered from London at 6× zoom. The top pixel row is a lunar cycle progress bar; the ring indicator shows the moon's current position in the sky.
Now playing — album art centre-cropped to 64×64 with pixel-font track and artist overlay.
Install via HACS by adding this repository as a custom repository,
or copy custom_components/trinity/ into your HA config/custom_components/ directory
and restart Home Assistant.
The HA MQTT integration must be set up first — Trinity uses it to publish pixel data.
Add the integration via Settings → Devices & Services → Add Integration → Trinity.
You will be asked for the MQTT topic the display subscribes to (default: trinity-matrix/image).
A ready-to-use ESPHome configuration is provided in esphome/trinity-matrix.yaml.
It subscribes to the configured MQTT topic, receives raw RGB565 pixel data (8192 bytes for a
64×64 image), and renders it directly to the HUB75 panel via the
hub75 component.
Add the following to your ESPHome secrets.yaml:
trinity_matrix_api_key: "<your-api-key>"
mqtt_broker: "10.10.10.x"The integration registers a media_player.trinity entity that accepts play_media and stop
commands. This lets you use standard HA services that target a media player — most usefully
camera.play_stream:
action: camera.play_stream
data:
entity_id: camera.front_door
media_player_entity_id: media_player.trinityThe stream is decoded via PyAV and published to the display at up to 10 FPS.
When the stream ends naturally or media_player.media_stop is called, the display reverts to
its default.
Before calling camera.play_stream, set input_select.trinity_crop to control which part of
the frame is cropped to the 64×64 display. The input_select is reset to center automatically
when the stream ends.
- action: input_select.select_option
target:
entity_id: input_select.trinity_crop
data:
option: top_right
- action: camera.play_stream
data:
entity_id: camera.front_left
media_player_entity_id: media_player.trinityRenders the current moon phase (using your HA home lat/lon/elevation) and pushes it to the display. Becomes the new default.
action: trinity.display_moonFetches album art from a media player entity and overlays scrolling track and artist text. Becomes the new default.
action: trinity.display_now_playing
data:
entity_id: media_player.spotify_dougal_matthewsPushes any image or camera snapshot. Cropped and resized to 64×64. Becomes the new default
unless display_for is set.
action: trinity.display_image
data:
path: /config/www/doorbell.jpg
display_for: 30Fetches a Twemoji image and displays it at 64×64. Accepts the
emoji character directly, or its name with or without colons. The rendered image is cached on
disk. Optionally overlays two lines of text (e.g. for weather condition + temperature).
Becomes the new default unless display_for is set.
action: trinity.display_emoji
data:
emoji: "bell" # or 🔔 or :bell:
display_for: 30
line1: "19C"
line2: "SW 12kmh"Repeatedly snapshots a camera entity and pushes frames at ~6 FPS. Reverts to the default display when the duration elapses or another display action is triggered.
The optional crop parameter controls which part of the frame is used. Supported values:
center (default), top, bottom, left, right, top_left, top_right,
bottom_left, bottom_right. Calling this service also updates input_select.trinity_crop.
action: trinity.display_stream
data:
entity_id: camera.front_door
stream_for: 30
crop: top_right # optional, default: centerSets display brightness (0–255).
action: trinity.set_brightness
data:
brightness: 128Publishes an empty payload, causing the display to fall back to its built-in clock.
action: trinity.clear
