<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Yeelight on Bruce's 博客</title><link>https://www.huangqixuan.com/tags/yeelight/</link><description>Recent content in Yeelight on Bruce's 博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 21 Sep 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://www.huangqixuan.com/tags/yeelight/index.xml" rel="self" type="application/rss+xml"/><item><title>让 Codex 用灯光叫我回来（二）：从多会话分区到 Micro 原生状态</title><link>https://www.huangqixuan.com/p/codexlighthub-native-micro-part-2/</link><pubDate>Mon, 21 Sep 2026 00:00:00 +0800</pubDate><guid>https://www.huangqixuan.com/p/codexlighthub-native-micro-part-2/</guid><description>&lt;img src="https://www.huangqixuan.com/site-images/codexlighthub-native/cover_hu_eb280410d7c9c795.webp" alt="Featured image of post 让 Codex 用灯光叫我回来（二）：从多会话分区到 Micro 原生状态" /&gt;&lt;p&gt;在&lt;a class="link" href="https://www.huangqixuan.com/p/codexlighthub-windows-rgb/" &gt;上篇&lt;/a&gt;里，我已经让 ROG 键盘和 Yeelight 挂灯跟着 Codex 的状态变色：工作时蓝色，需要我回答时橙色，完成后绿色，过一会儿再回到平时的彩色灯效。&lt;/p&gt;&#10;&lt;p&gt;这个想法来自 Codex Micro 的指示灯。我希望不用一直盯着聊天窗口，也能知道任务有没有结束、是不是在等我。&lt;/p&gt;&#10;&lt;p&gt;但真正用起来以后，我又想加一点东西：如果同时开着两个、三个对话，能不能让键盘分别显示它们的状态？如果 Codex 本身就能给 Micro 发送状态，能不能不再依赖 hooks？&lt;/p&gt;&#10;&lt;p&gt;于是，我和 Codex 又折腾了几轮。最直观的变化是桌面版真的出现了 Micro 的欢迎向导；最费时间的部分，却发生在它已经显示“已连接”之后。&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;封面是 AI 生成的概念插画，用来表达状态与灯光的连接关系，不是实机照片，也不作为灯效测试证据。下文的软件截图来自我的实际测试。&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="一块键盘能不能看几个对话"&gt;&lt;a href="#%e4%b8%80%e5%9d%97%e9%94%ae%e7%9b%98%e8%83%bd%e4%b8%8d%e8%83%bd%e7%9c%8b%e5%87%a0%e4%b8%aa%e5%af%b9%e8%af%9d" class="header-anchor"&gt;&lt;/a&gt;一块键盘，能不能看几个对话？&#10;&lt;/h2&gt;&lt;p&gt;原来的整块变色很直接，不过只能给出一个汇总结果。我说的多个对话，包括主窗口里的任务，也包括 Codex 右侧打开的另一个对话。&lt;/p&gt;&#10;&lt;p&gt;最开始的想法很朴素：两个就左右分，三个就左中右，再多一些也可以继续分，但要有上限。每个区域显示一个任务的状态。&lt;/p&gt;&#10;&lt;p&gt;第一次测试时，颜色确实出来了，边界却不太对。后来按这台 G615LR 的实际键盘布局重新校准，去掉不适用的数字小键盘布局假设，三色分区才变得正常。空格这样的大键也需要单独考虑：一个物理按键只能显示一种颜色，不能因为它跨过两个区域，就把它当成两颗灯处理。&lt;/p&gt;&#10;&lt;p&gt;紧接着又遇到了一个问题：两个相邻任务都在工作，两个区域都是蓝色，看起来又连成了一片。&lt;/p&gt;&#10;&lt;p&gt;我们试过白色分隔键，也试过熄灯隔离带。我反馈过“三色正常，但同色区分隔不清”。后来我举了个例子：一个蓝区向左流动，另一个向上流动，会不会更容易区分？&lt;/p&gt;&#10;&lt;p&gt;这把问题从分区带到了动画。区域越多，每块越窄，灯光本身也越难读。能把颜色写进去，离“我扫一眼就能看懂”还有距离。&lt;/p&gt;&#10;&lt;h2 id="我想用官方动画结果发现要分开看"&gt;&lt;a href="#%e6%88%91%e6%83%b3%e7%94%a8%e5%ae%98%e6%96%b9%e5%8a%a8%e7%94%bb%e7%bb%93%e6%9e%9c%e5%8f%91%e7%8e%b0%e8%a6%81%e5%88%86%e5%bc%80%e7%9c%8b" class="header-anchor"&gt;&lt;/a&gt;我想用官方动画，结果发现要分开看&#10;&lt;/h2&gt;&lt;p&gt;流动效果做出来之后，我的感觉是卡。既然 G-Helper 的灯效看着很顺，能不能直接用它的方式？&lt;/p&gt;&#10;&lt;p&gt;这里需要把两种控制方式分开。&lt;/p&gt;&#10;&lt;p&gt;整块键盘的常亮、呼吸，可以给键盘发送模式命令，让设备自己运行效果。任意分区里的独立波浪，则需要更细的逐键控制。目前这条实现路径还没有验证出“每个任意分区都能独立调用固件波浪”的能力，所以不能把整板原生动画当成多区动画的现成替代。&lt;/p&gt;&#10;&lt;p&gt;软件逐帧发送也做过优化。一次短测里，旧逻辑的实际提交频率约为 6.20 次/秒，调整调度后约为 29.71 次/秒。不过这测到的是程序提交灯光数据的节奏，不是相机测出的 LED 刷新率，更不能代替我的肉眼反馈。&lt;/p&gt;&#10;&lt;p&gt;我后来更在意的是颜色是否清楚。任务提示不一定要一直动，尤其不能为了波浪把蓝色压得很暗。动画保留为探索方向，日常显示先回到容易辨认的常亮。&lt;/p&gt;&#10;&lt;h2 id="让桌面版真正认出-micro"&gt;&lt;a href="#%e8%ae%a9%e6%a1%8c%e9%9d%a2%e7%89%88%e7%9c%9f%e6%ad%a3%e8%ae%a4%e5%87%ba-micro" class="header-anchor"&gt;&lt;/a&gt;让桌面版真正认出 Micro&#10;&lt;/h2&gt;&lt;p&gt;接下来，我提出了另一个要求：“我不想用钩子做这个。”&lt;/p&gt;&#10;&lt;p&gt;上篇的路线是读取 hooks 事件，再由 Hub 判断状态。这次尝试的是在 Windows 上提供一个兼容 Micro 通信的虚拟 HID 设备，让 Codex 桌面版本身发送灯光状态，再把它转给实际的 ROG 键盘和 Yeelight。&lt;/p&gt;&#10;&lt;p&gt;大致路径是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Codex 桌面版&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ Micro 灯光状态&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;虚拟 HID 设备与本地桥接程序&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├→ ASUS HID → ROG 键盘&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └→ 本地 MIoT → Yeelight 氛围灯&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;起初 Windows 已经能看到设备，本地程序也能枚举到，Codex 却没有真正开始通信。继续检查后，发现还涉及桌面版筛选设备时使用的设备路径。调整虚拟设备的标识路径之后，欢迎向导终于弹了出来。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Codex Micro 欢迎向导" class="gallery-image" data-flex-basis="286px" data-flex-grow="119" height="671" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/welcome_hu_7c1b31f5be870dfb.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/welcome_hu_824c3eb2f9c6ad86.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/welcome_hu_7c1b31f5be870dfb.webp 801w" width="801"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;桌面版出现了 Micro 的欢迎向导。这里连接的是本项目的虚拟兼容设备，不代表我购买或接入了一台实体 Micro。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;这个时刻很有意思：最初只是受到它的指示灯启发，现在终于走到了桌面版原本为它准备的状态通道。&lt;/p&gt;&#10;&lt;p&gt;不过，“原生”这个词也容易把几件事混在一起。在这里，我说的是状态由 Codex 的 Micro 通道发出；接收和转译仍然靠本地桥接，键盘仍然是 ASUS 的设备。它不意味着 ROG 键盘变成了 Micro，也不意味着分区动画就由 ASUS 固件自动完成。&lt;/p&gt;&#10;&lt;p&gt;这条路线涉及虚拟驱动和本地证书信任，也不是拷贝一个脚本就结束的普通配置。我把它当作自己这台机器上的兼容性实验，而不是已经适合所有人安装的通用方案。&lt;/p&gt;&#10;&lt;h2 id="欢迎向导能打开不代表所有功能都实现了"&gt;&lt;a href="#%e6%ac%a2%e8%bf%8e%e5%90%91%e5%af%bc%e8%83%bd%e6%89%93%e5%bc%80%e4%b8%8d%e4%bb%a3%e8%a1%a8%e6%89%80%e6%9c%89%e5%8a%9f%e8%83%bd%e9%83%bd%e5%ae%9e%e7%8e%b0%e4%ba%86" class="header-anchor"&gt;&lt;/a&gt;欢迎向导能打开，不代表所有功能都实现了&#10;&lt;/h2&gt;&lt;p&gt;向导里的智能体按键很贴合我最初想要的体验：六个位置，各自显示状态。截图里的图例包括白色空闲、蓝色思考中、绿色已完成、琥珀色需要输入、红色错误，以及关闭表示未分配。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="智能体按键向导：六个位置与状态颜色" class="gallery-image" data-flex-basis="229px" data-flex-grow="95" height="809" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/agent-keys_hu_244d9aeb715078e1.webp" width="772"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="命令键向导：桌面版界面，不代表本项目已实现控制功能" class="gallery-image" data-flex-basis="203px" data-flex-grow="84" height="671" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/command-keys_hu_6f74d139eb3c0820.webp" width="569"&gt;&lt;/p&gt;&#10;&lt;p&gt;我目前接的是灯光状态。截图里介绍的命令键、旋钮、麦克风，以及点击按键切换任务，都不能因为欢迎向导出现了，就算成本项目的功能。桥接程序也不会替我点击批准按钮。&lt;/p&gt;&#10;&lt;p&gt;设置页同样需要这样看：它显示已连接，能看到亮度和自动调暗设置，是通信接入的证据。但虚拟设备报告的“电池 100%”只是兼容信息，不能当作笔记本电池读数。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Codex Micro 设置页" class="gallery-image" data-flex-basis="403px" data-flex-grow="168" height="1142" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/settings_hu_cd6690d4b9d471b.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/settings_hu_53561592dc4ea876.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/settings_hu_807abd437203f76e.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/settings_hu_cd6690d4b9d471b.webp 1920w" width="1920"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;测试时的设置页：亮度为 100%，自动调暗关闭。设置值正常，仍然不保证实际键盘颜色足够明显。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;还有一个限制：这条实现接收的是六个原生槽位的灯光状态，不是读取所有聊天内容、任务标题或者百分比进度。它不能无上限地把所有打开的对话铺到键盘上，也不能承诺槽位始终对应屏幕上从左到右的窗口位置。&lt;/p&gt;&#10;&lt;h2 id="接通之后我看到的却是一整块淡蓝白色"&gt;&lt;a href="#%e6%8e%a5%e9%80%9a%e4%b9%8b%e5%90%8e%e6%88%91%e7%9c%8b%e5%88%b0%e7%9a%84%e5%8d%b4%e6%98%af%e4%b8%80%e6%95%b4%e5%9d%97%e6%b7%a1%e8%93%9d%e7%99%bd%e8%89%b2" class="header-anchor"&gt;&lt;/a&gt;接通之后，我看到的却是一整块淡蓝白色&#10;&lt;/h2&gt;&lt;p&gt;接入成功之后，实际效果仍让我不满意。我先反馈“整块蓝”，后来又觉得颜色很淡，基本看不清，甚至像白色。&lt;/p&gt;&#10;&lt;p&gt;这次没有继续只看日志里的“发送成功”。我们做了一轮独立的硬件测试：先整块红色，再左蓝右橙，最后左红中绿右蓝。我确认这三种都看到了。&lt;/p&gt;&#10;&lt;p&gt;这至少说明键盘能显示明显的颜色，也能接受分区数据。但它只验证了输出路径，不能证明真实聊天状态已经显示正确。接下来还得把状态选择、颜色映射和显示方式一起检查。&lt;/p&gt;&#10;&lt;p&gt;此前的显示会把原生槽位里的白色空闲状态也带进键盘，加上浅冰蓝和亮度变化，视觉上很容易变成一片偏白的光。后来的日常策略改得更直接：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;白色和关闭的槽位不再挤占键盘上的活动区域。&lt;/li&gt;&#10;&lt;li&gt;只有一个有色状态时，用整块键盘显示。&lt;/li&gt;&#10;&lt;li&gt;多个有色状态时，再做分区。&lt;/li&gt;&#10;&lt;li&gt;工作蓝改成更饱和的蓝色，RGB 为 &lt;code&gt;35, 105, 255&lt;/code&gt;，先用常亮保证可见。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;原始槽位数据仍然保留，改变的是呈现方式。至于相邻同色区域，目前还不能说已经完美解决，尤其不能把两区、三区通过测试，推成所有分区数量都清楚可读。&lt;/p&gt;&#10;&lt;p&gt;后来我又提了一个更直接的改法：把分界处的一条按键都点亮，不要只在顶部放一个白色标记。调整后的实拍里，两个相邻绿区之间已经出现了纵向白色分隔键。键盘每一排的位置有错位，大键也不能切开，所以它是一串沿边界排列的亮键，不是一条连续的灯带。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="最新分区实拍：相邻绿区之间的纵向白色分隔键" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1279" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/white-boundary-latest_hu_b8ec19d1a1186e9a.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/white-boundary-latest_hu_654e775846e468d7.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/white-boundary-latest_hu_21a945b9b82ba7c3.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/white-boundary-latest_hu_b8ec19d1a1186e9a.webp 1706w" width="1706"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;最新原图：左侧蓝色，中部与右侧绿色，白色按键标出两个相邻绿区的边界。这次改动后的代码测试为 110 项通过，照片记录实际显示效果。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;写这篇时，我又拍了两张新版分区的效果。第一张能看到左右蓝色、中间绿色；第二张多了一块黄橙色，从左到右是蓝、黄橙、绿、蓝。和之前那种整块偏白的观感相比，这两张照片里已经能直接辨认出不同的颜色区域。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="蓝绿双区：左侧蓝色，右侧绿色" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1279" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green_hu_f5c344f3af53b35f.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green_hu_6f679957f32f6540.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green_hu_a9cb9dfc49b4ac68.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green_hu_f5c344f3af53b35f.webp 1706w" width="1706"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="三块区域：中间绿色，两侧蓝色" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1280" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green-blue_hu_3c8efa2fc545db31.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green-blue_hu_99a69dfd4df8827c.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green-blue_hu_3d43cbe3105e1848.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-blue-green-blue_hu_3c8efa2fc545db31.webp 1707w" width="1707"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="新版分区实拍：蓝、黄橙、绿、蓝" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1280" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-four-colors_hu_542aeedf63428255.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-four-colors_hu_393543bff41e51ca.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-four-colors_hu_adb95f6023b584f7.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-four-colors_hu_542aeedf63428255.webp 1707w" width="1707"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;新版分区实拍之二：四块区域同时显示。照片里的黄橙色会受拍摄曝光和白平衡影响；两张静态照片只记录颜色与空间分区，不证明动画帧率，也不单独证明每个区域的任务对应关系。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;真正询问时也单独试过。我在一次真实询问里确认键盘和挂灯都变成了橙色。这个反馈比手动发送一个橙色测试命令更有意义，因为它走的是实际交互链路。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="黄橙色与蓝色分区近照" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1280" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-amber-blue_hu_df2e7fbadbb89057.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/zones-amber-blue_hu_69bfe536f407bd13.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-amber-blue_hu_94c7774ad4742815.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/zones-amber-blue_hu_df2e7fbadbb89057.webp 1707w" width="1707"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;另一组分区近照：左侧黄橙色，右侧蓝色。不同状态可以同时留在键盘上。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="询问窗口、键盘分区和 Yeelight 挂灯同框" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1280" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/real-question-desk_hu_31a8945687873a73.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/real-question-desk_hu_f3914854491d330.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/real-question-desk_hu_4a76a6125b5ca1f1.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub-native/real-question-desk_hu_31a8945687873a73.webp 1707w" width="1707"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;这张全景把询问窗口、键盘上的黄橙色区域和挂灯两端的橙光拍在了一起。比起只看设置页，我更想保留这种实际使用时的画面。&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="完成以后我还是想回到原来的彩色"&gt;&lt;a href="#%e5%ae%8c%e6%88%90%e4%bb%a5%e5%90%8e%e6%88%91%e8%bf%98%e6%98%af%e6%83%b3%e5%9b%9e%e5%88%b0%e5%8e%9f%e6%9d%a5%e7%9a%84%e5%bd%a9%e8%89%b2" class="header-anchor"&gt;&lt;/a&gt;完成以后，我还是想回到原来的彩色&#10;&lt;/h2&gt;&lt;p&gt;另一个让我直接要求改回去的地方，是任务结束后的灯。&lt;/p&gt;&#10;&lt;p&gt;我问：“运作完的灯为什么关了，还是和以前一样比较好。”&lt;/p&gt;&#10;&lt;p&gt;如果把原生槽位的关闭状态直接照搬到整个桌面，任务结束可能就把灯关掉了。但我平时用的就是彩色灯效，希望任务提示只是暂时覆盖它，而不是接管之后再把它熄灭。&lt;/p&gt;&#10;&lt;p&gt;后来的修正恢复了本地的完成保持：收到绿色完成状态后，保持三分钟，再恢复平时的灯效。键盘恢复 G-Helper 保存的灯效，Yeelight 恢复配置的空闲灯效。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="平时的彩虹灯效实拍" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1350" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub/idle-rainbow_hu_fd591344525db735.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub/idle-rainbow_hu_acde748662294c16.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub/idle-rainbow_hu_7fe519b2d72f8cd2.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub/idle-rainbow_hu_fd591344525db735.webp 1800w" width="1800"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;沿用上篇的彩虹灯效实拍，展示我想保留的日常效果，不单独证明三分钟倒计时与自动恢复的全过程。&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;这三分钟也不能挡住新任务。同一位置如果又变成蓝色、橙色或红色，就立即显示新状态；重复收到同一轮绿色不会不断延长倒计时。保持期间收到白色或关闭，也不应立刻把完成提示切掉。&lt;/p&gt;&#10;&lt;p&gt;这里还有一个边界：如果根本没有收到绿色，只是从蓝色变成关闭，就不能擅自判断“任务完成了”，再编出一段绿色提示。&lt;/p&gt;&#10;&lt;p&gt;这一轮修改后的本地测试记录是 109 项通过。它验证了程序行为，但截至这篇记录，我还没有把完整三分钟的双设备实机保持、恢复过程当作已经验收的结果。长时间使用、重启后的恢复，以及多个真实任务同时变化，仍然需要继续观察。&lt;/p&gt;&#10;&lt;h2 id="我现在更想要一盏看得懂的灯"&gt;&lt;a href="#%e6%88%91%e7%8e%b0%e5%9c%a8%e6%9b%b4%e6%83%b3%e8%a6%81%e4%b8%80%e7%9b%8f%e7%9c%8b%e5%be%97%e6%87%82%e7%9a%84%e7%81%af" class="header-anchor"&gt;&lt;/a&gt;我现在更想要一盏看得懂的灯&#10;&lt;/h2&gt;&lt;p&gt;这一轮从分区开始，绕到了逐帧动画、虚拟 HID 和 Micro 状态，最后又回到了很简单的要求：蓝色得看得清，需要我回答时要提醒，完成后别马上消失，也别把我原来的灯效弄没了。&lt;/p&gt;&#10;&lt;p&gt;Micro 给我的启发一直没有变。我喜欢的是把任务状态放到视线边缘，不用频繁切回聊天窗口。至于是不是每个区域都在滚动、有没有复制出向导里的全部功能，反而没那么着急。&lt;/p&gt;&#10;&lt;p&gt;目前的版本已经能继续沿着原生状态接入这条路走，也保留了后续校准和回退的余地。我会先让它在自己的桌面上稳定工作，再决定哪些效果值得留下。&lt;/p&gt;&#10;&lt;p&gt;毕竟我想要的是它在需要的时候叫我回来，而不是让我一直盯着灯，猜它现在到底是什么意思。&lt;/p&gt;&#10;&lt;h2 id="留两张整理后的桌面照片"&gt;&lt;a href="#%e7%95%99%e4%b8%a4%e5%bc%a0%e6%95%b4%e7%90%86%e5%90%8e%e7%9a%84%e6%a1%8c%e9%9d%a2%e7%85%a7%e7%89%87" class="header-anchor"&gt;&lt;/a&gt;留两张整理后的桌面照片&#10;&lt;/h2&gt;&lt;p&gt;最后，我也给两张照片做了 AI 美化，整理曝光和背景，留作这篇的视觉记录。前面的原图仍然保留。美化版可能重绘按键字符、屏幕文字和局部细节，不用于核对按键映射、灯光亮度或软件界面。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="四色分区近照 · AI 美化版，非测试证据" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1086" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/keyboard-retouched_hu_e2bcb3c44a66a163.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/keyboard-retouched_hu_2e089d98af871631.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/keyboard-retouched_hu_e2bcb3c44a66a163.webp 1448w" width="1448"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="桌面全景 · AI 美化版，非测试证据" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1086" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub-native/desk-retouched_hu_6f057248d34de892.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub-native/desk-retouched_hu_9c9ee236db8e02ac.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub-native/desk-retouched_hu_6f057248d34de892.webp 1448w" width="1448"&gt;&lt;/p&gt;&#10;</description></item><item><title>让 Codex 用灯光叫我回来：CodexLightHub 的 ROG 与 Yeelight 实机记录</title><link>https://www.huangqixuan.com/p/codexlighthub-windows-rgb/</link><pubDate>Tue, 08 Sep 2026 00:00:00 +0800</pubDate><guid>https://www.huangqixuan.com/p/codexlighthub-windows-rgb/</guid><description>&lt;img src="https://www.huangqixuan.com/site-images/codexlighthub/cover_hu_a0f28dc5a066aea9.webp" alt="Featured image of post 让 Codex 用灯光叫我回来：CodexLightHub 的 ROG 与 Yeelight 实机记录" /&gt;&lt;p&gt;Codex 在后台跑任务时，我不想一直盯着窗口。更需要提醒我的时刻，是它已经停下来，等我回答一个问题。既然桌上已经有 RGB 键盘和挂灯，能不能让这些灯直接表示任务状态？&lt;/p&gt;&#10;&lt;p&gt;这个想法来自 Codex Micro 的状态指示灯。它用颜色告诉我 Codex 正在工作、等待输入还是已经完成，我也想让整张桌面有同样直观的反馈。最后做出来的 CodexLightHub，是一个运行在 Windows 上的 Python 小程序。它接收 Codex 的生命周期事件，再把状态发给 ROG 笔记本灯光和 Yeelight 挂灯的后方氛围灯。&lt;/p&gt;&#10;&lt;p&gt;这篇记录整理到 &lt;code&gt;1.0.6&lt;/code&gt;。ASUS 和 Yeelight 两条链路已经接通，EZ80 仍停在只读探测阶段。本文中的灯光照片均来自实际运行效果，连接图只用于解释程序结构。&lt;/p&gt;&#10;&lt;h2 id="先确定灯光应该告诉我什么"&gt;&lt;a href="#%e5%85%88%e7%a1%ae%e5%ae%9a%e7%81%af%e5%85%89%e5%ba%94%e8%af%a5%e5%91%8a%e8%af%89%e6%88%91%e4%bb%80%e4%b9%88" class="header-anchor"&gt;&lt;/a&gt;先确定灯光应该告诉我什么&#10;&lt;/h2&gt;&lt;p&gt;最早的设想很直接：工作时蓝色，需要我时橙色，完成时绿色。真正用起来以后，才发现颜色背后的判断比变色本身更难。&lt;/p&gt;&#10;&lt;p&gt;例如，Codex 发起权限检查时，可能由自动审核处理，根本没有弹窗让我操作。如果每次都变橙色，我就会不断被叫回来，最后开始忽略它。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;1.0.6&lt;/code&gt; 把规则收紧到了下面这样：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;状态&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;当前行为&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;工作中&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;满亮蓝色；ROG 使用硬件呼吸形成动态起伏，Yeelight 保持静态蓝色&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;真实询问&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;request_user_input&lt;/code&gt; 调用前变成满亮橙色，回答后恢复蓝色&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;自动审核或后台权限检查&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;保持蓝色，不触发橙色提醒&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;本轮完成&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;满亮绿色保持 180 秒，再恢复日常彩色灯效&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;收到中断事件&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;满亮红色短暂提示，默认保持 4 秒&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;空闲&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;ASUS 恢复 G-Helper 保存的灯效；Yeelight 按配置恢复彩虹&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="article-photo-grid"&gt;&lt;figure&gt;&#10; &lt;img src="https://www.huangqixuan.com/img/codexlighthub/working-blue.webp" alt="蓝色：Codex 正在工作" loading="lazy" decoding="async"&gt;&#10; &lt;figcaption&gt;蓝色：Codex 正在工作&lt;/figcaption&gt;&#10; &lt;/figure&gt;&lt;figure&gt;&#10; &lt;img src="https://www.huangqixuan.com/img/codexlighthub/waiting-orange.webp" alt="橙色：等待我回答问题" loading="lazy" decoding="async"&gt;&#10; &lt;figcaption&gt;橙色：等待我回答问题&lt;/figcaption&gt;&#10; &lt;/figure&gt;&lt;figure&gt;&#10; &lt;img src="https://www.huangqixuan.com/img/codexlighthub/completed-green.webp" alt="绿色：这一轮已经完成" loading="lazy" decoding="async"&gt;&#10; &lt;figcaption&gt;绿色：这一轮已经完成&lt;/figcaption&gt;&#10; &lt;/figure&gt;&lt;figure&gt;&#10; &lt;img src="https://www.huangqixuan.com/img/codexlighthub/idle-rainbow.webp" alt="彩色：恢复平时的桌面灯效" loading="lazy" decoding="async"&gt;&#10; &lt;figcaption&gt;彩色：恢复平时的桌面灯效&lt;/figcaption&gt;&#10; &lt;/figure&gt;&lt;/div&gt;&#10;&#10;&lt;p&gt;这里的“完成”指当前一轮结束，不代表整个项目已经做完。红色也不能覆盖所有错误：当前安装器没有注册通用错误事件，Hub 只是保留了 &lt;code&gt;Interrupt&lt;/code&gt; 的处理入口。&lt;/p&gt;&#10;&lt;p&gt;还有一个限制要单独说清楚。项目默认启用了 &lt;code&gt;plan_stop_is_waiting&lt;/code&gt;，当收到带有 &lt;code&gt;permission_mode=plan&lt;/code&gt; 的 &lt;code&gt;Stop&lt;/code&gt; 时，会保守地显示等待状态。它是为部分计划确认界面补的启发式判断，不能证明屏幕上一定有弹窗。普通询问使用的是实际工具事件，这两条路径不能混为一谈。&lt;/p&gt;&#10;&lt;h2 id="一条很短的事件链"&gt;&lt;a href="#%e4%b8%80%e6%9d%a1%e5%be%88%e7%9f%ad%e7%9a%84%e4%ba%8b%e4%bb%b6%e9%93%be" class="header-anchor"&gt;&lt;/a&gt;一条很短的事件链&#10;&lt;/h2&gt;&lt;p&gt;程序分成三层：Hook 接事件，Hub 判断状态，Adapter 控灯。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="CodexLightHub 的事件、状态机和双设备输出示意" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub/cover.svg"&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Codex lifecycle hooks&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;codex-light-hook.cmd → hook.py&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ UDP 127.0.0.1:17871&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Hub：按会话保存状态、去重、决定当前灯色&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── ASUS HID → ROG 键盘与机身灯光&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── 本地 MIoT → Yeelight 后方氛围灯&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;hook.py&lt;/code&gt; 只挑出事件名、会话、轮次、工具名等少量字段，发送到本机回环地址后退出。提示词、工具参数、工具输出、回复正文和工作目录都不在转发白名单里。灯光程序也不输出允许或拒绝权限的决定。&lt;/p&gt;&#10;&lt;p&gt;硬件写入在 Hub 的工作线程里执行。挂灯连接慢了，或某个设备不可用，不应该让 Codex 的 Hook 一直等着。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Codex Desktop、ROG 键盘和 Yeelight 挂灯联动的桌面实拍" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1350" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub/desktop-overview_hu_4bafa2bc26838238.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub/desktop-overview_hu_b720b52f4ea1c3c8.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub/desktop-overview_hu_bc99cec487176054.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub/desktop-overview_hu_4bafa2bc26838238.webp 1800w" width="1800"&gt;&lt;/p&gt;&#10;&lt;p&gt;同一时间开多个任务时，Hub 按下面的顺序选择灯色：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;waiting &amp;gt; running &amp;gt; interrupted &amp;gt; completed &amp;gt; idle&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因此，一个任务完成不会用绿色盖住另一个任务的橙色询问；只要还有任务在运行，整体也会优先显示蓝色。这意味着绿色的 3 分钟计时到了，不一定马上看到彩虹，还要看其他会话是否仍然活跃。&lt;/p&gt;&#10;&lt;h2 id="rog从没有设备的-rest-接口走到-asus-hid"&gt;&lt;a href="#rog%e4%bb%8e%e6%b2%a1%e6%9c%89%e8%ae%be%e5%a4%87%e7%9a%84-rest-%e6%8e%a5%e5%8f%a3%e8%b5%b0%e5%88%b0-asus-hid" class="header-anchor"&gt;&lt;/a&gt;ROG：从没有设备的 REST 接口，走到 ASUS HID&#10;&lt;/h2&gt;&lt;p&gt;这次使用的笔记本是 ROG Strix G16 G615LR，灯光由 G-Helper 0.279.0 管理。&lt;/p&gt;&#10;&lt;p&gt;最初的 Aura REST 探测没有枚举到设备，返回值是 &lt;code&gt;5&lt;/code&gt;。我们随后试过 Windows Dynamic Lighting，又遇到了 PyWinRT 枚举接口的参数问题。但确认平时由 G-Helper 控灯后，主线就转向了它使用的 ASUS HID 通道。&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://github.com/seerge/g-helper" target="_blank" rel="noopener"&#10; &gt;G-Helper 的公开源码&lt;/a&gt;提供了实际设备控制实现。项目据此整理协议，再结合本机 G-Helper 日志确认目标设备，而不是只看到 ASUS 的厂商编号就发送数据。&lt;/p&gt;&#10;&lt;p&gt;本机核对到的参数是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;VID: 0B05&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PID: 19B6&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Aura collection: col04&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Report length: 64 bytes&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;桥接层会同时检查 PID 白名单、配置中的允许列表、日志里的完整 HID 路径、报告长度和 Aura Probe 结果。检查不通过时，拒绝写入。&lt;/p&gt;&#10;&lt;p&gt;灯效写入沿用了三段报告的顺序：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5D-B3-00-{mode}-{R}-{G}-{B}-{speed}-...&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5D-B5-00-00-00&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5D-B4&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面是协议结构说明，不是可以直接复制发送的完整数据包。它也不代表所有 ASUS 设备都适用。当前配置默认只允许这次验证过的 &lt;code&gt;19B6&lt;/code&gt;，换型号后应重新探测。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;GHelperAuraBridge.py&lt;/code&gt; 提供 &lt;code&gt;blue&lt;/code&gt;、&lt;code&gt;waiting&lt;/code&gt;、&lt;code&gt;complete&lt;/code&gt;、&lt;code&gt;error&lt;/code&gt; 和 &lt;code&gt;restore&lt;/code&gt; 命令。ASUS 的运行、等待和错误效果使用硬件呼吸模式，不需要 Python 持续计算每一帧亮度。四种任务状态都按 100% 亮度发送。&lt;/p&gt;&#10;&lt;p&gt;恢复灯效时，程序读取 G-Helper 保存的 &lt;code&gt;aura_mode&lt;/code&gt;、&lt;code&gt;aura_color&lt;/code&gt; 和 &lt;code&gt;aura_speed&lt;/code&gt;，再发送对应模式。它不会修改 G-Helper 的配置。这恢复的是保存的日常设置，并不是对接管前任意瞬时灯光状态的完整快照。&lt;/p&gt;&#10;&lt;h2 id="yeelight55443-不通仍然可以走本地-miot"&gt;&lt;a href="#yeelight55443-%e4%b8%8d%e9%80%9a%e4%bb%8d%e7%84%b6%e5%8f%af%e4%bb%a5%e8%b5%b0%e6%9c%ac%e5%9c%b0-miot" class="header-anchor"&gt;&lt;/a&gt;Yeelight：55443 不通，仍然可以走本地 MIoT&#10;&lt;/h2&gt;&lt;p&gt;挂灯是 Yeelight 显示器挂灯 2 Pro，设备型号为 &lt;code&gt;yeelink.light.lamp42&lt;/code&gt;。这里控制的是背后的氛围灯。&lt;/p&gt;&#10;&lt;p&gt;最容易绕进去的地方，是把“Yeelight 设备”与“开放传统 Yeelight LAN Control”画上等号。本机测试中，传统局域网控制端口 &lt;code&gt;55443&lt;/code&gt; 没有开放。这只能说明那条路径没有跑通，不能据此判定设备没有其他本地接口。&lt;/p&gt;&#10;&lt;p&gt;另一个障碍是登录。早期 &lt;code&gt;python-miio/micloud&lt;/code&gt; 的密码登录在这次环境中失败，后面改用了 &lt;a class="link" href="https://pypi.org/project/mihome-ctl/" target="_blank" rel="noopener"&#10; &gt;mihome-ctl&lt;/a&gt; 的米家扫码登录，取得设备的本地 IP 和 Token。这个工具用于完成设备信息获取；日常灯色切换由 CodexLightHub 的本地 MIoT 后端处理。&lt;/p&gt;&#10;&lt;p&gt;所以最终链路是：扫码取得凭据，然后通过本地 MIoT 控灯。它不需要每变一次颜色就重新扫码，也没有把米家账号密码写进 Hub。&lt;/p&gt;&#10;&lt;p&gt;在这盏灯上，氛围灯属性已经按下面的映射完成实机验证：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;属性&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;SIID / PIID&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;开关&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3 / 1&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;亮度&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3 / 2&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;RGB 颜色&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3 / 3&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;模式&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3 / 4&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;颜色按 RGB 转成十进制值：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;正常变色时，后端依次写入静态模式、颜色、亮度和开关。恢复日常灯效时则把模式放到最后写，因为写颜色可能让设备回到静态模式。此次验证中，最后写入 &lt;code&gt;mode=1&lt;/code&gt; 可以恢复彩虹。&lt;/p&gt;&#10;&lt;p&gt;这里还有一个设备差异：ASUS 的蓝色运行和橙色等待灯效使用硬件呼吸，当前 Yeelight 后端则显示对应颜色的满亮静态灯效。两者表示同一个状态，动画并不完全一致。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Codex 完成后，Yeelight 挂灯显示绿色状态" class="gallery-image" data-flex-basis="320px" data-flex-grow="133" height="1350" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://www.huangqixuan.com/site-images/codexlighthub/yeelight-completed_hu_54f0cb2063c59573.webp" srcset="https://www.huangqixuan.com/site-images/codexlighthub/yeelight-completed_hu_d3664758feb739e.webp 800w, https://www.huangqixuan.com/site-images/codexlighthub/yeelight-completed_hu_5904de5a83dce505.webp 1600w, https://www.huangqixuan.com/site-images/codexlighthub/yeelight-completed_hu_54f0cb2063c59573.webp 1800w" width="1800"&gt;&lt;/p&gt;&#10;&lt;p&gt;Token 是设备控制密钥，只放在本地配置。文章没有附设备地址、Token、登录二维码或账号信息；如果分享工程，应使用 &lt;code&gt;config.example.json&lt;/code&gt;，不能打包自己的运行配置。&lt;/p&gt;&#10;&lt;h2 id="真正费时间的是状态细节"&gt;&lt;a href="#%e7%9c%9f%e6%ad%a3%e8%b4%b9%e6%97%b6%e9%97%b4%e7%9a%84%e6%98%af%e7%8a%b6%e6%80%81%e7%bb%86%e8%8a%82" class="header-anchor"&gt;&lt;/a&gt;真正费时间的是状态细节&#10;&lt;/h2&gt;&lt;h3 id="hook-显示完成不等于灯光脚本执行了"&gt;&lt;a href="#hook-%e6%98%be%e7%a4%ba%e5%ae%8c%e6%88%90%e4%b8%8d%e7%ad%89%e4%ba%8e%e7%81%af%e5%85%89%e8%84%9a%e6%9c%ac%e6%89%a7%e8%a1%8c%e4%ba%86" class="header-anchor"&gt;&lt;/a&gt;Hook 显示完成，不等于灯光脚本执行了&#10;&lt;/h3&gt;&lt;p&gt;Windows 包装命令曾是一个排查点。项目最后用 &lt;code&gt;.cmd&lt;/code&gt; 包装器承接 Python 调用，避免在 Hook 字符串里反复嵌套引号。&lt;/p&gt;&#10;&lt;p&gt;安装器会备份并合并已有的 &lt;code&gt;hooks.json&lt;/code&gt;，保留不属于本项目的处理器。最终版本还移除了本项目之前注册的 &lt;code&gt;PermissionRequest&lt;/code&gt; 处理器，让自动审核不再触发橙色。&lt;/p&gt;&#10;&lt;p&gt;这套安装方式是在本机路径和 Codex 版本下跑通的。包装命令依赖路径格式，迁移到包含空格的用户目录时仍应检查，不能把一次成功当成所有 Windows 环境的保证。&lt;/p&gt;&#10;&lt;h3 id="已完成和我已经看过不是一回事"&gt;&lt;a href="#%e5%b7%b2%e5%ae%8c%e6%88%90%e5%92%8c%e6%88%91%e5%b7%b2%e7%bb%8f%e7%9c%8b%e8%bf%87%e4%b8%8d%e6%98%af%e4%b8%80%e5%9b%9e%e4%ba%8b" class="header-anchor"&gt;&lt;/a&gt;“已完成”和“我已经看过”不是一回事&#10;&lt;/h3&gt;&lt;p&gt;开发中一度参考 Codex Micro 的“完成且未读”思路，让绿色一直保持到下一次交互。用了一下，我又把需求改成了“过几分钟切回彩色”。&lt;/p&gt;&#10;&lt;p&gt;最后的配置是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;completed_hold_seconds&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sticky_completed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;新提示提交后立即回到蓝色，不必等计时结束。Hub 虽然保留了 &lt;code&gt;MarkRead&lt;/code&gt; 和 &lt;code&gt;Read&lt;/code&gt; 入口，但当前接入没有收到“用户已阅读回复”的事件，不能根据绿色是否消失判断我有没有看过结果。&lt;/p&gt;&#10;&lt;h3 id="橙色必须值得我回来"&gt;&lt;a href="#%e6%a9%99%e8%89%b2%e5%bf%85%e9%a1%bb%e5%80%bc%e5%be%97%e6%88%91%e5%9b%9e%e6%9d%a5" class="header-anchor"&gt;&lt;/a&gt;橙色必须值得我回来&#10;&lt;/h3&gt;&lt;p&gt;最后一次调整是把手工变橙色测试改成真正的询问弹窗测试。&lt;/p&gt;&#10;&lt;p&gt;先手工写入橙色，只能证明设备能接收颜色。真正调用 &lt;code&gt;request_user_input&lt;/code&gt;、出现问题、回答后恢复蓝色，才能检查从 Codex 到设备的整条链路。开发记录里最终确认了“弹窗且橙色”，随后完成 &lt;code&gt;1.0.6&lt;/code&gt;。&lt;/p&gt;&#10;&lt;p&gt;Hub 还处理了一个并行工具细节：已经在等我回答时，另一个工具先结束，不应把等待状态提前冲掉。只有匹配的询问结束，才应该回到运行状态。&lt;/p&gt;&#10;&lt;h2 id="目前完成到哪里"&gt;&lt;a href="#%e7%9b%ae%e5%89%8d%e5%ae%8c%e6%88%90%e5%88%b0%e5%93%aa%e9%87%8c" class="header-anchor"&gt;&lt;/a&gt;目前完成到哪里&#10;&lt;/h2&gt;&lt;p&gt;截至这次记录，已经完成 ASUS HID 写入、Yeelight 本地 MIoT 写入、双设备接入同一状态机、真实询问提醒，以及完成 3 分钟后的彩色恢复。最终开发记录报告 11 项自动测试通过，代码中的测试覆盖了状态变化、HID 构造与保护条件、MIoT 属性写入等部分。自动测试与实机变色是两类证据，不能互相替代。&lt;/p&gt;&#10;&lt;p&gt;EZ80 暂时只有只读 HID 探测器，没有写入灯光协议。当前项目也没有实现逐键显示多个任务、按某个键跳回会话，或者识别所有客户端弹窗。这些早期讨论过的想法，没有被写成已经完成的功能。&lt;/p&gt;&#10;&lt;p&gt;工程仍是围绕这台 G615LR 和这盏 lamp42 做的个人工具。设备断开、网络超时、G-Helper 与其他灯光控制器竞争，以及不同 Codex 版本的事件差异，都是后续使用时需要观察的地方。&lt;/p&gt;&#10;&lt;p&gt;对我来说，最有用的结果是：起伏的蓝色让我知道它还在工作，橙色提示有问题要回答，绿色短暂保留完成状态，然后桌面回到原来的彩色。这个小工具的价值，取决于这些提醒能不能对应真实情况。&lt;/p&gt;&#10;</description></item></channel></rss>