Назад

Дашборд использования Claude на M5Stack Basic — лимиты плана и расходы API на вашем столе

M5Stack Basic на клавиатуре ноутбука с дашбордом: аккаунт Claude Max на 88% недельного лимита, 5-часовая сессия на 30% и 142M токенов сегодня

Я использую Claude каждый день, и вопрос, который я задаю чаще всего, не о коде. Это «сколько недели у меня осталось?». Экран /usage в Claude Code отвечает на него, но только когда я останавливаюсь и набираю команду. Я хотел видеть ответ на своём столе — так же, как часы показывают время.

M5Stack Basic хорошо подходит для этого. Это готовое устройство: 2-дюймовый экран 320×240, три кнопки, батарея и ESP32 в корпусе размером 54 мм. Ни макетной платы, ни пайки.

В этой статье описывается дашборд: что он показывает, как данные попадают из Claude на экран, как устройство подключается без какой-либо настройки и какие шаги нужны, чтобы собрать свой. Интерфейс был спроектирован на M5Stack Core в Velxio ещё до того, как он попал на железо, и именно этот путь я рекомендую, если вы хотите собрать такой же. Вы также можете запустить эту прошивку в браузере на демо-данных, без устройства.

Дашборд на устройстве: смотреть на YouTube.

Весь код, прошивка и мост на ПК — на GitHub под лицензией MIT: velxio/m5claude. Раздел «Код, часть за частью» ниже описывает, что делает каждый файл.

Железо

M5Stack Basic v2.7: ESP32 с 2-дюймовым IPS-экраном 320x240, тремя кнопками, USB-C, слотом microSD и батареей 110 мАч

Плата — это M5Stack Basic Core IoT Development Kit v2.7:

Больше ничего не нужно: дашборд использует только то, что есть в корпусе. На плате нет IMU, микрофона, светодиодов или часов реального времени, поэтому дашборд использует всё остальное: экран и кнопки, динамик для оповещений, подсветку для экономии батареи и чип питания для отображения заряда.

Что показывает экран

Дашборд работает с двумя видами аккаунтов Claude, и с несколькими каждого вида:

Для обоих видов показываются токены за день за последнюю неделю, разбитые на входные, выходные, чтения кэша и записи кэша, а также по моделям.

Есть четыре вида. B переключает на следующий, A и C переключают между аккаунтами, удержание B запрашивает у ПК свежие данные, а удержание C открывает настройки. Вот все экраны с анимацией, которую проигрывает каждый вид при открытии:

Анимированный обзор всех экранов: обзор с тремя аккаунтами, виды лимитов, токенов и разбивки, API-организация, обзор одного аккаунта, зарядка батареи, настройки на английском и испанском, запрос подтверждения и экран ожидания

Обзор. Одна карточка на аккаунт. Раскладка подстраивается под количество аккаунтов: один аккаунт занимает весь экран, два получают карточки повыше со строкой сегодняшнего использования, а три и больше превращаются в прокручиваемый список.

Обзор с одним аккаунтом Claude Max: недельный лимит в виде кольца, 5-часовая сессия и лимиты по моделям справа, а также сегодняшние токены с семидневным графиком

Обзор с двумя аккаунтами Max и API-организацией: недельный процент, полосы за 5 часов и 7 дней, время сброса и семидневные расходы для API-аккаунта

Лимиты. Недельный лимит в виде кольца, рядом сессия и лимиты по моделям. Названия моделей приходят от самого Claude, поэтому строки соответствуют тем лимитам, которые есть в вашем плане. Цвета меняются на 60% (янтарный) и 85% (красный).

Вид лимитов: недельное кольцо на 67%, 5-часовая сессия на 42%, недельные лимиты Opus и Sonnet

Токены. Сегодня, последние семь дней и сумма в долларах, затем токены за день с пунктирной линией на среднем значении. Для подписки сумма в долларах — это то, сколько те же токены стоили бы по прайс-листу API. Это не списание, но полезный способ увидеть, насколько интенсивно вы используете план.

Вид токенов: 2,84 млн токенов сегодня, 20,8 млн за семь дней, стоимость по API $84,20 и столбчатая диаграмма токенов за день

Вид токенов на устройстве: 142 млн токенов сегодня и 296 млн за семь дней

Разбивка. Токены за неделю по типам и по моделям. С Claude Code чтения кэша обычно составляют большую часть общего объёма.

Вид разбивки: составная полоса входных, выходных токенов, чтений кэша и записей кэша, а также доля каждой модели

Вид разбивки на устройстве: почти все 296 млн токенов за неделю — это чтения кэша, разделённые между Opus и Fable

Точка рядом с часами показывает состояние связи: зелёная, пока данные свежие, янтарная, когда они устарели, красная, когда ПК не подключён. На фотографиях мой собственный аккаунт. На скриншотах демо-аккаунты.

Батарея, звук и настройки

Рядом с часами — батарея, нарисованная так, как её рисуют телефоны: уровень и молния с заполнением, которое растёт во время зарядки. Микросхема питания IP5306 сообщает только четыре ступени (25, 50, 75 и 100%), поэтому число меняется шагами по 25.

Заголовок во время зарядки: 75% с молнией и зелёной батареей, рядом точка связи и часы

Динамик используется для оповещений. Когда сессионный или недельный лимит пересекает 90% (или 80%, если вы так выбрали), устройство играет короткий двойной сигнал и показывает, какой аккаунт и какой лимит. Когда лимит сбрасывается, оно играет восходящий сигнал. Запросы подтверждения с нового компьютера тоже издают звук. Щелчки кнопок опциональны.

Удержание C открывает настройки. A и C перемещают, B меняет значение, а удержание B закрывает экран. Настройки сохраняются на устройстве.

Экран настроек: язык, яркость, звуки, порог оповещения, выключение экрана от батареи, ночное затемнение, сопряжённые компьютеры и версия прошивки

Те же экраны на испанском: настройки и обзор

Обзор на испанском

Как заставить 110 мА·ч работать долго

Первая прошивка разряжала батарею заметно меньше чем за час. Процессор работал на 240 МГц, экран перерисовывался каждую секунду, а радио передавало на полной мощности с интервалом соединения 15–30 мс. Ничего из этого не нужно, чтобы показывать число, которое меняется раз в минуту. От батареи прошивка теперь делает следующее:

Для использования весь день вдали от стола Battery Module 13.2 ставится под Basic и добавляет 1500 мА·ч.

Как это работает

Данные поступают из логина и транскриптов Claude Code и из Admin API в мост на Python, затем по USB или Bluetooth LE на M5Stack, который рисует только то, что ему прислали

Главное правило дизайна — устройство ничего не знает. В нём нет ни учётных данных Claude, ни настроек Wi-Fi. Небольшая программа на ПК, мост, собирает всё и отправляет устройству снимок для отрисовки. Так секреты не попадают на устройство, которое лежит на столе, а смена компьютера или сети не требует перенастройки.

Откуда берутся данные

Мост — это около 1100 строк на Python с двумя зависимостями (pyserial и bleak). Он читает три источника:

  1. Лимиты тарифа из логина Claude Code. Каждый каталог конфигурации Claude Code (~/.claude, ~/.claude-work, …) хранит логин одного аккаунта. Мост находит их все и использует каждый токен, чтобы прочитать те же лимиты, что показывает экран /usage в Claude Code. Он только читает токен и никогда его не обновляет, потому что обновление ротировало бы токен и разлогинило Claude Code.
  2. Токены из транскриптов Claude Code. Каждый ответ, который получает Claude Code, записывается в файл JSONL в projects/ вместе с расходом токенов и моделью. Мост суммирует их по дням, убирает дубликаты (возобновлённая сессия копирует более ранние сообщения в новый файл) и оценивает их по прайс-листу API.
  3. Расходы для API-организаций из Admin API Usage и Cost. usage_report/messages даёт токены по дням и моделям. cost_report даёт реальные расходы. Обоим нужен ключ Admin API (sk-ant-admin01-...).

Два урока, полученных при работе с реальными аккаунтами:

Снимок

Каждое обновление порождает одну строку JSON примерно на 600 байт:

{"v":1,"ts":1792770195,"tz":3600,"acc":[
 {"n":"Personal","p":"Max 20x","k":"sub","ok":1,
  "s":[42,1792778235],"w":[67,1793037195],"x":[["Opus",54,1793037195],["Sonnet",31,1793037195]],
  "td":2840000,"tk":[2310000,1480000,15900000,1120000],"c":84.2,"ct":11.35,
  "d":[1900000,3400000,2600000,4100000,3300000,2670000,2840000],"m":[["Opus",61],["Sonnet",34],["Haiku",5]]}]}

s, w и x — это лимиты сессии, недели и по моделям в виде [процент, время сброса]. d — токены за день. ts и tz — часы ПК и смещение UTC. У M5Stack Basic нет часов реального времени и базы часовых поясов, поэтому устройство берёт оба значения из снимка и дальше считает секунды от них. Этого достаточно для «сброс через 2ч 14м» и «вт 04:00».

Подключение без настройки

Я хотел вообще никакой настройки. Вводить пароль Wi-Fi на устройстве с тремя кнопками — удовольствие ниже среднего. Сохранение IP-адреса ПК на устройстве ломается, как только вы меняете компьютер. Поэтому устройство поддерживает два канала связи, и ни один из них не требует настроек.

USB. Воткните кабель. Мост ищет последовательные порты, USB-чип которых принадлежит M5Stack (CH9102 или CP2104). Он открывает порт, не переключая DTR и RTS, чтобы ESP32 не перезагружался, и ждёт приветствия. Прошивка отправляет {"hello":"m5claude",...} каждые две секунды, пока не придут данные. Если приветствие не приходит в течение нескольких секунд, мост освобождает порт и оставляет его в покое на некоторое время, чтобы не мешать другим платам ESP32 и инструментам прошивки.

Bluetooth LE. Прошивка анонсирует GATT-сервис с двумя характеристиками: в одну ПК пишет строки, по другой устройство отправляет уведомления. Мост сканирует UUID сервиса и подключается. Никаких диалогов сопряжения Windows и ничего, что нужно выбирать из списка.

Поскольку любое устройство в радиусе действия может найти устройство, каждый новый ПК одобряется один раз, на самом устройстве:

Запрос одобрения: «Новый компьютер, DESKTOP-STUDIO. Разрешить ему отправлять данные об использовании?» с «Отклонить» на кнопке A и «Разрешить» на кнопке C

Обмен при сопряжении: приветствие от устройства, имя ПК и стабильный id от моста, ожидающий ответ, запрос на экране, затем ok, запрос обновления и снимки

Мост хранит случайный id в ~/.m5claude/pc_id. Устройство хранит id до четырёх одобренных ПК в NVS. Известный ПК принимается сразу, а удержание A при включении забывает их все. Устройство, уже подключённое по USB, пропускается по Bluetooth, чтобы его не просили одобрить один и тот же ПК дважды.

Пока мост не запущен, устройство показывает, что делать:

Экран ожидания: «Ожидание вашего ПК. Запустите m5claude-bridge на компьютере. Он подключается по USB или Bluetooth автоматически.»

Прошивка

Прошивка — это скетч Arduino, собранный через arduino-cli на ядре arduino-esp32 2.0. Он использует три библиотеки:

Код интерфейса не зависит от аппаратного обеспечения. Он рисует в цель LovyanGFX и читает три кнопки. Всё, что специфично для платы (панель, USB, BLE, NVS), живёт в скетче.

Несколько деталей, которые делают его похожим на продукт, а не на демо:

Отрисовка без PSRAM и диагональные полосы

Полный кадр 320×240 в 16-битном цвете — это 150 КБ. Самый большой свободный блок памяти ESP32 при работающем Bluetooth меньше этого. Поэтому интерфейс рисуется четыре раза за кадр в полосу 320×60 (38 КБ). Каждый проход рисует всё со сдвигом на смещение полосы, а части, выходящие за пределы полосы, обрезаются.

Когда это впервые запустилось на плате, экран показал диагональные полосы, а кнопки запроса одобрения появились дважды — сверху и снизу. Конфигурация панели была моим первым подозреваемым. Я переписал её вручную по документации M5Stack, и ничего не изменилось. Причина была в другом:

С одним буфером следующая полоса рисуется в буфер, пока DMA всё ещё отправляет его. С двумя буферами один рисуется, пока другой отправляется, и CPU ждёт завершения передачи перед повторным использованием буфера

LovyanGFX отправляет спрайт на панель через DMA в фоновом режиме. Мой цикл начинал рисовать следующую полосу в тот же буфер, пока предыдущая всё ещё отправлялась, поэтому панель получала половину одной полосы и половину следующей. Исправление использует два буфера по очереди и ждёт завершения предыдущей передачи перед отправкой:

for (int y = 0, k = 0; y < 240; y += 60, k ^= 1) {
  LGFX_Sprite& band = bands[k];
  band.fillScreen(BG);
  draw_ui(band, /*offset_y=*/y);   // runs while the other buffer is still being sent
  lcd.waitDMA();                    // the other buffer's transfer has finished
  band.pushSprite(&lcd, 0, y);      // starts this buffer's transfer
}
lcd.waitDMA();

Это стоит ещё одного буфера на 38 КБ из примерно 275 КБ свободной RAM.

Код, часть за частью

Скачайте код командой git clone https://github.com/velxio/m5claude.git или ZIP-архивом по кнопке Code в репозитории. В нём две половины, которые не связывает ничего, кроме протокола: bridge/ работает на ПК, а firmware/ и src/ — на M5Stack.

На M5Stack

firmware/m5claude/m5claude.ino: всё, что специфично для платы.

src/app/app.cpp: протокол, независимый от канала связи.

src/model/: данные.

src/ui/: экраны.

На ПК

Мост находится в bridge/m5claude_bridge/. Его единственные зависимости — pyserial и bleak. HTTPS-запросы используют стандартную библиотеку.

__main__.py: командная строка и главный цикл.

autostart.py регистрирует мост для запуска при входе в систему без окна: ключ реестра Run с pythonw в Windows, LaunchAgent в macOS, пользовательский юнит systemd в Linux.

config.py: аккаунты.

sources/: один файл на источник данных.

pricing.py содержит каталожные цены API по семействам моделей. Он оценивает ценность использования подписки.

snapshot.py: сборка снимка.

hub.py хранит новейший снимок и отдаёт его каждому подключённому устройству. Медленный канал получает только последний, никогда не очередь.

transports/: один файл на канал связи.

В README репозитория тот же обзор в виде таблиц, плюс устранение неполадок.

Соберите свой

Порядок, который я рекомендую: сначала спроектируйте экраны в Velxio, затем прошейте плату, затем подключите мост.

1. Запустите и измените его на M5Stack Core в Velxio

Velxio эмулирует M5Stack Core с его экраном 320×240, кнопками A, B и C и чипом батареи. Вёрстка двухдюймового экрана — это масса мелких правок (подпись на два пикселя ниже, число, не влезающее в свою карточку), и каждая занимает секунды в браузере вместо цикла прошивки.

Дашборд есть в галерее примеров Velxio, с теми же исходными файлами, что и в репозитории:

  1. Откройте M5Stack Core: Claude usage dashboard (m5claude) и нажмите кнопку воспроизведения. Регистрация не нужна. Он запускается на демо-аккаунтах из этой статьи.
  2. Нажимайте A и C, чтобы выбрать аккаунт, и B, чтобы переключать виды. Симулятор выполняет прошивку медленнее платы, поэтому чтобы открыть настройки, удерживайте C несколько секунд.
  3. Чтобы увидеть свои собственные цифры, запустите m5claude-bridge snapshot на ПК и вставьте строку, которую он выведет, в монитор последовательного порта. В первом комментарии скетча есть пример строки, которую можно отредактировать.
  4. Измените экраны в ui.cpp и запустите снова. Когда они будут выглядеть как надо, прошейте плату.

Два отличия от платы: в Velxio нет Bluetooth, поэтому это соединение опущено и монитор последовательного порта — единственный канал связи, а код динамика использует вызовы более нового ядра ESP32 Arduino. Каждое изменение отмечено в скетче.

Чтобы начать собственный дашборд с пустого экрана, M5Stack Core: Hello LCD + Buttons — самый маленький пример. Он использует M5GFX от M5Stack, который построен на LovyanGFX и разделяет его API отрисовки, так что код переносится между ними.

2. Прошейте прошивку

git clone https://github.com/velxio/m5claude.git && cd m5claude
arduino-cli core install esp32:esp32
arduino-cli lib install LovyanGFX NimBLE-Arduino ArduinoJson

./firmware/build.sh /dev/ttyUSB0      # Linux / macOS
.\firmware\build.ps1 -Upload          # Windows, finds the COM port by itself

Скрипты собирают для M5Stack Core со схемой разделов, оставляющей место для большого приложения (PartitionScheme=no_ota). Прошивка весит около 820 КБ. Две настройки застали меня врасплох:

3. Запустите мост

pip install -e bridge                # from the repository root; installs pyserial and bleak
m5claude-bridge accounts             # which accounts it found
m5claude-bridge autostart on         # start now, and at every login

autostart on регистрирует мост для запуска при входе в систему, без окна. В Windows он добавляет значение в раздел реестра Run пользователя, которое запускает pythonw. В macOS он устанавливает LaunchAgent, а в Linux — пользовательскую службу systemd. autostart status показывает, запущен ли он, и последние строки его журнала в ~/.m5claude/bridge.log. Одновременно работает только один мост: второй будет конкурировать за порт USB и соединение Bluetooth, поэтому он завершается с сообщением. Запуск m5claude-bridge сам по себе оставляет его на переднем плане, с журналом в терминале.

Аккаунты Pro и Max находятся по конфигурационным каталогам Claude Code. Чтобы добавить вторую подписку, войдите в неё под её собственным каталогом:

$env:CLAUDE_CONFIG_DIR = "$HOME\.claude-work"; claude    # then /login

API-организациям нужен ключ Admin API из Claude Console в разделе Settings → Admin keys:

m5claude-bridge add-api "Acme API" --key-env ACME_ADMIN_KEY

4. Подключите

Подключите кабель USB или оставьте устройство на столе и позвольте Bluetooth найти его. При первом подключении по Bluetooth нажмите C на устройстве, чтобы одобрить ПК. Данные появятся через несколько секунд.

Оговорки

Что дальше

Код находится на github.com/velxio/m5claude. Issues и pull requests приветствуются.

Спасибо M5Stack за плату, готовую к использованию из коробки, и авторам LovyanGFX, NimBLE-Arduino, ArduinoJson и bleak.

Ссылки на магазин M5Stack на этой странице являются партнёрскими: если вы покупаете через них, Velxio получает небольшую комиссию без дополнительных затрат для вас, и это помогает сохранять симулятор бесплатным.


Поделиться:
David Montero

Автор

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Похожие статьи


Предыдущая статья
Милый настольный робот: лицо, которое слушает, на ESP-VoCat с эмулятором в браузере
Следующая статья
Raspberry Pi 4 и 5 в браузере: базовый режим и режим Linux, шаг за шагом