No description
  • Python 99.4%
  • Shell 0.6%
Find a file
Djuri Baars 935d07d0aa
All checks were successful
Lint / Ruff (push) Successful in 1m17s
Test / Pytest (push) Successful in 4m18s
chore(deps): bump HA test pins to 2026.5.4 + ruff 0.15.15
Coordinated bump Dependabot can't do in isolation:
pytest-homeassistant-custom-component 0.13.333 pins homeassistant==2026.5.4
*and* syrupy==5.1.0, so the test harness, HA and syrupy must move together —
bumping any one alone fails resolution. That is exactly why the standalone
Dependabot PRs were red (#33 bumped pytest-hacc without HA; #30 bumped syrupy
past the pin).

- homeassistant 2026.5.0 -> 2026.5.4
- pytest-homeassistant-custom-component 0.13.329 -> 0.13.333
- ruff 0.15.14 -> 0.15.15
- syrupy held at 5.1.0 (pinned by pytest-hacc; a 5.2.0 bump is unmergeable)

208 passed; ruff check + format clean.
2026-06-01 15:37:00 +02:00
.forgejo/workflows Mirror btclock_v3's Forgejo CI pattern 2026-04-21 00:37:39 +02:00
.github Merge pull request #18 from dsbaars/dependabot/github_actions/actions/setup-python-6 2026-04-26 17:23:16 +02:00
.vscode Rewrite for BTClock firmware 3.4.0 and modernize HA integration 2026-04-18 10:43:16 +02:00
config Initial commit 2023-11-18 21:47:32 +00:00
custom_components/btclock test: lock in legacy vs 3.4.0 settings-write route (firmware-verified) 2026-06-01 15:25:33 +02:00
docs/screenshots Add scripts/screenshot for automated UI captures 2026-05-02 21:42:50 +02:00
scripts Add scripts/screenshot for automated UI captures 2026-05-02 21:42:50 +02:00
tests test: lock in legacy vs 3.4.0 settings-write route (firmware-verified) 2026-06-01 15:25:33 +02:00
.devcontainer.json Rewrite for BTClock firmware 3.4.0 and modernize HA integration 2026-04-18 10:43:16 +02:00
.gitattributes Initial commit 2023-11-13 20:09:19 +01:00
.gitignore Add scripts/screenshot for automated UI captures 2026-05-02 21:42:50 +02:00
.python-version Add v4 light control services 2026-05-08 18:27:09 +02:00
.ruff.toml Rewrite for BTClock firmware 3.4.0 and modernize HA integration 2026-04-18 10:43:16 +02:00
CONTRIBUTING.md Initial commit 2023-11-13 20:09:19 +01:00
hacs.json Revert "hacs: allow installing the main branch alongside tagged releases" 2026-04-18 11:25:18 +02:00
LICENSE Create README 2023-11-19 00:20:24 +01:00
pyproject.toml Rewrite for BTClock firmware 3.4.0 and modernize HA integration 2026-04-18 10:43:16 +02:00
README.md Improve v4 light service metadata 2026-05-08 18:51:30 +02:00
requirements.txt chore(deps): bump HA test pins to 2026.5.4 + ruff 0.15.15 2026-06-01 15:37:00 +02:00
requirements_screenshot.txt Update playwright requirement from >=1.59.0 to >=1.60.0 2026-05-19 06:23:59 +00:00
requirements_test.txt chore(deps): bump HA test pins to 2026.5.4 + ruff 0.15.15 2026-06-01 15:37:00 +02:00
validate-HACS Validation-2378.log Add v4 light control services 2026-05-08 18:27:09 +02:00
validate-Hassfest Validation-2377.log Add v4 light control services 2026-05-08 18:27:09 +02:00

BTClock Integration

License: MIT

Home Assistant integration for the BTClock — an open-source Bitcoin price / block-height display. Maintained by the same author as the firmware.

Open in HACS Add integration

Integration overview

Supported firmware

Firmware Status Notes
v4 (4.x, ESP-IDF) Full + extras Everything v3.4 has, plus mining-pool / font selectors, Bitaxe data source, three diagnostic actions, eight v4-only setting toggles, three poll-cadence sliders
v3.4.x (Arduino) Full POST-style API, SSE push updates, HTTP auth, DND, frontlight
≤3.3.x (legacy) Basic GET-style API; read-only DND and no frontlight controls

The variant is detected automatically from GET /api/settingsgitTag on v3.x, gitRev on v4 (which fills only gitRev from git describe). Entities that depend on a specific variant or on a setting key the firmware doesn't expose are suppressed automatically, so a v3.4 device won't show v4-only entities and vice versa.

Platforms

v4-only entities are marked v4.

Platform Entities
sensor Current screen, currency, uptime, RSSI, free heap, ambient light level
binary_sensor Price / blocks / V2 / nostr feed connectivity, screen timer, OTA, DND
switch Screen timer, Do-not-disturb, scheduled Do-not-disturb (3.4.0+); v4: Bitaxe data source, mining-pool stats, pool-wide stats, MoW mode, sats symbol, block countdown, hide leading zero, inverted colors
select Screen (rotation-ordered on 3.4.1+), currency (3.4.0+); v4: mining pool, display font
time Do-not-disturb schedule start / end (3.4.0+)
light One entity per status LED, plus frontlight (when hardware present)
number LED brightness slider (0255); v4: Bitaxe poll interval, mining-pool poll interval, full-refresh interval
button Identify, restart, full refresh, next / previous screen, flash frontlight (3.4.0+); v4: simulate Nostr Zap, clear cached pool logos, restart data sources
update Firmware update (auto-update or specific version, 3.4.0+ release builds)

The screenshots below are taken from a Rev B device running v4 firmware (the v4-only switches/selects/buttons are visible alongside everything inherited from v3.4); on a v3.4 device the v4-marked rows are simply absent.

Controls Sensors Configuration Diagnostic
Controls Sensors Configuration Diagnostic

Services

Service Purpose
btclock.show_text Display a string across the device's screens (one char each, auto-uppercased, clamped to numScreens)
btclock.show_custom Display one string per screen — handy for symbols or multi-char labels
btclock.trigger_led_effect Trigger one of the v4 firmware's named LED effects

LED effects

btclock.trigger_led_effect requires v4 firmware. In Developer Tools → Actions, choose BTClock: Trigger LED effect, select the BTClock device in the device picker, and choose an effect.

Supported effects:

  • blink
  • blink_success
  • blink_error
  • rainbow
  • breathe
  • breathe_error
  • zap
  • identify
  • heartbeat
  • off
  • idle

YAML example:

action: btclock.trigger_led_effect
data:
  device_id: YOUR_BTCLOCK_DEVICE_ID
  effect: heartbeat

Firmware updates

If the BTClock is running a real release (e.g. 3.3.19, not a commit-hash dev build), the integration polls its configured gitReleaseUrl once a day and surfaces a firmware update entity — it also shows up in Settings → Updates. Release notes default to the release body; when that's empty, they're synthesized from the first-line commit messages of the compare API between the installed and latest tags.

Firmware update dialog showing 3.3.19 → 3.4.1 with synthesized release notes

Installing the latest version fires POST /api/firmware/auto_update and lets the device download + flash itself. Installing an older version downloads the matching {board}_firmware.bin and littlefs_{size}.bin assets and uploads them to /upload/firmware and /upload/webui; the device reboots into the new image at the end.

Data-source sensors

connectionStatus exposes four separate feeds — price, blocks, V2, nostr — because a BTClock can be driven by any combination of them depending on its dataSource setting. The integration exposes a binary sensor per feed:

  • Price / Blocks feed — always enabled by default (the common case — BTClock driven by the built-in mempool source).
  • V2 / Nostr feed — hidden by default, but auto-enabled at integration setup if the feed is already connected. If you later switch the device's dataSource, toggle the sensor visibility manually in Home Assistant's entity registry or reconfigure the integration.

Live updates

During setup you pick one of two strategies; swap later via Settings → Devices & Services → BTClock → Configure.

  • Server-Sent Events (default) — the integration subscribes to the BTClock's /events stream and receives status pushes the moment they happen. Lowest latency, zero polling traffic. The SSE client auto-reconnects with jittered backoff if the connection drops.
  • Polling — plain periodic GET /api/status. Choose this if SSE is unreliable on your network (e.g. through a flaky reverse proxy or VPN). The scan interval is configurable (5 3600 seconds, default 30).

HTTP Basic Auth

If the BTClock has httpAuthEnabled turned on, the config flow will prompt for credentials. When credentials stop working (e.g. you rotated the password on the device), Home Assistant will surface a reauth prompt.

Installation via HACS

HACS currently only accepts GitHub repositories, so use the GitHub mirror — the git.btclock.dev Forgejo instance won't work.

  1. Open in HACS — or manually: HACS → Integrations → menu → Custom repositories → add https://github.com/dsbaars/homeassistant-btclock with category Integration.
  2. Install "BTClock Integration" and restart Home Assistant.
  3. Add integration — or Settings → Devices & Services → Add Integration → BTClock, or accept the auto-discovered zeroconf prompt.

Manual installation

  1. Copy custom_components/btclock/ into your Home Assistant configuration's custom_components/ directory.
  2. Restart Home Assistant.
  3. Add the integration from Settings → Devices & Services.

Development

See CONTRIBUTING.md. Recommended workflow is to use the VSCode Dev Container (.devcontainer.json ships Python 3.13 + HA latest + test deps). Useful scripts:

  • scripts/setup install runtime + test deps
  • scripts/test run pytest tests/
  • scripts/check ruff lint + format check + pytest
  • scripts/develop boot a debug Home Assistant on port 8123 with this integration loaded (set BTCLOCK_DEBUGPY=1 to attach on port 5678)
  • scripts/screenshot regenerate the PNGs under docs/screenshots/ (boots a one-shot HA against a stub BTClock seeded from the v4 fixture; auto-installs Playwright + Chromium on first run)

Contributing

Issues and pull requests welcome at https://git.btclock.dev/btclock/homeassistant-btclock or the GitHub mirror.