场景:山特 TG-BOX 850 UPS 通过 USB 直连飞牛 NAS,飞牛已自带 NUT 服务,无需额外安装。目标:停电时自动感知,并通知 Home Assistant。
NUT 三层架构速解
NUT(Network UPS Tools)是 Linux 下 UPS 监控的标准方案,USB 直连时只用到前两层:
| 层 | 组件 | 功能 |
|---|---|---|
| Driver 层 | usbhid-ups |
通过 USB 与 UPS 硬件通信,协议翻译 |
| Server 层 | upsd |
收集 UPS 数据,TCP 3493 端口提供统一协议,支持认证和权限管理 |
| Client 层 | upsmon |
监控 UPS 状态,电量低于阈值执行关机 |
飞牛 FnOS 应用中心启用 NUT 后,usbhid-ups 驱动自动识别 USB UPS,无需手动配置驱动。
核心配置文件
| 文件 | 作用 |
|---|---|
ups.conf |
驱动配置(USB 连接时通常自动识别,无需修改) |
upsd.conf |
服务器配置(监听地址、端口) |
upsd.users |
用户认证(用户名/密码/角色) |
upsmon.conf |
客户端配置(阈值、SHUTDOWNCMD) |
飞牛 FnOS 的 NUT 默认配置
| 配置项 | 值 |
|---|---|
| NUT 用户名 | monuser |
| NUT 密码 | trim-secret |
| 角色 | master(直连 UPS 的那台 FnOS) |
| UPS 名称 | 2029431(示例,实际用 upsc -l 查) |
| 配置文件路径 | /etc/nut/upsd.users |
验证 UPS 是否被识别
# 查看 UPS 名称列表
upsc -l
# 查看 UPS 详细数据(ups.status / battery.charge / ups.load 等)
upsc 2029431
如果
upsc -l输出为空,说明 USB 未被识别,尝试重启飞牛或检查 USB 线接触。
⚠️ 远程访问时的关键问题:监听地址
如果 Home Assistant 装在另一台机器上,需要从网络访问 NUT 服务,则 upsd 默认只监听 127.0.0.1:3493,HA 扫不到。
修复步骤
1. 编辑配置文件
vim /etc/nut/upsd.conf
2. 改为全网监听
# LISTEN 127.0.0.1 3493
LISTEN 0.0.0.0 3493
3. 重启服务
systemctl daemon-reload
systemctl restart nut-server.service
4. 验证
ss -lnp | grep 3493
# 应显示 0.0.0.0:3493
💡 如果 Home Assistant 也装在飞牛本机上,不需要改监听地址,默认的
127.0.0.1:3493就够用。只有 HA 在其他机器时才需要改。
排查清单
| 步骤 | 命令 |
|---|---|
| 检查飞牛防火墙 | 控制面板 → 安全 → 防火墙,放行 3493 端口 |
| 检查监听地址 | grep LISTEN /etc/nut/upsd.conf |
| 测试网络连接 | nc -zv 飞牛IP 3493 |
Home Assistant NUT 集成配置
Home Assistant 装在其他机器时,在 设置 → 设备与服务 → 添加集成 里搜索 NUT,填入:
| 字段 | 值 |
|---|---|
| Host | 飞牛内网 IP(如 192.168.x.x) |
| Port | 3493 |
| Username | monuser |
| Password | trim-secret |
| UPS name | 2029431(用 upsc -l 查出的实际名称) |
如果 HA 装在飞牛本机,Host 填
localhost或127.0.0.1。
集成成功后自动发现以下实体:
| 显示名称 | Entity ID |
|---|---|
| 状态数据 | sensor.2029431_status |
| 电池充电 | sensor.2029431_battery_charge |
| 负载 | sensor.2029431_load |
| 电池续航 | sensor.2029431_battery_runtime |
| 输入电压 | sensor.2029431_input_voltage |
| 输出电压 | sensor.2029431_output_voltage |
NUT 输出数据解读
upsc 2029431 关键字段:
| 字段 | 示例值 | 含义 |
|---|---|---|
ups.status |
OL |
市电正常(Online) |
ups.status |
OB |
电池供电(On Battery) |
ups.status |
LB |
电池电量低(Low Battery) |
battery.charge |
100 |
电池剩余百分比(%) |
battery.runtime |
2400 |
电池续航秒数 |
ups.load |
12 |
当前负载百分比(%) |
HA 自动化示例
停电告警
automation:
- alias: "停电告警"
trigger:
- platform: state
entity_id: sensor.2029431_status
to: "OB"
action:
- service: notify.mobile_app_你的手机
data:
title: "停电了"
message: "飞牛 UPS 切电池,剩余 {{ states('sensor.2029431_battery_runtime') }} 秒"
市电恢复通知
automation:
- alias: "市电恢复通知"
trigger:
- platform: state
entity_id: sensor.2029431_status
to: "OL"
action:
- service: notify.mobile_app_你的手机
data:
title: "市电恢复"
message: "飞牛 UPS 已切回市电,供电正常"
完整测试流程
拔掉 UPS 电源测试
- 观察
sensor.2029431_status从OL→OB - 检查
input_voltage从正常值 →0 - 确认手机收到停电告警通知
- 插回 UPS,确认状态恢复
OL并收到恢复通知
验证飞牛关机策略
cat /etc/nut/upsmon.conf | grep -E "SHUTDOWN|NOTIFY"
常见问题
| 问题 | 解决方案 |
|---|---|
upsc -l 输出为空 |
重启飞牛 NAS,或检查 USB 线接触和供电 |
HA 连接失败 Errno 111 |
检查飞牛防火墙 + 确认 LISTEN 0.0.0.0 3493(HA 在其他机器时) |
| 修改后不生效 | 确认修改的是 /etc/nut/upsd.conf,重启 nut-server.service |
| 停电后飞牛没自动关机 | 检查 upsmon.conf 里的 SHUTDOWNCMD 和 FINALDELAY 设置 |
| UPS name 填什么 | 飞牛上执行 upsc -l,输出第一行即 UPS name |