Skip to main content

codex-usage-epd

PyPI Version PyPI Python Version

Push your OpenAI Codex usage statistics to a 4.2" 400x300 three-colour e-paper display powered by the EPD-nRF5 firmware.

Demo of the e-paper usage display

Features

  • Plan quota: 5-hour + weekly windows (used / remaining %, reset time)
  • "Tokens used today": a Total across all models, plus the top three models with bars proportional to the most-used model
  • Optional "Last 7 days" line chart for the seven completed local calendar days before today, with dates and compact K/M/B totals. Enable render.show_history or pass --show-history to place the chart beside today's usage
  • Credits balance when present on the plan
  • Red alert bars when remaining % drops below render.warn_threshold
  • --selftest verifies RLE + bitplane round-trips without network/hardware

Requirements

  • macOS (BLE via bleak/CoreBluetooth), Python 3.10+
  • ChatGPT login for Codex (~/.codex/auth.json with tokens.access_token)
  • 4.2" 400x300 B/W/R panel with SSD1683/SSD1619 driver, model id 0x02

Install with a coding agent

Copy and paste this prompt into Codex or another coding agent:

Install https://github.com/hunterMG/codex-usage-epd on this computer. Read the
README first, check that the prerequisites are available, clone the repository
into an appropriate user directory, install its dependencies with uv, generate
the configuration file, and run the self-test. Do not print, copy, or modify my
Codex authentication token. Tell me what configuration still needs my input,
and ask for confirmation before installing or starting the launchd background
agent.

Setup

Clone this repo and cd to it in terminal.

uv sync --locked                     # creates .venv, installs deps + the package (editable)
uv run codex-usage-epd --init        # generate config/codex_usage_epd.yaml from the template
# edit config/codex_usage_epd.yaml (set ble.device etc.)
uv run codex-usage-epd --selftest    # render preview.png, no net/BLE
uv run codex-usage-epd --dry-run     # live fetch + render preview.png

Usage

uv run codex-usage-epd --init          # generate a config from the template
uv run codex-usage-epd --selftest      # sample data, verify encode/decode
uv run codex-usage-epd --dry-run       # fetch + render preview.png (no BLE)
uv run codex-usage-epd --probe         # connect + INIT, print device config/mtu
uv run codex-usage-epd --test-screen   # INIT + CLEAR full refresh (firmware check)
uv run codex-usage-epd --once          # fetch + render + push to display
uv run codex-usage-epd --loop          # push every N minutes forever

Modifiers (combine with the actions above):

--config <path>    # use this YAML config instead of the default
--force            # with --init: overwrite an existing config
--font <path>      # override render.font
--sample           # use synthetic sample data (no network)
--debug            # also dump raw wham/usage JSON to tmp/usage_dump.json

Config resolution when --config is not given: repo config/codex_usage_epd.yaml, then ~/.config/codex-usage-epd/codex_usage_epd.yaml, then the bundled template.

ble.device accepts auto (scans for NRF_EPD), a MAC address, or a name substring.

Installing as a package

Install the latest release from PyPI:

uv tool install codex-usage-epd
# or, inside an existing environment:
uv add codex-usage-epd

The config template lives at config/codex_usage_epd.yaml.example. Run codex-usage-epd --init to generate a real config (~/.config/codex-usage-epd/ when installed, config/ in a checkout), or point at your own with --config /path/to/codex_usage_epd.yaml.

launchd (every 60 minutes)

./deploy/install.sh    # fills the __REPO__ placeholder with the checkout path
                       # and bootstraps the agent (works for any username)

This generates ~/Library/LaunchAgents/com.codex-usage-epd.plist from deploy/com.codex-usage-epd.plist.in, so no manual path editing is needed. To remove the agent later:

launchctl bootout gui/$(id -u)/com.codex-usage-epd
rm ~/Library/LaunchAgents/com.codex-usage-epd.plist

Configuration

Generate a config with codex-usage-epd --init, then edit config/codex_usage_epd.yaml (or ~/.config/codex-usage-epd/ when installed). Notable keys:

  • display.width / display.height - panel pixels (400x300); display.model_id - EPD panel model id (0x02 for SSD1619 400x300 BWR)
  • display.sleep_after_push - send the SLEEP command after pushing (default false; early sleep aborts the panel refresh)
  • ble.device - auto | MAC address | name substring
  • ble.scan_timeout - seconds per scan attempt; ble.scan_retries - retry the scan before giving up (missed advertisements)
  • ble.interleave - writes per response-ack, mirrors the web client (50)
  • ble.pacing_ms - delay between writes (0.0 = back-to-back)
  • ble.hold_after_refresh - seconds to stay connected so the panel refresh completes (20)
  • ble.slot - which image slot to write on the epdiy.cn slot firmware (0..N-1); "auto" picks the first free slot so an existing slot is never overwritten; -1/"none" disables the SET_SLOT command (plain EPD-nRF5 firmware)
  • codex.auth_file - where the OAuth tokens live (default ~/.codex/auth.json)
  • codex reads chatgpt_base_url from ~/.codex/config.toml if set
  • render.font - .ttf path (auto-detected on macOS/Windows/Linux otherwise)
  • render.warn_threshold - remaining % that turns a bar red
  • render.preview - filename for the rendered preview PNG
  • render.show_history - show the "Last 7 days" chart (default false); override with --show-history or --no-show-history, including in --selftest
  • schedule.interval_minutes - interval used by --loop; launchd uses the fixed StartInterval in deploy/com.codex-usage-epd.plist.in

Notes

  • Tokens are read from ~/.codex/auth.json and never logged or committed.
  • The display must be powered (USB). With ble.patch_wakeup_pin: true it forces the device config byte to 0xFF so the panel keeps re-advertising after the timeout, letting the scheduled push always connect.

Development

uv sync --locked
uv run pre-commit install
uv run pre-commit run --all-files

License

GNU AGPL v3.0 or later — see LICENSE.

Metadata

Release files for codex-usage-epd 2026.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for codex-usage-epd 2026.10.1
File Size Uploaded Provenance
codex_usage_epd-2026.10.1.tar.gz 309.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for codex-usage-epd 2026.10.1
File Interpreter ABI Platform
codex_usage_epd-2026.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 350.9 kB

Release files / codex_usage_epd-2026.10.1.tar.gz

Download URL codex_usage_epd-2026.10.1.tar.gz
Size 309.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a4955755a5312ff0aa7d96a0210e1ebfe37be44525161b87446cd433f180ed4b
BLAKE2b-256 checksum
How to use checksums
9437dd412e4bfed612fd9ab04b2840d4485d8a8caaf42694766d383c99e807a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / codex_usage_epd-2026.10.1-py3-none-any.whl

Download URL codex_usage_epd-2026.10.1-py3-none-any.whl
Size 41.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
53fc0963ee49845beca8ec1351e59ab38792851d011cdd9d754b7afa9bba8485
BLAKE2b-256 checksum
How to use checksums
6d344c2a46c65a875a0c47a7dfac97446156051fe2a6117c00f143e7f4a67106
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for codex-usage-epd 2026.10.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for codex_usage_epd-2026.10.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

2026.10.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page