前言
海康威视R1这台机器颜值、性价比都很高,功耗低、四盘位、N100、双2.5G网卡、板载EMMC、有两个NVME固态硬盘插槽,基本满足了我对NAS的需求。但机器自带的NAS系统不能当作普通Linux系统使用,所以机器到手第一时间就安装了Ubuntu Server 24.04系统(为了不破坏板载闪存上的原版系统,Ubuntu系统安装在NVME固态硬盘上,后续会庆幸这个英明的决定,哈哈)。 但海康威视R1这台机器当作一台7*24小时运行的Ubuntu服务器,存在几大硬伤:
一、机箱氛围灯无法关闭,虽然看着很酷炫
二、风扇无法控制转速,重负载时CPU温度会飙升到90度,平时无负载时风扇不减速或停止
三、前面板小屏幕无法关闭
第一个问题,机箱氛围灯(RGB灯光)
原厂系统里可以手动关闭主板氛围灯,换成 Ubuntu 之后,这个开关功能直接消失了。
这个问题其实说大不大,说小也不小;但 R1 很多人会放卧室、书房或者电视柜旁边,氛围灯晚上一直亮着,真的影响休息。前前后后试了 GPIO、ACPI、显示驱动、I2C,走了不少弯路,最后才从原厂 eMMC 镜像里把真正的控制方式抠出来。
结论先放在前面:
- 在
Ubuntu Server 24.04下可以成功关闭海康威视 R1 的氛围灯 (其它Linux系统应该也可以) - 方案已经做成可持久化配置,重启系统后依然生效
机器系统配置
- 原厂系统:安装在板载 eMMC
- Ubuntu Server 24.04:安装在 NVMe
一开始,我也以为是 GPIO
装完 Ubuntu 之后,最自然的第一反应当然是先看 Linux 有没有现成的 LED 接口:
ls /sys/class/leds
结果是空的。
那就只能继续找,开始怀疑是不是某个 GPIO 在控制灯。因为很多小主机、NAS、软路由的前面板功能,本来就可能挂在 GPIO 或 Super I/O 上。
我当时重点排查了两类:
gpiochip0:Intel PCH 提供的 GPIOgpiochip1:IT8613 Super I/O 提供的 GPIO
后面还专门做了几轮扫描:
- 扫
gpiochip1多个线号 - 扫
gpiochip0的GPP_E范围
结果:氛围灯完全没有变化。
R1 这台机器的氛围灯,不是靠普通 GPIO 直接拉高拉低就能解决的。
中途还误判过 I2C 设备
但这条线很快就被证伪了。
后面确认下来,i2c-2 上的 0x44 实际上是 Sensirion SHT4x 温湿度传感器,不是灯控芯片。
后来又怀疑 ACPI、BIOS、显示驱动
但最终都解决不了。
别猜了,还是直接去看原厂系统吧
所以,这里很庆幸没有把原厂系统格式化掉!!
先把原厂 eMMC 挂起来
挂载之后大致能对应出这些内容:
mmcblk0p3/mmcblk0p8:原厂系统分区mmcblk0p4/mmcblk0p5:histor.imgmmcblk0p7:小屏应用分区mmcblk0p6:配置分区
很快能发现两个关键点:
- 原厂前面板小屏应用是一个 Electron AppImage。
- 原厂真正的后端业务不在小屏分区里,而是在
histor.img。
这时候就知道该往哪下手了:前端看协议,后端找实现。
先从前端小屏应用里找线索
小屏分区里有这样一个文件:
HistorSub-Linux-1.1.15.AppImage
把它解包之后,前端代码里能看到一些非常直白的字段,比如:
deviceLightColordeviceLightMode
看到这里,其实已经能确认一件事:
这条氛围灯不是 Linux 标准
leds子系统在管,而是前面板/小屏这套软件栈的一部分。
继续往下看前端打包出来的 JS,很快又挖到了一个更关键的点:它并不是直接操作 GPIO,而是去访问一个本地 HTTPS 服务:
https://127.0.0.1:20443
而且代码里直接出现了这些动作:
get_atmo_lightset_atmo_lightset_atmo_colorget_light_themeset_light_theme
甚至还能看到灯效枚举:
LightEffectTurnOff = 999LightEffectMatchTheme = 1000LightEffectDynamicColor = 1001LightEffectBlueColor = 1002LightEffectWhiteColor = 1003LightEffectYellowColor = 1004
这一步非常有价值,因为它说明了两件事:
- 原厂前端确实在通过本地服务控制氛围灯
- “关灯”这个动作在原厂软件里是真实存在、可调用的
所以问题是:
这个服务到底是谁提供的?
最关键的后端,在 histor.img
把 histor.img 也挂出来之后,可以看到一批原厂二进制程序,比如:
emhistormod_intfproxyDaemonkey_event_handleserver_recv
其中最像“核心业务后端”的,就是:
/histor/bin/emhistor
继续在二进制字符串里搜,很快就发现它明确包含:
20443set_atmo_lightget_atmo_lightset_atmo_colorset_light_theme
到这里其实已经八九不离十了。
换句话说,原厂前端访问的那个本地服务,基本就是 emhistor 在提供服务。
接下来我没有去整套复刻原厂系统,而是做了一个更小、更安全的实验:
- 临时把原厂
histor环境挂到 Ubuntu - 补上它需要的动态库
- 直接尝试启动
emhistor
虽然它启动后报了不少“原厂环境不完整”的错误,但日志里出现了一条关键内容:
i2cset -f -y 0 0x26 0x90 0x0
看到这一行的时候,答案就已经出来了。
对,关灯就是这么关的。
最终结论:真正可用的关灯命令
在海康威视 R1 上,Ubuntu 下可以直接关闭氛围灯的命令就是:
sudo i2cset -f -y 0 0x26 0x90 0x0
执行完之后,可以再读一下对应寄存器确认:
sudo i2cget -f -y 0 0x26 0x90
正常会读到:
0x00
这条命令已经在实机验证通过:
- 执行后氛围灯彻底熄灭
- 配成自动化之后,Ubuntu 重启后依然保持熄灭
Ubuntu 下的最终修复方案
下面这套是我最终落地并验证通过的方案。
1. 安装 i2c-tools
如果系统里没有 i2cset / i2cget:
sudo apt update
sudo apt install -y i2c-tools
2. 写入控制脚本
创建文件:
/usr/local/sbin/hkvr1-ambient-light
内容如下:
#!/bin/sh
# 海康 R1 系氛围灯(DMI 匹配见 /etc/default/hkvr1-ambient 中 HKVR1_PRODUCT_PATTERN)。
# Reverse-engineered from the OEM eMMC image:
# i2cset -f -y 0 0x26 0x90 0x0 -> light off
set -eu
DEFAULTS=/etc/default/hkvr1-ambient
[ -r "$DEFAULTS" ] && . "$DEFAULTS"
: "${HKVR1_PRODUCT_PATTERN:=HS-EXMP-R1}"
: "${HKVR1_AMBIENT_BUS:=0}"
: "${HKVR1_AMBIENT_ADDR:=0x26}"
: "${HKVR1_AMBIENT_REG:=0x90}"
: "${HKVR1_AMBIENT_OFF:=0x0}"
: "${HKVR1_AMBIENT_ON:=0x9}"
usage() {
echo "Usage: $0 verify-dmi | get | off | on" >&2
echo " get - read current ambient-light register" >&2
echo " off - turn ambient light off" >&2
echo " on - restore OEM 'enabled' status value" >&2
exit 2
}
verify_dmi() {
pn=$(cat /sys/class/dmi/id/product_name 2>/dev/null || true)
case "$pn" in
"$HKVR1_PRODUCT_PATTERN"|"${HKVR1_PRODUCT_PATTERN}"*) return 0 ;;
esac
echo "hkvr1-ambient-light: unsupported product_name '$pn' (set HKVR1_PRODUCT_PATTERN in $DEFAULTS)" >&2
return 1
}
require_tools() {
command -v i2cget >/dev/null 2>&1 || {
echo "hkvr1-ambient-light: missing i2cget (install i2c-tools)." >&2
exit 1
}
command -v i2cset >/dev/null 2>&1 || {
echo "hkvr1-ambient-light: missing i2cset (install i2c-tools)." >&2
exit 1
}
}
cmd_get() {
verify_dmi || exit 1
require_tools
exec i2cget -f -y "$HKVR1_AMBIENT_BUS" "$HKVR1_AMBIENT_ADDR" "$HKVR1_AMBIENT_REG"
}
cmd_write() {
value=$1
verify_dmi || exit 1
require_tools
exec i2cset -f -y "$HKVR1_AMBIENT_BUS" "$HKVR1_AMBIENT_ADDR" "$HKVR1_AMBIENT_REG" "$value"
}
case "${1:-}" in
verify-dmi) verify_dmi ;;
get|status) cmd_get ;;
off|hold) cmd_write "$HKVR1_AMBIENT_OFF" ;;
on|release) cmd_write "$HKVR1_AMBIENT_ON" ;;
*) usage ;;
esac
给脚本加执行权限:
sudo chmod 755 /usr/local/sbin/hkvr1-ambient-light
3. 写入默认配置
创建文件:
/etc/default/hkvr1-ambient
内容如下:
# 海康 R1 系氛围灯(HKVR1_PRODUCT_PATTERN 须与本机 DMI product_name 一致;以下为占位示例)
HKVR1_PRODUCT_PATTERN=HS-EXMP-R1
# Hikvision R-class ambient light settings (I2C).
# Reverse-engineered from the OEM eMMC image.
#
# Known-good off command:
# sudo i2cset -f -y 0 0x26 0x90 0x0
#
# Manual checks:
# sudo hkvr1-ambient-light get
# sudo hkvr1-ambient-light off
# sudo hkvr1-ambient-light on
#
# Notes:
# - i2c-2 address 0x44 is the SHT4x temp/humidity sensor, not the LED controller.
# - The ambient light is controlled through i2c-0 address 0x26 register 0x90.
HKVR1_AMBIENT_BUS=0
HKVR1_AMBIENT_ADDR=0x26
HKVR1_AMBIENT_REG=0x90
HKVR1_AMBIENT_OFF=0x0
HKVR1_AMBIENT_ON=0x9
4. 配置开机自动关灯服务
创建文件:
/etc/systemd/system/hkvr1-ambient-light-off.service
内容如下:
[Unit]
Description=Hikvision R1 ambient light off
Documentation=file:/etc/default/hkvr1-ambient
After=systemd-modules-load.service systemd-udev-settle.service local-fs.target
Wants=systemd-udev-settle.service
[Service]
Type=oneshot
EnvironmentFile=-/etc/default/hkvr1-ambient
ExecStartPre=/sbin/modprobe i2c-dev
ExecStartPre=/usr/local/sbin/hkvr1-ambient-light verify-dmi
ExecStartPre=/bin/sh -c 'for _ in $(seq 1 20); do [ -c /dev/i2c-0 ] && exit 0; sleep 1; done; echo "hkvr1-ambient-light: /dev/i2c-0 not ready" >&2; exit 1'
ExecStart=/usr/local/sbin/hkvr1-ambient-light off
RemainAfterExit=yes
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
启用服务:
sudo systemctl daemon-reload
sudo systemctl enable --now hkvr1-ambient-light-off.service
5. 验证
手动验证可以先这样做:
sudo hkvr1-ambient-light get
sudo hkvr1-ambient-light off
sudo hkvr1-ambient-light get
查看服务状态:
systemctl status hkvr1-ambient-light-off.service
最后重启一次系统:
sudo reboot
重新进入 Ubuntu 后,氛围灯依然是灭的
systemctl status hkvr1-ambient-light-off.service显示成功执行
脚本里我同时保留了:
sudo hkvr1-ambient-light on
它对应的是原厂逻辑里的启用状态值 0x9。如果你确实有重新打开氛围灯的需求,可以自己试一下;
评论 (0)
暂无评论,来做第一个留言的人吧!