From 650ec84b3e2dcda0110a90d0b66a1e38b228fe97 Mon Sep 17 00:00:00 2001 From: Andrew Sorensen Date: Sat, 9 Apr 2016 22:03:01 -0700 Subject: [PATCH] Initial version --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- fancontrol.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 fancontrol.py diff --git a/README.md b/README.md index b989033..f8796bb 100644 --- a/README.md +++ b/README.md @@ -1 +1,40 @@ -# lenovo-sa120-fanspeed-utility \ No newline at end of file +# lenovo-sa120-fanspeed-utility + +This is currently in prototype status. + +## Requirements + +apt-get install sg3-utils + +## Usage + +find your scsi controller (one of the /dev/sgX devices, perhaps using lsscsi) + +change /dev/sgX in fanspeed.py if needed. + +```` +# python fan.py 2 +Fan 0 speed: 0 +Fan 1 speed: 947 +Fan 2 speed: 932 +Fan 3 speed: 812 +Fan 4 speed: 932 +Fan 5 speed: 947 +Reading current configuration... +Setting fan 0 to 2 +Setting fan 1 to 2 +Setting fan 2 to 2 +Setting fan 3 to 2 +Setting fan 4 to 2 +Setting fan 5 to 2 + LENOVO ThinkServerSA120 1007 +Sending Enclosure Control [0x2] page, with page length=296 bytes + +Fan 0 speed: 0 +Fan 1 speed: 945 +Fan 2 speed: 932 +Fan 3 speed: 812 +Fan 4 speed: 926 +Fan 5 speed: 945 + +```` diff --git a/fancontrol.py b/fancontrol.py new file mode 100644 index 0000000..088364b --- /dev/null +++ b/fancontrol.py @@ -0,0 +1,51 @@ +import sys +import time +try: + from StringIO import StringIO +except ImportError: + from io import StringIO +from subprocess import check_output + +def print_speeds(): + for i in range(0, 6): + print("Fan {} speed: {}".format(i, check_output(['sg_ses', '--index=coo,{}'.format(i), '--get=1:2:11', '/dev/sg6']).decode('utf-8').split('\n')[0])) + +print_speeds() +print("Reading current configuration...") +out = check_output(["sg_ses", "-p", "0x2", "/dev/sg6", "--raw"]).decode('utf-8') +s = out.split() +if len(sys.argv) < 1: + print("python fanspeed.py 1-7") + sys.exit(-1) +fan = int(sys.argv[1]) +for i in range(0, 6): + print("Setting fan {} to {}".format(i, fan)) + idx = 92 + 4 * i + s[idx+0] = "80" + s[idx+1] = "00" + s[idx+2] = "00" + s[idx+3] = format(1 << 5 | fan & 7, "x") + +output = StringIO() +off = 0 +count = 0 +line = '' +while True: + output.write(s[off]) + off = off + 1 + count = count + 1 + if count == 8 : + output.write(" ") + elif count == 16: + output.write("\n") + count=0 + else: + output.write(" ") + if off >= len(s): + break +output.write("\n") +from subprocess import Popen, PIPE, STDOUT +p = Popen(['sg_ses', '-p', '0x2', '/dev/sg6', '--control', '--data', '-'], stdout=PIPE, stdin=PIPE, stderr=PIPE) +print(p.communicate(input=bytearray(output.getvalue(), 'utf-8'))[0].decode('utf-8')) +time.sleep(10) +print_speeds()