Created
June 18, 2021 18:14
-
-
Save haxwithaxe/93d1b6b66220a6f3d90cdf73450d16bd to your computer and use it in GitHub Desktop.
A script to adjust the fan speed on a Supermicro X9 motherboard based on hard drive temperatures.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""A script to adjust the fan speed on a Supermicro X9 motherboard based on | |
hard drive temperatures. | |
Install to `/usr/local/sbin/coolhddx9` for use with the associated systemd | |
service and timer. | |
""" | |
import glob | |
import os | |
import subprocess | |
MAX_TEMP = 39 # Magic number from a differnt script found online | |
FULL = '0x01' # "Maximum cooling" | |
OPTIMAL = '0x02' # "Balanced fan speed and power consumption" | |
def get_temp(hdd): | |
"""Get the temperature of `hdd` from `smartctl`. | |
Arguments: | |
hdd (str): The path to a hard drive block device. | |
Returns: | |
int: The temperature of `hdd` or 0 if a temperature can't be found. | |
""" | |
try: | |
lines = subprocess.check_output(['smartctl', '--attributes', hdd]) | |
except subprocess.CalledProcessError as err: | |
print('Error:', err) | |
return 0 | |
for line in lines.split(b'\n'): | |
if b'Temp' in line: | |
# Sometimes there is a "(Min/Max n/n)" at the end of the line. | |
# This gives "n/n)" in the last index. | |
try: | |
# No min/max | |
return int(line.split()[-1]) | |
except ValueError: | |
# Min/max. Use a different index. | |
return int(line.split()[-3]) | |
print('Error: No temp found for', hdd) | |
return 0 | |
def set_mode(mode): | |
"""Set the fan mode of the motherboard.""" | |
proc = subprocess.run(['ipmitool', 'raw', '0x30', '0x45', '0x01', mode], | |
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | |
if proc.returncode != 0: | |
print('Error:', proc.stdout) | |
def _main(): | |
for hdd in glob.glob('/dev/sd[a-z]'): | |
if get_temp(hdd) > MAX_TEMP: | |
set_mode(FULL) | |
return | |
set_mode(OPTIMAL) | |
if __name__ == '__main__': | |
_main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description=HDD tempurature manager | |
[Service] | |
Type=oneshot | |
ExecStart=/usr/local/sbin/coolhddx9 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Unit] | |
Description=HDD tempurature manager | |
[Timer] | |
OnBootSec=10m | |
OnUnitActivate=10m | |
Unit=coolhddx9.service | |
[Install] | |
WantedBy=timers.target |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment