通过 USB HID 直接读取绿联 UGREEN US3000 UPS 遥测数据的 Go 程序。纯 Go 实现,零第三方依赖、无需 cgo、无需安装任何驱动或厂商软件。
设备标识:VID:2B89 PID:FFFF,固件 V3.3(对外报告版本 1.00)。
# 终端实时面板(默认,每秒刷新)
ups-monitor.exe
# 启动 Web 仪表盘并自动打开浏览器
ups-monitor.exe -web :8080
# 读取一次并以 JSON 输出(便于脚本集成)
ups-monitor.exe -once -json
# 列出系统中所有 HID 设备(排查连接问题时使用)
ups-monitor.exe -list若控制台中文显示异常,程序已自动切换到 UTF-8 代码页;如仍异常可手动执行
chcp 65001。
终端实时面板
| 市电供电 | 电池供电 |
|---|---|
Web 仪表盘
| 市电供电 | 电池供电 |
|---|---|
| 参数 | 默认值 | 说明 |
|---|---|---|
-web <addr> |
无 | 启动 Web 仪表盘,如 -web :8080;启动后自动打开浏览器 |
-once |
false | 只读取一帧即退出 |
-json |
false | 以 JSON 格式输出(配合 -once 或持续输出) |
-list |
false | 枚举系统中所有 HID 接口及其 UsagePage |
-csv <file> |
无 | 同时将每帧数据追加写入 CSV 文件 |
-raw |
false | 额外输出原始帧的十六进制 |
-i <ms> |
1000 | 采样间隔(毫秒) |
-no-browser |
false | Web 模式下不自动打开浏览器 |
-low <n> |
0 | 电量低于该百分比时自动执行电源动作(0=关闭,范围 1–100) |
-action <a> |
shutdown | 低电量动作:shutdown(关机) / sleep(睡眠) / hibernate(休眠) |
状态 市电供电 · 电池已充满 (OL)
输入电压 12.318 V 输入电流 1.112 A
输入功率 13.70 W 负载 0 %
电池电压 16.536 V 电量 100 %
电芯电压 4.086 / 4.108 / 4.100 / 4.107 V(压差 22 mV)
预计续航 约 3 小时(按 43 Wh 容量与当前功率估算)
US3000 不是传统的交流 UPS。其输入为外置电源适配器的直流电(12V/19V/20V),输出为 12V 直流,用于给 NAS、路由器等设备供电。因此:
- 表中出现的电压是 直流电压,不应按 220V 市电理解;
- 电池组为 4 节锂离子电芯串联(4S),满电约 16.4–16.6V;
- 标称容量 43 Wh(3000 mAh × 14.4V)。官方宣传的 "12000 mAh" 是四节电芯容量之和,不能直接用于能量计算。
设备通过 USB 暴露两个 HID 集合(Top-Level Collection):
| 接口 | UsagePage | 用途 |
|---|---|---|
| COL01 | 0xFF00 |
绿联私有遥测,Report ID 0x71,64 字节,每秒主动上报 — 本程序的主要数据源 |
| COL02 | 0x0084 |
标准 HID Power Device,被 Windows 电池驱动占用;仅用于 Feature 报告交叉校验 SOC |
Windows 会将 COL02 识别为"HID UPS 电池",这是正常现象。本程序读取 COL01 获取完整遥测,避免了与系统驱动的冲突。
私有帧为 64 字节,偏移均包含开头的 Report ID(即 data[0] == 0x71)。
| 值 | 含义 |
|---|---|
0x26 |
市电供电,电池已充满(OL) |
0x36 |
市电供电,电池充电中(OL CHRG) |
0x21 |
电池供电,市电中断(OB) |
| 偏移 | 解码 | 含义 |
|---|---|---|
[16-17] |
BE u16 | OL:直流输入电压(V,÷1000);OB:剩余运行时间(秒) |
[18-19] |
BE u16 ÷1000 | OL:直流输入电压(V);OB:稳压输出电压(V) |
[22-23] |
BE u16 ÷1000 | 电池组总电压(V) |
[24-25] |
BE u16 ÷1000 | OL:输入电流(A);OB:电池放电电流(A) |
[29-30] |
BE u16 | 充电电流(mA),仅在 OL CHRG 有效 |
[35-36] [37-38] [39-40] [41-42] |
BE u16 ÷1000 | 第 1–4 节电芯电压(V) |
[43] |
原始字节 | 电池电量百分比 |
[30] / [31] |
原始字节 | 负载百分比(OL 取 [30],OB 取 [31]) |
[16-17]与[18-19]是两个不同的电压测量点,实测相差约 70–100 mV,属正常现象。
| 报告 ID | 内容 |
|---|---|
0x06 [1] |
BMS 上报的 SOC(%),用于校准 [43] |
0x06 [2-5] |
LE u32 剩余秒数,0xFFFFFFFF 表示市电正常时不可用 |
0x01 |
PresentStatus 位域,bit 7 为 NeedReplacement(需更换电池) |
[20-21]、[28]、[32]、[45]、[46] 含义未确认,程序不予展示。其中 [28] 呈约 15 分钟周期震荡,推测与充电器状态机相关,而非温度。
ugreen-ups/
├── cmd/ups/ 主程序
│ ├── main.go 入口、终端面板、JSON 输出
│ ├── web.go HTTP 服务与采集器
│ └── assets/
│ └── dashboard.html Web 仪表盘(内嵌,无外部 CDN 依赖)
├── hid/ Windows HID 驱动(纯 syscall,无 cgo)
│ └── hid.go setupapi / hid.dll / kernel32 封装
├── protocol/ 协议解析
│ └── protocol.go 64 字节帧解码
├── probe/ 诊断工具:枚举设备、读取用法能力与原始报告
├── sample/ 诊断工具:长时采样并统计逐字节变化
└── ups-monitor.exe 编译产物
环境未安装 C 编译器(CGO_ENABLED=0),主流 HID 库(如 karalabe/hid、go-hid)依赖 cgo/hidapi 无法编译。因此 hid 包直接通过 syscall 调用 Windows 原生 API:
setupapi.dll:设备枚举与接口路径获取hid.dll:属性、报告描述符、用法能力、Feature 报告kernel32.dll:CreateFileW+ OverlappedReadFile(带超时)
该实现同时规避了 Linux hidraw 方案在 Windows 上的不适用性。
若后续固件升级导致协议变化,可用内置工具重新分析:
go run ./probe -vid 2B89 -n 5 # 枚举设备、打印用法能力与原始报告
go run ./sample -n 120 -i 1000 # 采样 2 分钟,输出逐字节统计以定位字段go build -o ups-monitor.exe ./cmd/ups/要求 Go 1.20+,仅支持 Windows(依赖 Win32 HID API)。国内网络建议:
go env -w GOPROXY=https://goproxy.cn,direct- 长期监控:
ups-monitor.exe -web :8080 -csv ups.csv,同时获得可视化与原始数据。 - 断电演练:确认市电中断后程序能否在约 3 秒内切换到 OB 状态(程序内置 3 帧去抖)。
- 电池健康:关注"压差"指标。新电池约 20–30 mV,若长期超过 150 mV 说明电芯一致性下降。
- 续航估算:市电模式下按
43Wh × SOC ÷ 当前功率推算;实际断电后改用设备上报值,更为准确。
市电中断、UPS 仅靠电池供电时,可在电量耗尽前让电脑安全退场。设置无需修改启动参数——既可用命令行一次性指定,也能在运行时通过终端菜单或网页随时修改并保存。
ups-monitor.exe -low 20 # 电量<20% 自动关机(默认动作)
ups-monitor.exe -low 15 -action sleep # 电量<15% 睡眠
ups-monitor.exe -web :8080 -low 10 -action hibernate # Web 模式 + 电量<10% 休眠运行终端面板时,输入 c 回车即可进入设置菜单,无需停止监控:
低电量自动保护 · 设置
当前状态: 已启用(电量 < 20% 时 关机)
1) 修改电量阈值(当前 20%)
2) 修改动作(当前 关机)
3) 启用/禁用保护
4) 保存并返回
q) 不保存退出
- 选
1输入电量阈值(0=禁用),选2选择关机 / 睡眠 / 休眠 / 仅提示,选3启用或禁用; - 选
4写入配置文件ups-monitor.json并立即生效;q放弃修改。 - 终端面板底部提示:
按 c 进入设置 · Ctrl+C 退出(另外输入q可直接退出程序)。
Web 仪表盘底部新增"低电量自动保护"卡片:勾选启用、填写电量阈值、选择动作,点"保存"即生效并持久化,无需重启服务。卡片标题实时显示当前启用状态。
设置保存在与可执行文件同目录的 ups-monitor.json:
{
"low": 20,
"action": "shutdown"
}- 程序启动时:若给定
-low/-action启动参数则优先并回写配置;否则读取该文件;都没有则默认禁用。 - 运行时修改(菜单或网页)即时生效,并覆盖文件内容。
- 该文件已被
.gitignore忽略,不会进入版本库(每台机器独立配置)。
- 仅在电池供电(OB)模式下触发。市电供电(OL)时即便电量读数偏低也不会动作——避免老旧电池在插电状态下被误判而关机。
- 连续 3 帧确认:必须连续 3 次采样都满足"电池模式 + 电量低于阈值"才执行动作,过滤瞬时抖动与偶发错误读数。
- 单次触发:本会话内只执行一次。睡眠/休眠恢复后若电量仍低也不会再次触发,避免反复开关机。
- 动作可靠性:
shutdown(关机) 与hibernate(休眠) 通过系统shutdown.exe执行,稳定可靠;sleep(睡眠) 调用 WindowsSetSuspendState电源 API,绝大多数环境可用,个别环境失败时会回退到rundll32并写入事件日志;none(仅提示) 只记录事件、不执行任何电源动作。
建议在断电演练中验证:临时把阈值设到略高于当前电量(例如当前 100% 时设 99%),观察是否按预期关机/睡眠,确认无误后再设为真正想要的保护阈值。
- 交互式低电量配置:新增终端设置菜单(运行中输入
c进入)与 Web 仪表盘设置卡片,可随时修改"电量阈值 / 动作(关机·睡眠·休眠·仅提示)/ 启用禁用",并持久化到ups-monitor.json;启动参数-low/-action仍可在首次运行时覆盖并回写。详见 低电量自动保护。 - 低电量自动保护:市电中断、仅靠电池供电时,按阈值自动关机 / 睡眠 / 休眠(仅电池模式触发,连续 3 帧确认,单次触发)。
- 基础监控:通过 USB HID 直读 UGREEN US3000 遥测,提供终端实时面板 / JSON 输出 / Web 仪表盘三种用法,纯 Go 实现、零第三方依赖、免驱动。
协议字段依据实测与公开逆向资料整理,随固件版本可能变化。本工具仅做只读监控,不向设备写入任何控制指令。