Skip to content

Add macOS host support and Waveshare 1.8" AMOLED board port#5

Closed
lorddavidson wants to merge 1 commit into
HermannBjorgvin:mainfrom
lorddavidson:macos-and-amoled18-port
Closed

Add macOS host support and Waveshare 1.8" AMOLED board port#5
lorddavidson wants to merge 1 commit into
HermannBjorgvin:mainfrom
lorddavidson:macos-and-amoled18-port

Conversation

@lorddavidson

Copy link
Copy Markdown
Contributor

Summary

Adds macOS host support and a Waveshare ESP32-S3-Touch-AMOLED-1.8 board port, alongside the existing 2.16" Linux target. Both pre-existing paths are preserved — nothing breaks for current users.

What's new

macOS host (replaces bluetoothctl / busctl / systemd)

  • daemon/claude_usage_daemon.py — Python rewrite of the bash daemon using bleak (CoreBluetooth). Mirrors the original's behavior: 60s poll, refresh-on-notify, 1→60s reconnect backoff, MAC/UUID caching.
  • daemon/com.user.claude-usage-daemon.plist — LaunchAgent template (Mac equivalent of the systemd unit).
  • install-mac.sh — installs to ~/Library/LaunchAgents/, sets up a Python venv, primes Bluetooth permission interactively.
  • flash-mac.sh — wraps pio run -t upload with /dev/cu.usbmodem* autodetect and -e <env> selection.
  • Token reading on macOS pulls from the Keychain (Claude Code-credentials service) since ~/.claude/.credentials.json is Linux-only; Linux path is preserved as a fallback.

Firmware: Waveshare ESP32-S3-Touch-AMOLED-1.8 (368×448)

Gated by -DBOARD_AMOLED_18 — original 2.16" build is untouched at runtime.

  • firmware/platformio.ini — refactored into a [common] base + two envs (waveshare_amoled_216, waveshare_amoled_18).
  • firmware/src/display_cfg.h — board-conditional pins, resolution, driver typedefs:
    • Display: Arduino_SH8601 (vs CO5300), SCLK 11 (vs 38), reset via TCA9554 P0
    • Touch: TouchDrvFT6X36 at 0x38 (vs CST92xx at 0x5A), INT on GPIO 21
    • New: TCA9554 I/O expander at 0x20 drives reset lines
  • firmware/src/main.cpp — conditional object construction; minimal inline TCA9554 driver (reset pulse before display init); rotate_strip rewritten to handle non-square panels (was hardcoded S = LCD_WIDTH which broke on 368×448); rot_buf sized by max(LCD_W, LCD_H).
  • firmware/src/ui_layout.h (new) — per-board layout constants for ui.cpp (margins, panel sizes, splash cell size).
  • firmware/src/ui.cpp / firmware/src/splash.cpp — consume ui_layout.h; splash canvas uses 18px cells on 1.8 (360×360 centered) vs 24px on 2.16 (480×480).

Testing

  • pio run -e waveshare_amoled_216 builds clean (regression check — confirms refactors didn't break upstream behavior)
  • pio run -e waveshare_amoled_18 builds clean
  • ✅ Flashed and ran on real ESP32-S3-Touch-AMOLED-1.8 hardware: display renders correctly, touch axes correct, splash animations centered, BLE GATT round-trips with the Mac daemon
  • ✅ Mac daemon connects, polls Anthropic API, writes payload, receives REQ notifications
  • ⚠️ Not regression-tested on Linux — I don't have a Linux setup. The original daemon/claude-usage-daemon.sh, install.sh, flash.sh, and .service files are unmodified, so Linux behavior should be intact, but a second pair of eyes there would help.

Notes

  • Happy to split this into two PRs (macOS support / 1.8 board port) if you'd prefer smaller review surface — let me know.
  • The 1.8 port's touch swap/mirror and SH8601 col/row offsets are best-guesses that worked on my unit; if other 1.8 owners see issues I'll iterate.
  • No upstream assets, font files, or licensing-sensitive material modified.

@HermannBjorgvin

Copy link
Copy Markdown
Owner

Thanks for the PR! I'll take a look in a few hours when I get back home, I think I even have one of the 1.8" boards to test as well.

@HermannBjorgvin

Copy link
Copy Markdown
Owner

🤖AI Generated: Tested this on the 2.16 board — build/flash/runtime all clean, daemon connects, Usage screen renders identically, layout constants and rotate_strip math both check out. Thanks for the careful refactor and the ui_layout.h split.

One thing I wanted to ask about before I sign off — I don't have a 1.8" board on me right now so I can't verify this myself, but reading through the diff it looks like main.cpp's button loop is unchanged, while from the Waveshare docs the 1.8 only ships two physical buttons (BOOT on GPIO 0, PWR on TCA9554 EXIO4 rather than the AXP). On paper that would mean:

  • BTN_FWD = GPIO 18 has no physical button on the 1.8, so Shift+Tab (Claude Code mode toggle) wouldn't fire.
  • power_pwr_pressed() reads via the AXP path, which isn't how the 1.8's PWR button is wired, so cycling screens / splash animations wouldn't work either — and the Bluetooth status screen would be unreachable.

How's it actually behaving for you on the unit you flashed? Curious whether I'm reading the wiring wrong, or whether you're already navigating via touch / a different path I'm not seeing. If there is a gap there, one shape I had in mind was remapping PWR (via EXIO4) → Shift+Tab and letting a touch tap cycle `Usage → Bluetooth → Splash`, but I'd rather hear how it works for you today before suggesting changes.

@HermannBjorgvin HermannBjorgvin mentioned this pull request May 14, 2026
2 tasks
@HermannBjorgvin

Copy link
Copy Markdown
Owner

Hey @lorddavidson I had techcrunch reach out the project so expedited the macos support and cherry picked parts from your branch into #6 I hope you don't mind.

I wanted to have the macos support as soon as possible due to that article coming out, I credited you in the macos instructions in the README.md, really appreciate your work in verifying that.

@lorddavidson

lorddavidson commented May 14, 2026 via email

Copy link
Copy Markdown
Contributor Author

wiacal pushed a commit to wiacal/Clawdmeter that referenced this pull request May 14, 2026
Cherry-picks the macOS-specific pieces from PR HermannBjorgvin#5: Python daemon using
bleak (CoreBluetooth backend), LaunchAgent template, flash-mac.sh, and
install-mac.sh. Token is read from the macOS Keychain ("Claude
Code-credentials" service); Linux behavior is unchanged. README split
into "macOS installation" and "Linux installation" sections with
parallel Flash / Pair / Install subsections.

Co-Authored-By: Chris Davidson <36679917+lorddavidson@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
jjhuff added a commit to jjhuff/Clawdmeter that referenced this pull request May 15, 2026
Move per-board layout numbers (margins, panel sizes, font choices, splash
cell size) out of ui.cpp / splash.cpp into a single ui_layout.h with #if
branches per board. Shared values stay outside any ifdef; overrides are
added only where the original metrics actually break — currently just
UI_BT_LINE_FONT, which drops to styrene_24 on the 450-wide LilyGO so the
BT-screen MAC line doesn't clip at the right panel edge.

Adapted from the approach in PR HermannBjorgvin#5 (1.8" AMOLED port). Both Waveshare and
LilyGO envs build; BT screen verified on LilyGO hardware.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
AytuncYildizli added a commit to AytuncYildizli/clawdmeter that referenced this pull request May 15, 2026
…mascot

(1) Threshold-colored big number: white >=30% left, yellow 10-29%, red <10%.
Progress bar indicator matches. Critical-low signal is impossible to miss
without taking up extra screen real estate.

(2) Multi-account row cleanup: trimmed 'acct-' prefix at render time so the
4-char hash suffix shows alone (e.g. '9b7c 87%   c1f2 92%' instead of
'acct-9b7c 87% | acct-c1f2 92%'). Switched to 3-space separator for
breathing room. Trim only applied for auto-generated names; user-set labels
(future) render verbatim.

(3) Boot sequence: replaced the bright-orange 'CLAWDMETER BOOT' debug flash
with a black screen + dim 'clawdmeter' wordmark for 500ms. The orange flash
served its purpose during the flash-iteration debugging era; it's just
visual noise now.

(4) Real Codex mascot: generated via Gemini Nano Banana (same flow as Clawd)
with teal/cyan coloring and the same chubby blob silhouette. Post-processed
through codex_frames/postprocess.py (white-BG -> alpha, crop to bbox, resize
160x160 nearest), baked to firmware/src/assets/codex_sprite.h via
rescale_sprites.py. splash::show(codex_palette=true) now renders the teal
mascot on a teal backdrop instead of the procedural 'CODEX' label.

The Codex sprite is single-frame for now; the same 4-frame animation
pipeline (idle/blink/wave/sleep) could extend to Codex later if we want a
matching loop.

Skipped: auto-rotate progress hint (polish HermannBjorgvin#5) — useful but adds a global
animated bar widget and reset bookkeeping; defer to next round.
carroarmato0 pushed a commit to carroarmato0/Clawdmeter that referenced this pull request May 16, 2026
Cherry-picks the macOS-specific pieces from PR HermannBjorgvin#5: Python daemon using
bleak (CoreBluetooth backend), LaunchAgent template, flash-mac.sh, and
install-mac.sh. Token is read from the macOS Keychain ("Claude
Code-credentials" service); Linux behavior is unchanged. README split
into "macOS installation" and "Linux installation" sections with
parallel Flash / Pair / Install subsections.

Co-Authored-By: Chris Davidson <36679917+lorddavidson@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@HermannBjorgvin

Copy link
Copy Markdown
Owner

Closing since #25 added 1.8" device support. Please bring a PR if you have any feedback on it of course!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants