Ubuntu Pastebin

Paste from tj at Wed, 2 Dec 2015 17:04:15 +0000

Download as text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/bin/sh
# monitor temperature on external Quadro NVS420 and adjust fan speed
# logs changes to syslog
# Copyright 2015 TJ <hacker@iam.tj>
# Licenced on the terms of the GNU General Public Licence version 3

# uncomment for debugging in foreground
# set -x

# user-friendly device name for logging
TARGET=${TARGET:-NVS420}

# GPUs reported by nvidia-settings
GPU_CONTROL=${GPU_CONTROL:-1 2}
# Fans reported
FAN_CONTROL=${FAN_CONTROL:-0}

# temperature bounds
TARGET_TEMP_MIN=${TARGET_TEMP_MIN:-60}
TARGET_TEMP_RANGE=${TARGET_TEMP_RANGE:-5}
TARGET_TEMP_MAX=${TARGET_TEMP_MAX:-$((TARGET_TEMP_MIN + TARGET_TEMP_RANGE))}

# sampling delay in seconds
SLEEP=${SLEEP:-2}

# percentages
FAN_SPEED_MAX=${FAN_SPEED_MAX:-100}
FAN_SPEED_MIN=${FAN_SPEED_MIN:-30}
FAN_SPEED_STEP_BASE=${FAN_SPEED_STEP_BASE:-5}
FAN_SPEED_STEP=${FAN_SPEED_STEP_BASE}

# maximum speed change in one operation
FAN_SPEED_STEP_MAX=$(( (FAN_SPEED_MAX - FAN_SPEED_STEP_MIN) / 4 ))

TEMP_LAST=0
NO_CHANGE_COUNT=0

# adjust fan speed in proportion to temperature differential
adjust_proportional ()
{
  TEMP_DIFF=$(( TEMP_AVG - TARGET_TEMP_MIN ))
  TEMP_CHANGE=$(( TEMP_AVG - TEMP_LAST ))
  # shell doesn't allow return values < 0 so bias to 128 and remember to remove bias in calling code
  return $(( TEMP_CHANGE * TEMP_DIFF + $1 + TEMP_DIFF + 128 ))
}


# start
logger -p syslog.notice -- nvidia_fan_control[$$]: ${TARGET} Target ${TARGET_TEMP_MIN}-${TARGET_TEMP_MAX}°C controlling GPUs: ${GPU_CONTROL} Fans: ${FAN_CONTROL}

# continue looping whilst the X server is running
while pgrep X; do
  TEMP_AVG=0
  GPU_COUNT=0
  for GPU in ${GPU_CONTROL}; do
    TEMP_AVG=$(( TEMP_AVG + $(nvidia-settings --terse --query [gpu:${GPU}]/GPUCoreTemp) ))
  done
  TEMP_AVG=$(( TEMP_AVG/2 ))

  for FAN in ${FAN_CONTROL}; do
    FAN_SPEED=$(nvidia-settings --terse --query [fan:${FAN}]/GPUTargetFanSpeed)

    if [ -n "${TEMP_AVG}" -a -n "${FAN_SPEED}" ]; then
      FAN_SPEED_NEW=${FAN_SPEED}

      # call adjustment calculation function
      if [ ${TEMP_LAST} -gt 0 ]; then
       adjust_proportional ${FAN_SPEED}
       FAN_SPEED_NEW=$(( $? - 128))
      fi

      if   [ ${FAN_SPEED_NEW} -gt ${FAN_SPEED_MAX} ]; then
        FAN_SPEED_NEW=${FAN_SPEED_MAX}
      elif [ ${FAN_SPEED_NEW} -lt ${FAN_SPEED_MIN} ]; then
        FAN_SPEED_NEW=${FAN_SPEED_MIN}
      fi

      if [ ${FAN_SPEED} -ne ${FAN_SPEED_NEW} ]; then
        for GPU in ${GPU_CONTROL}; do
          nvidia-settings --verbose=none --assign=[gpu:${GPU}]/GPUFanControlState=1 >/dev/null
        done
        nvidia-settings --verbose=none --assign=[fan:${FAN}]/GPUTargetFanSpeed=${FAN_SPEED_NEW} >/dev/null
        logger -p syslog.notice -- nvidia_fan_control[$$]: ${TARGET} Target ${TARGET_TEMP_MIN}-${TARGET_TEMP_MAX}°C  Temp=${TEMP_AVG}°C Fan=${FAN_SPEED_NEW}%
      fi
    fi
    
  done
  TEMP_LAST=${TEMP_AVG}
  sleep ${SLEEP}
done
Download as text