#!/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