乐于分享
好东西不私藏

【人工智能】Claude Code 实体状态灯:15 元给 xiaocc助手 装个「指示灯」

【人工智能】Claude Code 实体状态灯:15 元给 xiaocc助手 装个「指示灯」

成品效果:

省流版

已关注
关注
重播 分享

详细版

已关注
关注
重播 分享

🛠️ 一杯咖啡的时间,让你的 AI 助手学会「打信号」

本文适合:正在用 Claude Code 写代码,想给 AI 加个硬件外设的折腾党
阅读时间:约 6 分钟
最终效果:显示器旁一盏三色 LED,余光一扫就知道 AI 在干什么

🤔  起因:AI 在「思考」还是「卡住了」?

用 Claude Code 写代码时,你有没有遇到过这种场景:

发完指令后切到浏览器查资料,几分钟后切回来——发现它还在「思考」。更糟的是,它弹出权限请求卡住了,而你浑然不知,白白等了半天。

于是我决定搞一个实体状态灯,放在显示器旁边,用余光就能判断 AI 的工作状态:

💡 灯光
含义
你的操作
🟡 黄灯慢闪
AI 正在思考 / 执行中
该干嘛干嘛,等它
🔴 红灯快闪
需要你介入(权限请求/出错)
快切回来看看
🟢 绿灯常亮
任务完成,等你下指令
给新任务

  🛒 硬件清单(总价 ≈ ¥15)

部件
数量
参考价
Arduino Uno 开发板
×1
~¥12
LED 灯珠(红 / 黄 / 绿)
各×1
~¥0.5
220Ω 电阻
×3
~¥0.3
杜邦线 + 面包板
若干
~¥5
USB 数据线
×1
已有

如果你手头有 Arduino Nano 或 ESP32 开发板,完全可以替换,接线一样简单。

接线图(文字版)

Arduino Uno LED

D2 ──→ 220Ω ──→ 红色 LED 正极,负极 → GND

D3 ──→ 220Ω ──→ 黄色 LED 正极,负极 → GND

D8 ──→ 220Ω ──→ 绿色 LED 正极,负极 → GND

三条线,三个电阻,接完就能用,不需要任何额外模块。

  💻 Arduino 固件(直接烧录)

Arduino 端的逻辑非常简单:监听串口指令,控制对应 LED 闪烁

指令集只有四个字母:

R → 红灯快闪    Y → 黄灯慢闪    G → 绿灯常亮    X → 全部熄灭

完整代码如下(可直接复制到 Arduino IDE 烧录):

Arduino C++ — led_indicator.ino

// 串口指令:R=红灯快闪, Y=黄灯慢闪, G=绿灯, X=全灭

#define RED_PIN 2

#define YELLOW_PIN 3

#define GREEN_PIN 8

void setup() {

pinMode(RED_PIN, OUTPUT);

pinMode(YELLOW_PIN, OUTPUT);

pinMode(GREEN_PIN, OUTPUT);

Serial.begin(9600);

// 启动时绿灯快闪 3 次表示就绪

for (int i = 0; i < 3; i++) {

    digitalWrite(GREEN_PIN, HIGH); delay(100);

    digitalWrite(GREEN_PIN, LOW); delay(100);

}

digitalWrite(GREEN_PIN, HIGH);

}

void loop() {

if (Serial.available()) {

    char cmd = Serial.read();

    switch (cmd) {

    case 'R': blinkRed(100); break;

    case 'Y': blinkYellow(600); break;

    case 'G': allOff();

                digitalWrite(GREEN_PIN, HIGH); break;

    case 'X': allOff(); break;

    }

}

}

void blinkRed(int ms) {

while (!Serial.available()) {

    digitalWrite(RED_PIN, HIGH); delay(ms);

    digitalWrite(RED_PIN, LOW); delay(ms);

}

}

void blinkYellow(int ms) {

while (!Serial.available()) {

    digitalWrite(YELLOW_PIN, HIGH); delay(ms);

    digitalWrite(YELLOW_PIN, LOW); delay(ms);

}

}

void allOff() {

digitalWrite(RED_PIN, LOW);

digitalWrite(YELLOW_PIN, LOW);

digitalWrite(GREEN_PIN, LOW);

}

烧录到 Arduino Uno(COM5,9600bps)即可,一行命令搞定:

Shell

arduino-cli compile --fqbn arduino:avr:uno led_indicator/

arduino-cli upload -p COM5 --fqbn arduino:avr:uno led_indicator/

  🖥️ 电脑端方案演进(踩坑全记录)

这部分是本文的精华所在。从最初的想法到最终跑通,踩了四个方案的坑才找到正确答案。

❌ 方案 1:Python + HTTP 守护进程

思路:Python HTTP 服务常驻 → Claude Code hooks 触发 bat 脚本 → bat 调用 curl → HTTP 请求 → 串口写指令。

翻车原因
• 每次 Python 重新打开 COM5 会触发 Arduino 硬件复位(DTR 信号),有 3 秒延迟
• 升级为「守护进程模式」独占串口后,又遇到 Windows 串口权限问题

❌ 方案 2:Node.js TCP 桥接

思路:参考开源项目 agent-light,用 Node.js 做 TCP 桥接:serial-bridge.mjs 常驻进程独占 COM5,hook-client.mjs 被 hooks 调用时发 TCP 指令。

翻车原因:桥接本身工作完美——手动测试串口通信、TCP 转发全正常。但 hooks 始终不触发

❌ 方案 3:opencode-led 框架改造

思路:参考 opencode-led 的 MQTT + ESP32 方案,保留 hooks + daemon 架构,只把 MQTT 输出换成串口。

关键发现/hooks 命令显示 hooks 配置正确,但实际从未执行——stdin JSON 事件数据根本没有传入。

重大发现:经过数十次调试(不同格式、完整路径、timeout 参数、bash/cmd/node 各种命令),最终确认:

Claude Code v2.1.187 + DeepSeek API 后端,hooks 系统不工作。 这是一个客户端无法修复的根因问题。

✅ 方案 4:文件系统监控(最终方案)

既然 hooks 不可用,那就彻底绕过它。

灵光一闪:Claude Code 的每次交互都会写入 session JSONL 文件(位于 ~/.claude/projects/),实时记录每一条事件。那为什么不直接监控这个文件?

Claude Code 输入框

    │

    ↓ (自动写入 session JSONL)

监控脚本轮询文件变化

    │

    ↓ (检测事件类型)

通过串口发送指令 (R/Y/G/X)

    │

    ↓

Arduino → LED 亮起 ✨

核心监控逻辑(仅约 120 行 Node.js)

JavaScript — led-monitor.mjs 核心代码

// 每 500ms 轮询最新的 session JSONL 文件

function poll() {

const latest = findLatestSession(); // 找最新修改的 .jsonl

if (latest.mtime > lastMtime || latest.size !== lastSize) {

    const lastLine = readLastLine(latest.path);

    const event = JSON.parse(lastLine);

    if (event.type === "user") {

    setState("thinking"); // 🟡 用户发消息 → 黄灯

    } else if (event.subtype === "turn_duration") {

    setState("done"); // 🟢 任务完成 → 绿灯

    }

}

// 3 秒无活动 → 自动切绿灯

if (idleFor(3000)) setState("idle");

}

这个方案的优势
✅ 完全不依赖 hooks,无需任何权限配置
✅ 500ms 轮询延迟几乎无感知
✅ Session JSONL 比 hooks 更可靠——它是 Claude Code 的核心日志

  📁 完整项目结构

E:\ccdeng\

├── arduino-led\ # Arduino 固件

│ └── led_indicator.ino

└── opencode-led\ # 电脑端

    ├── led-monitor.mjs # 🔑 文件监控脚本(核心)

    ├── start-monitor.bat # 启动脚本(双击即用)

    ├── claude-led-daemon-serial.mjs # HTTP daemon(备选)

    └── claude-led-hook.mjs # hooks 客户端(待修复后可用)

  🚀 三步跑起来

Step 1:烧录 Arduino

Shell

arduino-cli compile --fqbn arduino:avr:uno led_indicator/

arduino-cli upload -p COM5 --fqbn arduino:avr:uno led_indicator/

Step 2:安装电脑端依赖

Shell

cd E:\ccdeng\opencode-led

npm install

Step 3:启动监控

双击 start-monitor.bat,或者命令行:

Shell

node led-monitor.mjs

启动后,监控脚本自动检测 session 文件变化,LED 实时反映 Claude Code 的工作状态。不需要任何额外配置。

  📊 状态映射表

Claude Code 状态
💡 LED 表现
🔍 检测方式
用户发送消息
🟡 黄灯慢闪
session JSONL 出现 type:"user"
AI 思考 / 执行工具
🟡 黄灯慢闪
持续检测到文件活动
任务完成
🟢 绿灯常亮
出现 subtype:"turn_duration"
3 秒无活动
🟢 绿灯常亮
超时自动切换
需要权限 / 出错
🔴 红灯快闪
待实现(需普通 claude 模式)

  📝 踩坑总结(6 条血泪教训)

#
教训
1
Hooks 在非官方 API 后端不可用
最大天坑,耗时最久。/hooks 显示正常但从不触发
2
Arduino 串口复位
每次打开 COM5 触发 DTR → Arduino 重启 3 秒。必须用常驻进程独占串口
3
Windows 串口权限
Git Bash 下 arduino-cli upload 有问题,需用 avrdude 直接烧录
4
Git Bash 不兼容 .bat
Claude Code 用 Git Bash 执行 hooks,但 .bat/.cmd 行为不一致
5
500ms 轮询足够快
实际使用中几乎感觉不到延迟,完全没必要优化到更低
6
Session JSONL 是宝藏
记录了所有交互事件,比 hooks 更可靠、更完整

  🔮 后续优化方向

1支持权限请求检测 → 红灯提醒(需要用 claude 普通模式跳过 xiaocc 权限模式)

2添加声音提示(任务完成时「叮」一声 🎵)

3多项目同时运行时合并状态显示

43D 打印一个好看的外壳(告别「杜邦线裸奔」)

  📎 相关链接

项目
地址
本文源码(Arduino 固件 + 监控脚本)
E:\ccdeng\
参考:agent-light
github.com/eternityspring/agent-light
参考:opencode-led
github.com/mydubai7794/opencode-led

📝 写于 2026 年 6 月,一个调试 hooks 到凌晨的夜晚。如果你也在折腾 Claude Code 的硬件外设,欢迎交流。

如果这篇文章对你有帮助,欢迎 点赞、在看、转发 🙌