시놀로지 팬 가드 추가
This commit is contained in:
1 parent
33851e0189
commit
17dacd896f
3 files changed
+129
No files matched your search
@@ -102,6 +102,10 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를
|
||||
|
||||
커널 패닉이나 강제 재부팅 분석을 위해 `systemd-journald`는 `/var/log/journal`에 영구 저장합니다. `dtoverlay=ramoops` 기반 pstore는 부팅 직후 `control-pstore-collect.service`가 `/var/log/pstore`로 복사합니다. 현재 pstore에 남은 크래시 조각이 없으면 이 서비스는 조건 불충족으로 `inactive`일 수 있으며 정상입니다.
|
||||
|
||||
## 시놀로지 팬 가드
|
||||
|
||||
시놀로지 CPU 온도는 `k10temp`의 `Tdie` 값을 기준으로 보고, `nct6795`의 실제 회전 팬 `fan2_input`과 `pwm2`를 감시합니다. `bin/synology_fan_guard.sh`는 DSM 기본 팬 제어를 평소에는 유지하고, CPU가 75도 이상이면 `pwm2`를 255로 강제합니다. CPU가 65도 이하로 내려가고 수동 강제 상태라면 DSM 자동제어(`pwm2_enable=5`)로 되돌립니다. systemd 예시는 `systemd/synology-fan-guard.service`에 둡니다.
|
||||
|
||||
## UPS/배터리 상태
|
||||
|
||||
UPS가 과부하 상황에서 전압 하강과 강제 종료를 반복해 현재 운영 구성에서는 제거되어 있습니다. 이에 따라 Control은 기본적으로 MAX17048 배터리 센서를 읽지 않고, 배터리 SOC/전압 차트와 잔여 시간 UI도 표시하지 않습니다.
|
||||
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
INTERVAL_SECONDS="${INTERVAL_SECONDS:-5}"
|
||||
HIGH_TEMP_C="${HIGH_TEMP_C:-75}"
|
||||
LOW_TEMP_C="${LOW_TEMP_C:-65}"
|
||||
PWM_CHANNEL="${PWM_CHANNEL:-2}"
|
||||
PWM_FULL="${PWM_FULL:-255}"
|
||||
PWM_AUTO_ENABLE="${PWM_AUTO_ENABLE:-5}"
|
||||
PWM_MANUAL_ENABLE="${PWM_MANUAL_ENABLE:-1}"
|
||||
LAST_MODE=""
|
||||
|
||||
log() {
|
||||
if command -v logger >/dev/null 2>&1; then
|
||||
logger -t syno-fan-guard "$*"
|
||||
fi
|
||||
printf '%s\n' "$*"
|
||||
}
|
||||
|
||||
hwmon_by_name() {
|
||||
target="$1"
|
||||
for hwmon in /sys/class/hwmon/hwmon*; do
|
||||
[ -r "$hwmon/name" ] || continue
|
||||
[ "$(cat "$hwmon/name" 2>/dev/null)" = "$target" ] || continue
|
||||
printf '%s\n' "$hwmon"
|
||||
return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
read_cpu_temp_mc() {
|
||||
cpu_hwmon="$(hwmon_by_name k10temp || true)"
|
||||
if [ -n "$cpu_hwmon" ]; then
|
||||
for sensor in temp2_input temp1_input temp3_input; do
|
||||
path="$cpu_hwmon/$sensor"
|
||||
[ -r "$path" ] || continue
|
||||
value="$(cat "$path" 2>/dev/null || printf 0)"
|
||||
case "$value" in
|
||||
''|*[!0-9-]*) continue ;;
|
||||
esac
|
||||
[ "$value" -gt 0 ] || continue
|
||||
printf '%s\n' "$value"
|
||||
return 0
|
||||
done
|
||||
fi
|
||||
printf '0\n'
|
||||
}
|
||||
|
||||
fan_hwmon() {
|
||||
hwmon_by_name nct6795
|
||||
}
|
||||
|
||||
write_if_needed() {
|
||||
path="$1"
|
||||
value="$2"
|
||||
[ -w "$path" ] || return 1
|
||||
current="$(cat "$path" 2>/dev/null || printf '')"
|
||||
[ "$current" = "$value" ] && return 0
|
||||
printf '%s\n' "$value" > "$path"
|
||||
}
|
||||
|
||||
apply_once() {
|
||||
verbose="${1:-0}"
|
||||
fan_hwmon_path="$(fan_hwmon)"
|
||||
pwm_path="$fan_hwmon_path/pwm${PWM_CHANNEL}"
|
||||
enable_path="$fan_hwmon_path/pwm${PWM_CHANNEL}_enable"
|
||||
rpm_path="$fan_hwmon_path/fan${PWM_CHANNEL}_input"
|
||||
temp_mc="$(read_cpu_temp_mc)"
|
||||
temp_c=$((temp_mc / 1000))
|
||||
rpm=0
|
||||
[ -r "$rpm_path" ] && rpm="$(cat "$rpm_path" 2>/dev/null || printf 0)"
|
||||
enable="$(cat "$enable_path" 2>/dev/null || printf '?')"
|
||||
pwm="$(cat "$pwm_path" 2>/dev/null || printf '?')"
|
||||
|
||||
if [ "$temp_c" -ge "$HIGH_TEMP_C" ]; then
|
||||
write_if_needed "$enable_path" "$PWM_MANUAL_ENABLE"
|
||||
write_if_needed "$pwm_path" "$PWM_FULL"
|
||||
if [ "$LAST_MODE" != "force-full" ] || [ "$verbose" = "1" ]; then
|
||||
log "force-full temp=${temp_c}C rpm=${rpm} pwm=${pwm} enable=${enable}"
|
||||
fi
|
||||
LAST_MODE="force-full"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$temp_c" -le "$LOW_TEMP_C" ] && [ "$enable" != "$PWM_AUTO_ENABLE" ]; then
|
||||
write_if_needed "$enable_path" "$PWM_AUTO_ENABLE"
|
||||
log "restore-auto temp=${temp_c}C rpm=${rpm} pwm=${pwm} enable=${enable}"
|
||||
LAST_MODE="auto"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$verbose" = "1" ]; then
|
||||
log "observe temp=${temp_c}C rpm=${rpm} pwm=${pwm} enable=${enable}"
|
||||
fi
|
||||
LAST_MODE="observe"
|
||||
}
|
||||
|
||||
case "${1:-run}" in
|
||||
once|status)
|
||||
apply_once 1
|
||||
;;
|
||||
run)
|
||||
log "start high=${HIGH_TEMP_C}C low=${LOW_TEMP_C}C channel=${PWM_CHANNEL}"
|
||||
while :; do
|
||||
apply_once 0 || true
|
||||
sleep "$INTERVAL_SECONDS"
|
||||
done
|
||||
;;
|
||||
*)
|
||||
printf 'Usage: %s [run|once|status]\n' "$0" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Synology CPU temperature fan guard
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/sbin/synology-fan-guard run
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user