Transform your HUB75 LED matrix into a retro game-inspired clock with Home Assistant integration! ๐โจ
This ESPHome component brings the fantastic Clockwise project to Home Assistant, featuring retro gaming clockfaces like Mario and Pac-Man with full remote control capabilities.
- ๐ฎ Retro Game Clockfaces: Mario and Pac-Man themed clock displays
- ๐ Home Assistant Integration: Full control via Home Assistant dashboard
- ๐ก Brightness Control: Adjust display brightness (0-255) remotely
- ๐ Automatic Brightness: Optional LDR sensor for automatic brightness adjustment
- ๐ Clockface Switching: Change between clock styles on the fly
- ๐จ Panel Color Order: Fix wrong colors without rewiring โ swap R/G/B channels in software
- โก Power Control: Turn display on/off remotely
- ๐ฏ Huidu HD-WF2 Support: Optimized for HD-WF2 boards with automatic pin mapping
- ๐ฑ Real-time Sync: Time synchronized with Home Assistant or NTP
- ๐ Triple Time Sources: Choose between Home Assistant, NTP (SNTP), or hardware RTC (BM8563)
- ๐ RTC Sync: One-click button to sync Home Assistant time to RTC hardware
Once installed, you'll get these entities in Home Assistant:
- Switch:
display_power- Turn display on/off - Switch:
auto_brightness- Enable/disable automatic brightness (when LDR is configured) - Number:
display_brightness- Adjust brightness (0-255) - Select:
clockface- Choose between Mario, Pac-Man, and other styles - Select:
time_source- Choose between Home Assistant, NTP, or RTC time - Select:
panel_color_order- Fix swapped colors by selecting RGB, RBG, GRB, GBR, BRG, or BGR - Button:
sync_time_to_rtc- Sync current Home Assistant time to RTC hardware - Sensor:
ambient_light- Current light level percentage (when LDR is configured)
This project integrates the amazing Clockwise retro clock project by jnthas with Home Assistant using ESPHome. It leverages the excellent HUB75 ESPHome component by Stuart Parmenter to drive HUB75 LED matrices.
- Original Clockwise: clockwise.page | GitHub
- HUB75 Driver: hub75-esp32
- Hardware: Optimized for Huidu HD-WF2 boards
- Platform: ESPHome with Home Assistant integration
Hardware:
- ESP32 development board (ESP32, ESP32-S3, or ESP32-S2)
- HUB75 RGB LED Matrix panel (64ร32 or 64ร64)
- Huidu HD-WF2 board (recommended) or compatible HUB75 driver board
- 5V power supply (adequate for your panel size)
Software:
- ESPHome installed (via Home Assistant or standalone)
- Home Assistant instance
- Clone this repository or add as external component:
external_components:
- source: github://aschoelzhorn/clockwise-esphome@main
components: [clockwise_hub75]- Use the example configuration:
Start with examples/clockwise.yaml and modify according to your hardware setup.
- Configure your secrets:
Create a secrets.yaml file:
wifi_ssid: "YourWiFiSSID"
wifi_password: "YourWiFiPassword"
api_encryption_key: "your-encryption-key"
ota_password: "your-ota-password"
wifi_ap_password: "fallback-hotspot-password"- Flash to your ESP32:
esphome run examples/clockwise.yaml# I2C for RTC (required if using hardware RTC)
i2c:
sda: 41
scl: 42
# Time components
time:
- platform: homeassistant
id: homeassistant_time
timezone: Europe/Vienna
- platform: sntp # Optional: NTP time source (no HA required)
id: ntp_time
timezone: Europe/Vienna
servers:
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- platform: bm8563 # Optional: Hardware RTC for offline operation
id: rtc_time
address: 0x51
# HUB75 Display (using board preset for HD-WF2)
display:
- platform: hub75
id: matrix_display
board: huidu-hd-wf2 # Automatic pin mapping
panel_width: 64
panel_height: 64
shift_driver: FM6126A
brightness: 128
update_interval: 4294967295ms # Never - clockwise handles updates
rotation: 90 # (Optional, integer): The rotation of the display in degrees, one of 0, 90, 180 or 270. Defaults to 0
# Clockwise Component
clockwise_hub75:
id: clockwise_main
hub75_id: matrix_display
clockface_type: MARIO # Options: MARIO, PACMAN
panel_color_order: RGB # Fix wrong colors: RGB, RBG, GRB, GBR, BRG, BGR
initial_brightness: 128
esphome:
on_boot:
priority: 600
then:
- lambda: |-
id(clockwise_main).set_ha_time(id(homeassistant_time));
id(clockwise_main).set_ntp_time(id(ntp_time));
id(clockwise_main).set_rtc_time(id(rtc_time));
# Home Assistant Controls
number:
- platform: clockwise_hub75
clockwise_hub75_id: clockwise_main
id: display_brightness
name: "Display Brightness"
switch:
- platform: clockwise_hub75
clockwise_hub75_id: clockwise_main
id: display_power
name: "Display Power"
select:
- platform: template
id: clockface_selector
name: "Clockface"
options:
- "Pacman"
- "Mario"
initial_option: "Pacman"
restore_value: true
optimistic: true
on_value:
then:
- lambda: |-
if (x == "Mario") id(clockwise_main).switch_clockface(esphome::clockwise_hub75::MARIO);
else id(clockwise_main).switch_clockface(esphome::clockwise_hub75::PACMAN);
# Time source selector
- platform: template
id: time_source_selector
name: "Time Source"
options:
- "Home Assistant"
- "NTP"
- "RTC"
initial_option: "Home Assistant"
restore_value: true
optimistic: true
on_value:
then:
- lambda: |-
// 0 = Home Assistant, 1 = NTP, 2 = RTC
int source = (x == "Home Assistant") ? 0 : (x == "NTP") ? 1 : 2;
id(clockwise_main).set_time_source(source);
# Panel color order - fix swapped colors without rewiring
- platform: template
id: panel_color_order_selector
name: "Panel Color Order"
icon: mdi:palette
entity_category: config
options:
- "RGB"
- "RBG"
- "GRB"
- "GBR"
- "BRG"
- "BGR"
initial_option: "RGB"
restore_value: true
optimistic: true
on_value:
then:
- lambda: |-
esphome::clockwise_hub75::PanelColorOrder order = esphome::clockwise_hub75::RGB;
if (x == "RBG") order = esphome::clockwise_hub75::RBG;
else if (x == "GRB") order = esphome::clockwise_hub75::GRB;
else if (x == "GBR") order = esphome::clockwise_hub75::GBR;
else if (x == "BRG") order = esphome::clockwise_hub75::BRG;
else if (x == "BGR") order = esphome::clockwise_hub75::BGR;
id(clockwise_main).set_panel_color_order(order);
# Sync button (when RTC is configured)
button:
- platform: template
name: "Sync Time to RTC"
icon: mdi:clock-check
on_press:
- bm8563.write_time:
id: rtc_timeTested Configurations:
- Huidu HD-WF2 + 64ร64 FM6126A panel (recommended)
- ESP32-S3 DevKit + 64ร64 panel
Board Presets Available:
huidu-hd-wf2- Automatic pin mapping for HD-WF2 boards- Manual pin configuration available for other boards
- Classic Super Mario Bros. styling
- Animated blocks and character elements
- Custom Super Mario font
- Based on: Original Mario Clockface (cw-cf-0x01)
- Retro Pac-Man game aesthetics
- Yellow color scheme
- Classic arcade font styling
- Based on: Original Pac-Man Clockface (cw-cf-0x05)
The display can automatically adjust brightness based on ambient light using an LDR sensor:
substitutions:
enable_ldr: "true" # Initial state on first boot
ldr_pin: GPIO4
ldr_update_interval: "2s"
sensor:
- platform: adc
pin: ${ldr_pin}
name: "Ambient Light"
id: ambient_light
update_interval: ${ldr_update_interval}
attenuation: 12db
filters:
- sliding_window_moving_average:
window_size: 5
- calibrate_linear:
- 1.3 -> 0.0 # Dark voltage -> 0%
- 3.0 -> 100.0 # Bright voltage -> 100%
on_value:
# Maps 0-100% light to 20-255 brightnessHome Assistant Control: Toggle auto-brightness on/off anytime using the switch.auto_brightness entity - no recompilation needed! The switch state persists across reboots and can be integrated into automations.
Calibration: Measure your LDR voltage range in dark/bright conditions and adjust the calibrate_linear values accordingly. See the full example in examples/clockwise.yaml.
- ๐ฎ More Themes: Additional retro game clockfaces
- ๐ Weather Display: Weather information integration
For Huidu HD-WF2 boards, no manual wiring needed - just use board: huidu-hd-wf2 in your configuration.
RTC Support: The HD-WF2 board includes a BM8563 RTC chip connected via I2C. Configure it as a time source:
i2c:
sda: 41
scl: 42
time:
- platform: homeassistant
id: homeassistant_time
- platform: sntp
id: ntp_time
servers:
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- platform: bm8563
id: rtc_time
address: 0x51
esphome:
on_boot:
priority: 600
then:
- lambda: |-
id(clockwise_main).set_ha_time(id(homeassistant_time));
id(clockwise_main).set_ntp_time(id(ntp_time));
id(clockwise_main).set_rtc_time(id(rtc_time));
# Time source selector
select:
- platform: template
id: time_source_selector
name: "Time Source"
options:
- "Home Assistant"
- "NTP"
- "RTC"
initial_option: "Home Assistant"
on_value:
- lambda: |-
// 0 = Home Assistant, 1 = NTP, 2 = RTC
int source = (x == "Home Assistant") ? 0 : (x == "NTP") ? 1 : 2;
id(clockwise_main).set_time_source(source);
# Sync button to write HA time to RTC
button:
- platform: template
name: "Sync Time to RTC"
icon: mdi:clock-check
on_press:
- bm8563.write_time:
id: rtc_timeWhy NTP? NTP provides accurate time directly from internet time servers without requiring a Home Assistant connection โ ideal if you want the clock to work standalone.
Why RTC? An RTC maintains accurate time even when WiFi is unavailable, making your clock more reliable.
For custom setups, see the original HUB75 ESPHome component.
Add this card to your dashboard:
type: entities
entities:
- entity: select.clockwise_hdwf2_clockface
name: Clockface
- entity: select.clockwise_hdwf2_time_source
name: Time Source
- entity: select.clockwise_hdwf2_panel_color_order
name: Panel Color Order
- entity: button.clockwise_hdwf2_sync_time_to_rtc
name: Sync Time to RTC
- entity: number.clockwise_hdwf2_display_brightness
name: Display Brightness
- entity: switch.clockwise_hdwf2_display_power
name: Display Power
- entity: switch.clockwise_hdwf2_auto_brightness
name: Auto Brightness
- entity: update.clockwise_clock_firmware
name: Firmware
title: Clockwise HD-WF2 ClockThis ESPHome component adapts the original Clockwise codebase with these key changes:
- File Structure: Flattened directory structure (ESPHome limitation)
- Include Paths: Modified to use local includes (
"file.h"vs<file.h>) - DateTime Integration: Custom
CWDateTime.cppimplementation for ESPHome time sync - Component Architecture: Wrapper around original Clockwise rendering code
- ESP32-S3: Recommended for higher refresh rates (120+ Hz)
- ESP32: Works well at 60-80 Hz refresh rates
- Memory Usage: Optimized with
-Oscompile flag - Power Efficiency: Configurable brightness for power management
Display is blank:
- Check power supply (5V, adequate current)
- Verify wiring connections
- Verify shift driver setting (
FM6126AvsGENERIC)
Wrong colors:
- Use the Panel Color Order select in Home Assistant to swap channels in software โ try
RBG,GRB,BGR, etc. until colors look correct. No rewiring needed. - If none of the six options fix it, check the physical RGB pin connections on your board.
Boot loops:
- Disconnect HUB75 during ESP32 boot
- Use board presets to avoid strapping pin conflicts
- Check power supply stability
- Issues: GitHub Issues
- ESPHome: ESPHome Discord
- Home Assistant: Community Forum
This project is licensed under the MIT License - see the LICENSE file for details.
- Clockwise by jnthas - Original retro clock implementation
- HUB75-ESP32 by Stuart Parmenter - HUB75 driver library
- ESPHome - Home automation platform
- Home Assistant - Home automation hub
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is maintained and tested with the hardware configurations listed above. New features and clockfaces are continuously being developed.
Current Status: Stable for Mario and Pac-Man clockfaces with optional auto-brightness support

