把 DeepSeek 余额放到桌面上:ESP8266 AI 用量小屏实践

Personal AI Infrastructure 系列第一篇。

ESP8266 DeepSeek Usage Dashboard

1. 为什么要做这个小屏

1)硬件看余额更顺手。网页适合配置和管理,桌面小屏适合提醒和感知。平时根本不会想起来看,放到物理设备上之后,就会变成环境的一部分。

2)AI Agent 早就是我开发环境的一部分了。你一旦习惯让它写代码、改项目,自然会开始盯token还剩多少、余额够不够烧。以前看 DeepSeek 余额得进网页翻账户页,所以干脆摆块小屏,抬头就能看到。

3)外显token或余额设备本身也可以成为一个符号。就像潮牌衣服、桌面摆件一样,它会释放一种信号:我在用什么工具,我关心什么问题,我在搭什么东西。懂的人看到这个设备,很容易聊到AI Agent、个人基础设施,更像一种个人品牌的外部标签。

2. 系统设计-由云端采集

云端负责拿数据,ESP8266负责显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DeepSeek Usage
|
v
Alibaba Cloud ECS
|
v
Node.js server.js
|
| HTTP JSON API
v
ESP8266 over Wi-Fi
|
v
OLED

每一层的职责如下:

  • DeepSeek Usage:数据来源,当前使用 DeepSeek 官方余额接口。https://api-docs.deepseek.com/zh-cn/api/get-user-balance
  • Alibaba Cloud ECS:云端中间层,负责保存敏感配置、访问 DeepSeek API、处理失败与缓存。
    ESP8266 DeepSeek Usage Dashboard
  • server.js:对ESP8266暴露轻量 HTTP JSON API。
  • ESP8266:低成本边缘终端,只负责连 Wi-Fi、请求 API、解析字段、刷新屏幕。
  • OLED:本地物理仪表盘,用来显示关键资源状态。

ESP8266 不处理Token、网页解析、第三方API Key。敏感信息和复杂逻辑放在ECS上,边缘设备只消费整理好的JSON。

这样做的好处是后面扩展比较自然。如果以后要接入OpenAI Usage、Claude Usage指标,只需要扩展云端数据源和API,ESP8266显示逻辑可以尽量保持稳定。

3. 实现细节

项目主要包含两部分:运行在阿里ECS上的Node.js服务,以及烧录到ESP8266的Arduino程序。

1
2
3
4
5
6
7
deepseek-balance/
server.js
package.json
ecosystem.config.js

OpenAIUsageDisplay/
OpenAIUsageDisplay.ino

deepseek-balance 是云端服务,OpenAIUsageDisplay.ino 是设备端代码。

3.1 ECS 上的 Node.js 服务

Node.js 服务位于 deepseek-balance/server.js。它负责读取环境变量DeepSeek API Key,定时请求余额接口,并对ESP8266暴露一个简单的HTTP JSON。

展开核心配置
1
2
3
4
5
const PORT = Number(process.env.PORT || 8788);
const REFRESH_INTERVAL_MS = Number(process.env.REFRESH_INTERVAL_MS || 60000);
const DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY;
const SOURCE = 'deepseek_user_balance_api';
const BALANCE_URL = 'https://api.deepseek.com/user/balance';

服务启动后会立即刷新一次余额,并每 60 秒自动刷新。ESP8266主要访问这个接口:

1
GET /deepseek-balance

返回格式类似下面这样:

1
2
3
4
5
6
7
8
9
10
11
{
"updated_at": "2026-06-22T12:00:00.000Z",
"source": "deepseek_user_balance_api",
"is_available": true,
"currency": "CNY",
"total_balance": "100.00",
"granted_balance": "0.00",
"topped_up_balance": "100.00",
"granted_balance_expire_at": null,
"error": null
}

当前服务监听 0.0.0.0:8788,因此ESP8266可以通过公网IP访问:

1
http://公网ECSIP:8788/deepseek-balance

3.2ESP8266请求 API

ESP8266侧代码位于 OpenAIUsageDisplay.ino。设备端只做:连接Wi-Fi、请求接口、解析字段、刷新屏幕。

1
2
3
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

请求DeepSeek余额的逻辑在 fetchBalance() 。先检查 Wi-Fi 状态,如果断连就重新调用 connectWiFi()

1
2
3
4
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
if (WiFi.status() != WL_CONNECTED) return false;
}

3.3 OLED / TFT 显示设计

当前显示逻辑在 drawScreen() 中,核心信息包括总余额、账户是否可用、最近更新时间和服务状态。

最常用的drawText() 方法的第一个数字表示 x 轴坐标,第二个数字表示 y 轴坐标,后面依次是显示内容、文字颜色、背景颜色和字体大小。有代码基础的同学阅读起来应该很容易。

展开显示逻辑片段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
void drawScreen() {
//清空整个屏幕,相当于先用黑色背景重新刷一遍,避免上次内容残留。
fillRect(0, 0, TFT_W, TFT_H, BLACK);
//判断当前接口状态和账户状态。
bool ok = snapshot.status == "OK";
bool accountOk = snapshot.isAvailable == "YES";

// Blue外框 左上角显示标题
drawRectLine(0, 0, TFT_W, TFT_H, BLUE);
drawText(5, 6, "Zxj DEEPSEEK", CYAN, BLACK, 1);

// 右上角状态
if (ok) {
fillRect(104, 5, 18, 10, GREEN);
drawText(107, 6, "OK", BLACK, GREEN, 1);
} else {
fillRect(98, 5, 24, 10, RED);
drawText(101, 6, "ERR", WHITE, RED, 1);
}

drawHLine(20, BLUE);

//BALANCE 标题,再显示币种。
//substring(0,3)的作用是只截取币种字符串的前三个字符
drawText(5, 28, "BALANCE", WHITE, BLACK, 1);
String currency = snapshot.currency.substring(0, 3);
drawText(5, 42, currency, YELLOW, BLACK, 1);

//由于余额使用的是大字体,根据余额字符串长度计算宽度,让余额显示在屏幕中间。
String balance = snapshot.totalBalance.substring(0, 8);
int balanceWidth = balance.length() * 12;
int balanceX = (TFT_W - balanceWidth) / 2;
if (balanceX < 2) balanceX = 2;

drawText(balanceX, 55, balance, GREEN, BLACK, 2);

drawHLine(82, BLUE);

drawText(5, 98, "updated_at", WHITE, BLACK, 1);

// 底部时间
if (snapshot.updated.length() >= 16) {
String shortTime = snapshot.updated.substring(5, 10) + " " + snapshot.updated.substring(11, 16);
drawText(5, 107, shortTime, YELLOW, BLACK, 1);
} else {
drawText(5, 107, "-- --:--", YELLOW, BLACK, 1);
}

// 账户状态 右下角
drawText(76, 107, "ACCT", WHITE, BLACK, 1);

if (accountOk) {
drawText(104, 107, "YES", GREEN, BLACK, 1);
} else {
drawText(110, 107, "NO", RED, BLACK, 1);
}
}

4. 后续计划

可能的后续计划包括:

扩展 Usage Source

  • OpenAI Usage
  • Claude Usage
  • Codex Usage
  • 股票监控
  • 服务器状态

扩展API Gateway

  • 多数据源聚合
  • 鉴权
  • 告警触发
  • Web Dashboard

整体演进 :

  • Web Dashboard
  • 多块 OLED / 墨水屏
  • 额度低于阈值时发送提醒
  • 图形化额度展示
  • 增加外壳并产品化

最想优先做的是多数据源聚合,单个余额小屏只是开始,如果能同时显示多个AI工具的状态,就会更接近一个真正的个人AI资源面板。

5. 状态展示

ESP8266 DeepSeek Usage Dashboard

ESP8266 DeepSeek Usage Dashboard