by sorryhumans
A round AMOLED desk display for your live Claude Code usage, weather, background-agent health, and a daily voice greeting. ESP32-S3 + macOS BLE daemon. Fork of Clawdmeter.
# Add to your Claude Code skills
git clone https://github.com/sorryhumans/clawdmeter-plusGuides for using ai agents skills like clawdmeter-plus.
clawdmeter-plus is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by sorryhumans. A round AMOLED desk display for your live Claude Code usage, weather, background-agent health, and a daily voice greeting. ESP32-S3 + macOS BLE daemon. Fork of Clawdmeter. It has 53 GitHub stars.
clawdmeter-plus's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/sorryhumans/clawdmeter-plus" and add it to your Claude Code skills directory (see the Installation section above).
clawdmeter-plus is primarily written in C. It is open-source under sorryhumans on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh clawdmeter-plus against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
A tiny round AMOLED desk display that shows your live Claude Code usage, the time, the London weather, the health of your background agents, and an animated pixel mascot - and greets you out loud twice a day. It runs on a Waveshare ESP32-S3-Touch-AMOLED-2.16 and talks to a small macOS daemon over Bluetooth LE.
This is a personal fork/extension of the open-source Clawdmeter by Hermann Bjorgvin. It is an independent, unofficial hobby project and is not affiliated with, endorsed by, or sponsored by Anthropic. See Credits & License.
The finished build on my desk. The crisp screenshots further down are captured straight off the panel's framebuffer.
The display has two pages. Press the middle PWR button to flip between them.
Your live Claude Code limits, straight from the Anthropic usage API:
A bento-style dashboard:
tmux session, each with an identity icon. Whichever agent is actively working
gets a pulsing orange highlight behind its cell.The agent-dots panel is tailored to a specific multi-agent setup (it looks for
named tmux windows). If you don't run agents that way the dots simply stay
idle - everything else works unchanged. See Customizing.
| Action | What it does |
|---|---|
| Tap PWR (middle button) | Cycle pages: Usage ⟷ Status |
| Hold PWR ~3 s | Pairing mode (clears the Bluetooth bond) |
| Side buttons | BLE HID keys you can use inside Claude Code (e.g. push-to-talk) |
| Part | Notes |
|---|---|
| Waveshare ESP32-S3-Touch-AMOLED-2.16 | The board. 480×480 round AMOLED, capacitive touch, IMU, onboard speaker, USB-C. This is the main build target (waveshare_amoled_216). |
| LiPo battery (optional) | A single-cell 3.7 V LiPo with the board's JST connector makes it cordless. The onboard AXP2101 charges it over USB by default. Mind the connector polarity. |
| Onboard speaker | The 2.16" board has an ES8311 codec + speaker, used for the session-reset chime and the daily voice. |
| USB-C data cable | Needed to flash. Use a real data cable, not a charge-only one. |
Other boards in the same family are also supported by the firmware - see Supported boards.
On battery the device sleeps after a few minutes idle to save power and wakes on a PWR press; on USB it stays always-on. A dark screen after a night on battery is normal - just tap PWR.
(Enclosure/wiring photos will be added here.)
The firmware is a PlatformIO project (C++ / LVGL 9).
Prerequisites
brew install platformio # provides the `pio` CLI
Flash (convenience script, auto-detects the USB port):
./flash-mac.sh waveshare_amoled_216
# or pin the port explicitly:
./flash-mac.sh waveshare_amoled_216 /dev/cu.usbmodem1101
Flash (raw PlatformIO):
pio run -e waveshare_amoled_216 -t upload
If no /dev/cu.usbmodem* device is found, the cable is charge-only or the board
needs download mode - hold BOOT while plugging in, then flash.
Monitor serial output with:
pio device monitor -e waveshare_amoled_216 -b 115200
The board is just a screen; a small Python daemon (bleak + httpx) is the
brains. It reads your Claude usage, fetches the weather, checks agent health, and
pushes a compact JSON payload to the device over BLE every ~60 s.
It never stores a token in this repo. On macOS it reads your Claude Code
OAuth token from the login Keychain (service Claude Code-credentials) at
runtime - the same credential Claude Code itself uses. You just need to be
signed in to Claude Code.
Install:
./install-mac.sh
This will:
daemon/.venv (installs bleak + httpx).com.user.claude-usage-daemon) so the
daemon starts at login and restarts if it crashes.blueutil (auto-recovers the BLE bond after a reflash).Pair the device (once, after flashing):
The daemon discovers the paired device within ~30 s and starts sending.
Logs & control:
tail -F ~/Library/Logs/claude-usage-daemon.out.log # "Sending: {…ok:true}" = healthy
launchctl unload -w ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist # stop
launchctl load -w ~/Library/LaunchAgents/com.user.claude-usage-daemon.plist # start
Linux / Windows: the upstream project also ships a
systemdunit (daemon/claude-usage-daemon.sh,install.sh) and a Windows daemon + tray (daemon/*_windows.*,install-windows.ps1,daemon/README-windows.md). This fork's extra features are developed and tested on macOS.
The Keychain OAuth token has a short TTL and only refreshes when some Claude
Code process makes a call. During long idle stretches it can expire and the
device shows stale data until the next activity. daemon/token_keepwarm.sh is a
tiny launchd job that spends one throwaway claude -p call only when the token
is within ~6 min of expiry, forcing a refresh. Optional but nice for an
always-on desk display.
Daemon options live in a plain config file that's re-read every poll (no restart needed):
~/.config/claude-usage-monitor/config
Copy daemon/config.example there to start. Keys:
clock - off / auto / 12 / 24 (show a clock on the usage screen)chime - on / off (play a sound through the speaker when your 5-hour
session limit resets)config_dirs - poll more than one ~/.claude* plan and show whichever is
activeThe board speaks to you through its onboard speaker twice a day:
Each plays once per day, scheduled off the device clock. The audio is embedded
in the firmware as 12 kHz PCM (firmware/src/voice_morning_pcm.h and
voice_evening_pcm.h) and played back via the ES8311 codec.
Test the clips over serial (no need to wait for the hour):
voice1 # play the morning clip
voice2 # play the evening clip
Change the times: edit the schedule in firmware/src/main.cpp (search for
voice_schedule_tick) - the two lines compare the current minute-of-day against
8 * 60 and 20 * 60. Change those and reflash.
Change the messages / language: the easiest way is the included helper. Type your text, in any language, and it regenerates the header for you:
tools/gen_voice.sh morning en "Good morning! Have a productive day."
tools/gen_voice.sh evening uk "Добрий вечір. Час відпочивати."
# then reflash:
./flash-mac.sh waveshare_amoled_216
It uses free Google Translate TTS (no API key) and writes a 12 kHz / 16-bit /
mono PCM header with the right symbol names. Needs ffmpeg (brew install ffmpeg). Keep clips short - they live in the app partition alongside the
firmware. Prefer your own audio? Any 12 kHz/16-bit/mono PCM emitted as a C byte
array in the same shape works too (mirror bell_pcm.h).
The bundled clips are in English (generic greetings, so anyone can use the build as-is). Swap them for your own language or wording with the command above.
WX_URL request) in
daemon/claude_usage_daemon.py for your city.tmux session. If you don't use that setup, the dots stay idle and
ha