[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-75680":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},75680,"Clawdmeter","HermannBjorgvin\u002FClawdmeter","HermannBjorgvin","ESP32 desk dashboard that shows Claude Code usage",null,"C",1579,195,6,5,0,9,65,402,29,19.88,false,"main",true,[],"2026-06-12 02:03:35","# Clawdmeter\n\nA small ESP32 dashboard I made for my desk to keep an eye on Claude Code usage.\n\nIt runs on a [Waveshare ESP32-S3-Touch-AMOLED-2.16](https:\u002F\u002Fwww.waveshare.com\u002Fesp32-s3-touch-amoled-2.16.htm?&aff_id=149786) and pairs with my laptop over Bluetooth, the splash screen plays pixel-art Clawd animations that get\nbusier when your usage rate climbs. The two side buttons send Space and\nShift+Tab over BLE HID for Claude Code's voice mode and mode-toggle shortcuts.\n\n|              Usage meter              |              Clawd animation screen              |\n| :-----------------------------------: | :----------------------------------------------: |\n| ![Usage meter](assets\u002Fdemo.jpeg) | ![Clawd animation screen](assets\u002Fdemo.gif) |\n\nThe Clawd animations come from [claudepix](https:\u002F\u002Fclaudepix.vercel.app), [@amaanbuilds](https:\u002F\u002Fx.com\u002Famaanbuilds)'s library of pixel-art Clawd sprites, check it out, it's lovely.\n\n## Screens\n\nThe device boots into the splash and stays there until you press the middle (PWR) button, which cycles between Usage and Bluetooth. Tap the screen anywhere (except the Reset zone on the Bluetooth screen) to flip back to the splash; tap again to dismiss it.\n\n|              Splash               |              Usage              |                Bluetooth                |\n| :-------------------------------: | :-----------------------------: | :-------------------------------------: |\n| ![Splash](screenshots\u002Fsplash.png) | ![Usage](screenshots\u002Fusage.png) | ![Bluetooth](screenshots\u002Fbluetooth.png) |\n|   Splash; touch-toggle anytime    | Session and weekly utilization  |    Connection status and bond reset     |\n\nWhile the splash is up, the middle button cycles animations instead of screens. The firmware also auto-rotates every 20 s within the current usage-rate group, so a long stretch on the splash isn't just one Clawd on loop.\n\n## Hardware\n\n- [Waveshare ESP32-S3-Touch-AMOLED-2.16](https:\u002F\u002Fwww.waveshare.com\u002Fesp32-s3-touch-amoled-2.16.htm?&aff_id=149786) - ESP32-S3R8, 2.16\" 480×480 AMOLED (CO5300 QSPI), CST9220 cap touch, AXP2101 PMU + Li-Po battery, QMI8658 IMU\n- USB-C cable for flashing firmware and charging\n- 3.7V Li-Po battery (MX1.25 2-pin connector, optional)\n\n## Prerequisites\n\n- Linux (tested on Ubuntu) or macOS\n- [PlatformIO CLI](https:\u002F\u002Fdocs.platformio.org\u002Fen\u002Flatest\u002Fcore\u002Finstallation\u002Findex.html)\n- Linux: `curl`, `bluetoothctl`, `busctl` (BlueZ Bluetooth stack)\n- macOS: `python3` (the installer sets up a venv with `bleak` and `httpx`)\n- Claude Code with an active subscription\n\n## macOS installation\n\nThe macOS host pieces — Python daemon, LaunchAgent, and flash helper — were ported by [Chris Davidson (@lorddavidson)](https:\u002F\u002Fgithub.com\u002Florddavidson). Thanks Chris!\n\n### Flash the firmware\n\n```bash\n.\u002Fflash-mac.sh                       # auto-detects \u002Fdev\u002Fcu.usbmodem*\n.\u002Fflash-mac.sh \u002Fdev\u002Fcu.usbmodem1101  # or pass an explicit USB serial port\n```\n\n### Pair the device\n\nAfter flashing, open **System Settings → Bluetooth** and click *Connect* next to \"Clawdmeter\". The daemon will discover it on its next scan (~30 s).\n\n### Install the daemon\n\nThe 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.\n\n```bash\n.\u002Finstall-mac.sh\n```\n\nThe installer creates a Python venv in `daemon\u002F.venv\u002F`, installs `bleak` and `httpx`, renders a LaunchAgent into `~\u002FLibrary\u002FLaunchAgents\u002Fcom.user.claude-usage-daemon.plist`, and loads it. The first run is launched interactively so macOS prompts for Bluetooth permission.\n\nUseful commands:\n\n```bash\nlaunchctl list | grep claude-usage                                          # check it's running\ntail -F ~\u002FLibrary\u002FLogs\u002Fclaude-usage-daemon.out.log                          # live logs\nlaunchctl unload ~\u002FLibrary\u002FLaunchAgents\u002Fcom.user.claude-usage-daemon.plist  # stop\nlaunchctl load -w ~\u002FLibrary\u002FLaunchAgents\u002Fcom.user.claude-usage-daemon.plist # start\n```\n\n## Linux installation\n\n### Flash the firmware\n\n```bash\ncd firmware\npio run -t upload --upload-port \u002Fdev\u002FttyACM0\n```\n\n### Pair the device\n\nAfter flashing, the device advertises as \"Claudemeter\". Pair it once:\n\n```bash\n# Scan for the device\nbluetoothctl scan le\n\n# When \"Claude Controller\" appears, pair and trust it\nbluetoothctl pair F4:12:FA:C0:8F:E5    # use your device's MAC\nbluetoothctl trust F4:12:FA:C0:8F:E5\n```\n\nThe MAC address is shown on the Bluetooth screen — press the middle (PWR) button to cycle to it.\n\n### Install the daemon\n\nThe daemon polls your Claude usage every 60 seconds and sends it to the display over BLE.\n\n```bash\n.\u002Finstall.sh\nsystemctl --user start claude-usage-daemon\n```\n\nCheck status: `systemctl --user status claude-usage-daemon`\n\nView logs: `journalctl --user -u claude-usage-daemon -f`\n\n## How it works\n\n1. The daemon reads your Claude Code OAuth token from `~\u002F.claude\u002F.credentials.json`.\n2. It makes a minimal API call to `api.anthropic.com\u002Fv1\u002Fmessages` — one token of Haiku, basically free.\n3. The usage numbers come straight out of the response headers (`anthropic-ratelimit-unified-5h-utilization` and friends).\n4. The daemon connects to the ESP32 over BLE and writes a JSON payload to the GATT RX characteristic.\n5. The firmware parses it and updates the LVGL dashboard.\n6. The firmware also tracks the rate of change of session % over a 5-minute window and picks splash animations from the matching mood group.\n7. The two side buttons are independent of all of this — they send Space and Shift+Tab as BLE HID keyboard input to the paired host directly.\n\n## Physical buttons\n\nThe board has three side buttons. Left and right do the same thing on every screen; the middle button is screen-aware.\n\n| Button           | GPIO         | Function                                                       |\n| ---------------- | ------------ | -------------------------------------------------------------- |\n| **Left**         | GPIO 0       | Hold to send Space (Claude Code voice-mode push-to-talk)       |\n| **Middle** (PWR) | AXP2101 PKEY | Cycle screens (Usage ↔ Bluetooth); on splash, cycle animations |\n| **Right**        | GPIO 18      | Press to send Shift+Tab (Claude Code mode toggle)              |\n\nSpace 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.\n\n## BLE protocol\n\nThe device advertises a custom GATT service alongside the standard HID keyboard service:\n\n|                            | UUID                                   |\n| -------------------------- | -------------------------------------- |\n| **Data Service**           | `4c41555a-4465-7669-6365-000000000001` |\n| RX Characteristic (write)  | `4c41555a-4465-7669-6365-000000000002` |\n| TX Characteristic (notify) | `4c41555a-4465-7669-6365-000000000003` |\n| **HID Service**            | `00001812-0000-1000-8000-00805f9b34fb` |\n\nJSON payload format (written to RX):\n\n```json\n{ \"s\": 45, \"sr\": 120, \"w\": 28, \"wr\": 7200, \"st\": \"allowed\", \"ok\": true }\n```\n\nFields: `s` = session %, `sr` = session reset (minutes), `w` = weekly %, `wr` = weekly reset (minutes), `st` = status, `ok` = success flag.\n\n## Recompiling fonts\n\nThe `firmware\u002Fsrc\u002Ffont_*.c` files are pre-compiled LVGL bitmap fonts.\n\n```bash\nnpm install -g lv_font_conv\n```\n\nGenerate each one (one at a time — `lv_font_conv` doesn't like loop-driven invocations) with `--no-compress` (required for LVGL 9):\n\n```bash\n# Tiempos Text (titles, 56px)\nlv_font_conv --font assets\u002FTiemposText-400-Regular.otf -r 0x20-0x7E \\\n  --size 56 --format lvgl --bpp 4 --no-compress \\\n  -o firmware\u002Fsrc\u002Ffont_tiempos_56.c --lv-include \"lvgl.h\"\n\n# Styrene B (large numbers 48, panel labels 28, small text 24, minimal 20)\nfor size in 48 28 24 20; do\n  lv_font_conv --font assets\u002FStyreneB-Regular.otf -r 0x20-0x7E \\\n    --size $size --format lvgl --bpp 4 --no-compress \\\n    -o firmware\u002Fsrc\u002Ffont_styrene_${size}.c --lv-include \"lvgl.h\"\ndone\n\n# DejaVu Sans Mono (32px, with spinner Unicode chars)\nlv_font_conv --font assets\u002FDejaVuSansMono.ttf \\\n  -r 0x20-0x7E,0xB7,0x2026,0x2722,0x2733,0x2736,0x273B,0x273D \\\n  --size 32 --format lvgl --bpp 4 --no-compress \\\n  -o firmware\u002Fsrc\u002Ffont_mono_32.c --lv-include \"lvgl.h\"\n```\n\n**Important:** `lv_font_conv` v1.5.3 outputs LVGL 8 format. Each generated file must be patched for LVGL 9 compatibility:\n\n1. Remove `#if LVGL_VERSION_MAJOR >= 8` guards around `font_dsc` and the font struct\n2. Remove the `.cache` field from `font_dsc`\n3. Add `.release_glyph = NULL`, `.kerning = 0`, `.static_bitmap = 0` to the font struct\n4. Add `.fallback = NULL`, `.user_data = NULL` to the font struct\n\nWithout these patches, fonts compile but render as invisible.\n\n## Converting Lucide icons\n\nThe UI uses a small set of [Lucide](https:\u002F\u002Flucide.dev) icons (bluetooth + battery states) converted to RGB565 \u002F RGB565A8 C arrays for LVGL.\n\n```bash\nnode tools\u002Fpng_to_lvgl.js assets\u002Ficon_bluetooth_48.png icon_bluetooth_data ICON_BLUETOOTH_WIDTH ICON_BLUETOOTH_HEIGHT\n```\n\nDefault tint is white (`0xFFFFFF`); Lucide PNGs ship as black-on-transparent and would render invisible against the dark UI without it. Pass `--no-tint` for pre-coloured artwork like the logo. Battery icons use RGB565A8 (alpha plane) so they blend cleanly over the splash; the rest are baked RGB565 over the panel colour. Paste the converter output into `firmware\u002Fsrc\u002Ficons.h`.\n\n## Splash animations\n\nThe animations come from [claudepix.vercel.app](https:\u002F\u002Fclaudepix.vercel.app),\na library of Clawd sprites. `tools\u002Fscrape_claudepix.js` evaluates the\nsite's JavaScript in a Node VM to pull out frame data and palettes, then\n`tools\u002Fconvert_to_c.js` turns everything into RGB565 C arrays and writes\n`firmware\u002Fsrc\u002Fsplash_animations.h`.\n\nTo re-pull (e.g. when the source library updates):\n\n```bash\nnode tools\u002Fscrape_claudepix.js\nnode tools\u002Fconvert_to_c.js\npio run -d firmware -t upload\n```\n\nSee `tools\u002FREADME.md` for details.\n\n## Credits\n\n- Pixel-art Clawd animation by [@amaanbuilds](https:\u002F\u002Fx.com\u002Famaanbuilds), sourced from [claudepix.vercel.app](https:\u002F\u002Fclaudepix.vercel.app). Frame data and palettes scraped + converted by the tooling in `tools\u002F`.\n- Lucide icon set ([lucide.dev](https:\u002F\u002Flucide.dev), MIT) for bluetooth and battery UI glyphs.\n- Anthropic brand fonts (Tiempos Text, Styrene B) — see licensing warning below.\n\n## Licensing gray area warning\n\nThe 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 this if you fork or copy the code from this repo. **You have been warned!**\n","Clawdmeter 是一个基于 ESP32 的桌面仪表盘，用于监控 Claude Code 的使用情况。它采用 Waveshare ESP32-S3-Touch-AMOLED-2.16 显示屏，并通过蓝牙与笔记本电脑配对。核心功能包括显示会话和周使用量、连接状态及重置绑定等，并支持通过侧边按钮发送特定快捷键以控制 Claude Code 的语音模式切换。此外，该设备还具备根据使用率变化而动态调整的像素艺术动画。Clawdmeter 适用于需要实时跟踪 Claude Code 使用情况的开发者或团队，特别是那些希望在工作环境中增添趣味性和互动性的用户。",2,"2026-06-11 03:53:03","CREATED_QUERY"]