# Clawdmeter-Projekt-Analyse

Quelle: https://github.com/HermannBjorgvin/Clawdmeter  
Reddit-Post: https://www.reddit.com/r/ClaudeCode/comments/1takxpl/

## Hardware

**Waveshare ESP32-S3-Touch-AMOLED-2.16** (~32€)
- SoC: ESP32-S3R8 (8MB PSRAM, 384KB SRAM)
- Display: 2.16" 480×480 AMOLED, CO5300 QSPI-Controller
- Touch: CST9220 Capacitive (I2C, addr 0x5A)
- PMU: AXP2101 (I2C, addr 0x34) — Battery, USB VBUS, PWR-Button
- IMU: QMI8658 (I2C, addr 0x6B) — Auto-Rotation
- Buttons: GPIO 0 (links), GPIO 18 (rechts), AXP2101 PKEY (mitte)
- BLE 5.0, USB-C (JTAG + Serial + Charge)
- Li-Po-Anschluss (MX1.25 2-pin, optional)

## Firmware-Architektur (C++ / PlatformIO)

### Dateien und Aufgaben

| Datei | Zweck |
|-------|-------|
| `main.cpp` | setup(), loop(), Button-Polling, Rotation-Handling |
| `display_cfg.h` | Pin-Definitionen, extern-Objekt-Deklarationen |
| `ui.{h,cpp}` | 3-Screen UI: Splash, Usage, Bluetooth |
| `splash.{h,cpp}` | 20×20 Pixel-Art Animation Engine, 24× upscale |
| `imu.{h,cpp}` | Beschleunigungs-basierte Rotation (0..3) |
| `power.{h,cpp}` | AXP2101-Wrapper: Battery%, Charging, VBUS, PWR-Button |
| `touch.{h,cpp}` | Minimaler Tap-Detector |
| `ble.{h,cpp}` | NimBLE Peripheral: Custom GATT Service + HID Keyboard |
| `data.h` | `UsageData` Struct |
| `icons.h` | Icon-Arrays (RGB565 + RGB565A8) |
| `logo.h` | 80×80 RGB565 Logo |
| `font_*.c` | Pre-kompilierte LVGL-9 Bitmap-Fonts |
| `splash_animations.h` | Generierte Animation-Data (aus claudepix) |

### Pinout (kritisch)

- Display QSPI: CS=12, SCLK=38, SDIO0..3=4..7, RST=2
- Touch I2C: SDA=15, SCL=14, INT=11
- AXP2101: selber I2C-Bus, addr 0x34
- QMI8658: selber I2C-Bus, addr 0x6B
- Left Button: GPIO 0
- Right Button: GPIO 18
- Middle Button: AXP2101 PKEY

### UI-Flow

1. **Boot** → Splash Screen (Clawd-Animation)
2. **Mitte-Taste** → toggelt Usage ↔ Bluetooth
3. **Touch-Tap** (außer Reset-Zone) → Splash ↔ zurück
4. **Links-Taste halten** → sendet Space (Voice-Mode Push-to-Talk)
5. **Rechts-Taste** → sendet Shift+Tab (Mode-Toggle)
6. **Splash + Mitte-Taste** → cycle Animationen
7. **Auto-Rotation** alle 20s innerhalb derselben Mood-Gruppe

## Daemon (Host-Seite)

**Sprache:** Bash (aber Python empfohlen für bessere Fehlerbehandlung)

**Ablauf:**
1. Liest OAuth-Token aus `~/.claude/.credentials.json`
2. Polled `api.anthropic.com/v1/messages` (1 Token Haiku, quasi kostenlos)
3. Extrahiert Usage aus Response-Headers:
   - `anthropic-ratelimit-unified-5h-utilization`
   - `anthropic-ratelimit-unified-7d-utilization`
4. Schreibt JSON-Payload an BLE GATT RX
5. Systemd-User-Service für Autostart

**Resilienz:**
- Verbindet by-name (`"Claude Controller"`)
- Cacht MAC in `~/.config/claude-usage-monitor/ble-address`
- Bei Connect-Failure: Cache löschen + `bluetoothctl remove`
- Inner Loop alle 5s (Disconnect-Erkennung)
- Poll alle 60s oder bei ESP-Refresh-Request

## BLE-Protokoll

### GATT-Service: `4c41555a-4465-7669-6365-000000000001`

| Charakteristik | UUID-Suffix | Richtung | Zweck |
|----------------|-------------|----------|-------|
| RX | `...0002` | Write | Daemon → ESP32 JSON |
| TX | `...0003` | Notify | ESP32 → Daemon Ack/Nack |
| REQ | `...0004` | Notify | ESP32 signalisiert Refresh-Request |

### HID-Service: `00001812-0000-1000-8000-00805f9b34fb`

Sendet Standard-BLE-HID-Keyboard-Reports:
- Space (Links-Taste halten)
- Shift+Tab (Rechts-Taste)

### JSON-Payload-Format (an RX)

```json
{
  "s": 45,      // Session utilization %
  "sr": 120,    // Session reset in Minuten
  "w": 28,      // Weekly utilization %
  "wr": 7200,   // Weekly reset in Minuten
  "st": "allowed", // Status-String
  "ok": true    // Success-Flag
}
```

## Tools & Tooling

### Font-Konvertierung
```bash
npm install -g lv_font_conv
lv_font_conv --font TiemposText-400-Regular.otf -r 0x20-0x7E \
  --size 56 --format lvgl --bpp 4 --no-compress \
  -o font_tiempos_56.c --lv-include "lvgl.h"
```
**WICHTIG:** Danach LVGL-9-Patch anwenden (siehe `references/lvgl9-font-patch.md`).

### Icon-Konvertierung
```bash
node tools/png_to_lvgl.js input.png SYMBOL_NAME W_MACRO H_MACRO [--tint=FFFFFF]
```
Lucide-Icons sind schwarz-on-transparent → `--tint` notwendig.

### Animation-Scraping
```bash
node tools/scrape_claudepix.js   # → tools/claudepix_data/*.json
node tools/convert_to_c.js       # → firmware/src/splash_animations.h
```

### Screenshot über Serial
```bash
./screenshot.sh out.png /dev/ttyACM0
```
Dumpt den LVGL-Framebuffer als 480×480 PNG.

## Lizenz-Warnung

Der Autor warnt ausdrücklich:

> *"This repo includes proprietary fonts and copyrighted assets. The software uses Anthropic brand fonts (Tiempos Text, Styrene B) without permission, as well as the copyrighted Clawd mascot. I will not license it under a copyleft license. Please be aware of this if you fork or copy the code."*

**Fazit:** Code ist frei verwendbar, Assets nicht. Für eigenen Nachbau eigene Fonts und eigene Pixel-Art nutzen.

## Credits

- Pixel-Art: [@amaanbuilds](https://x.com/amaanbuilds) via [claudepix.vercel.app](https://claudepix.vercel.app)
- Icons: [Lucide](https://lucide.dev) (MIT)
- Fonts: Anthropic proprietary (nicht verwendbar)
