First version
parent
87ea517ef5
commit
a87a3d2ddf
@ -1,2 +1,16 @@
|
||||
# asrock-pwm-ipmi
|
||||
|
||||
This is a script to control 4-pin PWM fans on ASRock Rack motherboards with IPMI. The BMC does not properly expose fan control, so they must be controlled using raw IPMI commands. This script is a user-friendly way to do that.
|
||||
|
||||
|
||||
usage: asrock-pwm-ipmi [-h] [-i] [FAN:SPEED [FAN:SPEED ...]]
|
||||
|
||||
Read information about and control fans on ASRock boards with IPMI.
|
||||
|
||||
positional arguments:
|
||||
FAN:SPEED Fan to change the speed of, and the speed, separated by ':'. Set
|
||||
to 0 for auto.
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-i, --info Read fan information
|
||||
|
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
./pwm.py $@
|
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/python3
|
||||
import run_cmd
|
||||
import argparse
|
||||
|
||||
MAXFAN = 6
|
||||
|
||||
parser = argparse.ArgumentParser(description='Read information about and control fans on ASRock boards with IPMI.', prog='asrock-pwm-ipmi')
|
||||
parser.add_argument('fanplusspeed', nargs='*', metavar='FAN:SPEED',
|
||||
help='Fan to change the speed of, and the speed, separated by \':\'. Set to 0 for auto.')
|
||||
#parser.add_argument('SPEED', type=int, nargs='+',
|
||||
# help='Speed to set FAN to')
|
||||
parser.add_argument('-i', '--info', action="store_true", default=False,
|
||||
help='Read fan information')
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
#print(args.info)
|
||||
#print(args)
|
||||
#print(args.fanplusspeed)
|
||||
if args.info is False and args.fanplusspeed == []:
|
||||
print("Nothing to do! See --help for usage.")
|
||||
quit
|
||||
if args.fanplusspeed != []:
|
||||
for fanopt in args.fanplusspeed:
|
||||
if str(fanopt.split(":"))[2:-2] == fanopt or int(fanopt.split(":")[0]) < 1 or int(fanopt.split(":")[0]) > MAXFAN:
|
||||
print("Improper format!")
|
||||
continue
|
||||
fan, speed = fanopt.split(":")
|
||||
run_cmd.setSpeed(int(fan), int(speed))
|
||||
if int(speed) == 0:
|
||||
print("Set speed of FAN" + fan + " to Auto.")
|
||||
else:
|
||||
print("Set speed of FAN" + fan + " to " + speed + "%.")
|
||||
if args.info is True:
|
||||
print("\nRetrieving fan speeds...\n")
|
||||
for line in run_cmd.getFanInfo():
|
||||
print(line)
|
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python3
|
||||
import subprocess as sp
|
||||
|
||||
def setSpeed(fan, setspeed):
|
||||
speeds, speedsRaw = getAllSpeeds()
|
||||
speedcmd = ["ipmitool", "raw", "0x3a", "0x01"]
|
||||
for speed in speedsRaw:
|
||||
hexspeed = "0x"
|
||||
hexspeed += str(speed)
|
||||
speedcmd.append(hexspeed)
|
||||
speedcmd.append("0x00") # append the mystery (unused) extra values
|
||||
speedcmd.append("0x00")
|
||||
speedcmd[fan + 3] = hex(setspeed) # index + 3 because the array already has the beginning of the command
|
||||
#print(speeds)
|
||||
sp.call(speedcmd)
|
||||
|
||||
def getAllSpeeds():
|
||||
cmdoutput = sp.Popen(["ipmitool", "raw", "0x3a", "0x02"], stdout=sp.PIPE)
|
||||
speedsRaw, err = cmdoutput.communicate()
|
||||
speedsRaw = str(speedsRaw)[3:20].split()
|
||||
speeds = []
|
||||
for speed in speedsRaw:
|
||||
speeds.append(int(speed, 16))
|
||||
return speeds, speedsRaw
|
||||
|
||||
def getSpeed(fan):
|
||||
speeds, speedsRaw = getAllSpeeds()
|
||||
return speeds[fan - 1]
|
||||
|
||||
def getFanInfo():
|
||||
cmdoutput = sp.Popen(["ipmitool", "sdr"], stdout=sp.PIPE)
|
||||
sensorinfo, err = cmdoutput.communicate()
|
||||
#print(sensorinfo.splitlines())
|
||||
faninfo = []
|
||||
speeds, speedsRaw= getAllSpeeds()
|
||||
for line in sensorinfo.splitlines():
|
||||
if "FAN" in str(line):
|
||||
faninfo.append(str(line))
|
||||
for index, line in enumerate(faninfo):
|
||||
faninfo[index] = str(line)[2:-1]
|
||||
faninfo[index] += " | "
|
||||
if speeds[index] == 0:
|
||||
faninfo[index] += "Auto"
|
||||
else:
|
||||
faninfo[index] += str(speeds[index])
|
||||
faninfo[index] += "%"
|
||||
#print(faninfo[index])
|
||||
return faninfo
|
Loading…
Reference in New Issue