from subprocess import Popen, PIPE, STDOUT
import time
import string

maxCpuTemp = 88
highCpuTemp = 68
medCpuTemp = 58
semiCpuTemp = 48
lowCpuTemp = 38

sleepTime = 5
celcius = 'C'
floatDot = '.'

user = "admin"
password = "password"
ip = "192.168.123.123"

#Do a command and return the stdout of proccess
def sendcommand(cmdIn):
    p = Popen(cmdIn, shell=True, executable="/bin/bash", stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    print(cmdIn)
    return p.stdout.read()

#Do a ipmi command, setup for the default command.
def ipmicmd(cmdIn):
    return sendcommand("ipmitool -I lanplus -H " + ip +" -U " + user + " -P " + password + " " + cmdIn)

#Gets the CPU temperture from lm-sensors, returns the average of it.
#This isn't ideal for times when one CPU is much hotter than the other.
def getcputemp():
    cmd = sendcommand('sensors  -u | grep "input"')
    indexes = [pos for pos, char in enumerate(cmd) if char == floatDot]
    cputemperatures = []
    for loc in indexes:
        temp = cmd[int(loc) - 2] + cmd[int(loc) - 1]
        cputemperatures.append(int(temp))

    #return the average cpu temperature
    return sum(cputemperatures) / int(len(cputemperatures))

#Check if controller was in automode, if so we override to manual.
def checkstatus(status):
    if (status == 4):
        ipmicmd("raw 0x30 0x30 0x01 0x00")

#Main checking function which checks temperatures to the default set above.
def checktemps(status):
    avgCpuT = getcputemp()

    if (avgCpuT > maxCpuTemp):
        if (status != 4):
            ipmicmd("raw 0x30 0x30 0x01 0x01")
            print("Setting fans to auto/loud mode, server is too hot")
        status = 4

    elif(avgCpuT > highCpuTemp):
        if (status != 3):
            checkstatus(status)
            ipmicmd("raw 0x30 0x30 0x02 0xff 0x14")
            print("Setting to high RPM")
        status = 3

    elif(avgCpuT > medCpuTemp):
        if (status != 2):
            checkstatus(status)
            ipmicmd("raw 0x30 0x30 0x02 0xff 0x07")
            print("Setting to medium RPM")
        status = 2

    elif(avgCpuT > semiCpuTemp):
        if (status != 1):
            checkstatus(status)
            ipmicmd("raw 0x30 0x30 0x02 0xff 0x06")
            print("Setting to low RPM")
        status = 1

    else:
        checkstatus(status)
        if (status != 0):
            ipmicmd("raw 0x30 0x30 0x02 0xff 0x05")
            print("Setting to minimum RPM")
        status = 0

    print("Cpu at: " + str(avgCpuT) + " celcius \n")
    return status

#Main running function.
def main():
    ipmicmd("raw 0x30 0x30 0x01 0x00")
    status = 999
    while True:
        time.sleep(sleepTime)
        status = checktemps(status)
        print("Sleeping for " + str(sleepTime))
if __name__ == '__main__':
    main()
