Browse by type

A small ESP32 dashboard I made for my desk to keep an eye on Claude Code usage.
It runs on a Waveshare ESP32-S3-Touch-AMOLED-2.16 as well as a few other alternative boards and pairs over Bluetooth, the splash screen plays pixel-art Clawd animations that get busier when your usage rate climbs. The two side buttons send Space and Shift+Tab over BLE HID for Claude Code's voice mode and mode-toggle shortcuts.

The device boots into the splash. Tap the screen anywhere to switch to the Usage view; tap again to flip back to the splash.
| Splash | Usage |
|---|---|
![]() |
![]() |
| Splash; touch-toggle anytime | Session and weekly utilization |
While the splash is up, the middle (PWR) button cycles animations. Hold the power button for 3 seconds, then release, to put the device into pairing mode — this clears the saved Bluetooth bond and re-advertises. The firmware also auto-rotates animations every 20 s within the current usage-rate group, so a long stretch on the splash isn't just one Clawd on loop.
Boards supported out of the box:
Please check if a pull request exists for your alternative hardware port before opening a new one, providing QA feedback and testing on the same hardware is more valuable than duplicate pull requests.
Porting to another board: the firmware is a thin HAL with per-board folders under firmware/src/boards/. Drop in a new folder and a new PlatformIO env — main.cpp, ui.cpp, and splash.cpp never need to change. See docs/porting/adding-a-board.md for the walk-through and docs/porting/hal-contract.md for the interfaces a port must implement.
curl, bluetoothctl, busctl (BlueZ Bluetooth stack)python3 (the installer sets up a venv with bleak and httpx)python3 3.11+ (the installer sets up a venv with bleak, httpx, and pystray)The macOS host pieces — Python daemon, LaunchAgent, and flash helper — were ported by Chris Davidson (@lorddavidson). Thanks Chris!
./flash-mac.sh waveshare_amoled_216 # auto-detects /dev/cu.usbmodem*
./flash-mac.sh waveshare_amoled_18 /dev/cu.usbmodem1101 # or pass an explicit USB serial port
The board env name is required. Run ./flash-mac.sh with no args to see the available envs (scraped from firmware/platformio.ini).
After flashing, open System Settings → Bluetooth and click Connect next to "Clawdmeter". The daemon only ever connects to the peripheral this Mac is paired/connected to — it never scans for a nearby device — so once it's connected here the daemon picks it up on its next poll (~60 s).
The daemon reads your Claude OAuth token from the macOS Keychain (service Claude Code-credentials), polls usage every 60 s, and pushes it to the display over BLE.
./install-mac.sh
The installer creates a Python venv in daemon/.venv/, installs bleak and httpx, renders a LaunchAgent into ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist, and loads it. The first run is launched interactively so macOS prompts for Bluetooth permission.
Useful commands:
launchctl list | grep claude-usage # check it's running
tail -F ~/Library/Logs/claude-usage-daemon.out.log # live logs
launchctl unload ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist # stop
launchctl load -w ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist # start
./flash.sh waveshare_amoled_216 # defaults to /dev/ttyACM0
./flash.sh waveshare_amoled_18 /dev/ttyACM1 # or pass an explicit USB serial port
The board env name is required. Run ./flash.sh with no args to see the available envs (scraped from firmware/platformio.ini).
After flashing, the device advertises as "Clawdmeter". Pair it once:
# Scan for the device
bluetoothctl scan le
# When "Clawdmeter" appears, pair and trust it
bluetoothctl pair F4:12:FA:C0:8F:E5 # use your device's MAC
bluetoothctl trust F4:12:FA:C0:8F:E5
To re-pair later, hold the power button for 3 seconds then release — the device clears its saved bond and re-advertises.
The daemon polls your Claude usage every 60 seconds and sends it to the display over BLE.
./install.sh
systemctl --user start claude-usage-daemon
Check status: systemctl --user status claude-usage-daemon
View logs: journalctl --user -u claude-usage-daemon -f
Runs natively on Windows — no WSL required. A system-tray app polls your usage and pushes it over BLE, and starts automatically at login.
claude login completed. The token is read from %USERPROFILE%\.claude\.credentials.json (falling back to %LOCALAPPDATA%\Claude\ then %APPDATA%\Claude\).%USERPROFILE%\Clawdmeter), not a \\wsl$ share — the installer refuses a WSL path.pio run -d firmware -e waveshare_amoled_216 -t upload --upload-port COM5 # use your device's COM port
Run pio run -d firmware with no env to see the available board envs.
The device is a bonded BLE HID keyboard, so pair it once: Settings → Bluetooth & devices → Add device → Bluetooth, then select "Clawdmeter". Pairing is required — it enables the physical buttons and keeps a persistent connection (the device keeps showing your last-synced usage even after the daemon quits). To undo, use Remove device (this disables the buttons).
From the repo root in PowerShell:
powershell -ExecutionPolicy Bypass -File install-windows.ps1
This creates a venv, installs bleak/httpx/pystray/Pillow from the in-repo requirements (no internet downloads), registers a per-user login-autostart entry (HKCU\…\Run, no admin needed), and launches the tray app headlessly (no console window).
python -m venv .venv
.venv\Scripts\Activate.ps1 # if blocked: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned, then retry
pip install -r daemon\requirements-windows.txt
python daemon\claude_usage_daemon_windows.py # runs in the foreground; Ctrl+C to stop
The icon's corner bubble shows state — green Connected, amber Scanning, red Error — and hovering shows the status (Connected · last update HH:MM). A notification fires once when it enters Error (e.g. an expired token). Right-click for the menu:
Get-Content $env:LOCALAPPDATA\Clawdmeter\daemon.log -Tail 30 # view logs
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v Clawdmeter /f # remove autostart
| Symptom | Fix |
|---|---|
Device not found |
Power on the device; make sure it's in range and paired. |
token expired toast / API HTTP 401 |
Re-run claude login, then restart the daemon. |
Connection failed |
Toggle Windows Bluetooth off/on in Settings. |
Warning: running under Linux/WSL |
Run from a native PowerShell window, not a WSL shell. |

Claude Code-credentials) on macOS, or from ~/.claude/.credentials.json on Linux (%USERPROFILE%\.claude\.credentials.json on Windows).api.anthropic.com/v1/messages — one token of Haiku, basically free.anthropic-ratelimit-unified-5h-utilization and friends).The board has three side buttons. Left and right send HID keys; the middle (PWR) button cycles splash animations and, held for 3 seconds, triggers pairing mode.
| Button | GPIO | Function |
|---|---|---|
| Left | GPIO 0 | Hold to send Space (Claude Code voice-mode push-to-talk) |
| Middle (PWR) | AXP2101 PKEY | On splash: cycle animations. Hold 3s + release: pairing mode |
| Right | GPIO 18 | Press to send Shift+Tab (Claude Code mode toggle) |
Space and Shift+Tab go out as standard BLE HID keyboard reports, so they trigger in whatever window has focus on the paired host — not just Claude Code.
The device advertises a custom GATT service alongside the standard HID keyboard service:
| UUID | |
|---|---|
| Data Service | 4c41555a-4465-7669-6365-000000000001 |
| RX Characteristic (write) | 4c41555a-4465-7669-6365-000000000002 |
| TX Characteristic (notify) | 4c41555a-4465-7669-6365-000000000003 |
| HID Service | 00001812-0000-1000-8000-00805f9b34fb |
JSON payload format (written to RX):
{ "s": 45, "sr": 120, "w": 28, "wr": 7200, "st": "allowed", "ok": true }
Fields: s = session %, sr = session reset (minutes), w = weekly %, wr = weekly reset (minutes), st = status, ok = success flag.

pio run -d firmware -e
sim, then cd firmware && .pio/build/sim/program). See
SIM-USAGE.md for controls, scenarios, and headless
screenshots.research/clawd-official/;
node tools/convert_official_clawd.js regenerates
firmware/src/splash_animations.h. See tools/README.md.tools/png_to_lvgl.js. See tools/README.md.docs/fonts.md.docs/porting/adding-a-board.md
and docs/porting/hal-contract.md.tools/ and research/clawd-official/.The software in this repository uses and adheres to the Anthropic brand guidelines and uses the same proprietary fonts that Anthropic has a license for but this software uses without permission as well as using assets from Anthropic such as the copyrighted Clawd mascot so even though the code in this repo is non-proprietary I will not license it myself under a copyleft license since this repo includes proprietary fonts and copyrighted assets. Please be aware of
$ claude mcp add Clawdmeter \
-- python -m otcore.mcp_server <graph>