From d3d1ddb6e044c8b01c05ed75d38c9a2aa02abfbf Mon Sep 17 00:00:00 2001 From: adamus1red Date: Fri, 13 May 2022 15:26:21 +0100 Subject: [PATCH] Add inital IPMItools functionality created `getIPMIdata()` based on existing `getHPASMData()`. Leverages ipmitool to gather power usage data. --- snmp/powermon-snmp.py | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/snmp/powermon-snmp.py b/snmp/powermon-snmp.py index d9f179c1b..e9c0b451d 100755 --- a/snmp/powermon-snmp.py +++ b/snmp/powermon-snmp.py @@ -62,8 +62,9 @@ # 20210204 - v1.2 - added top-level reading, librenms option # 20210205 - v1.3 - added cents per kWh # 20210205 - v1.4 - improvement to UI +# 20220513 - v1.5 - Add inital IPMItool method -version = 1.4 +version = 1.5 ### Libraries @@ -97,7 +98,7 @@ + " [-m|--method ] [-N|--no-librenms] [-p|--pretty]" + " [-v|--verbose] [-w|--warnings] | -l|--list-methods | -h|--help" ) -methods = ["sensors", "hpasmcli"] +methods = ["sensors", "hpasmcli", "ipmitool"] # costPerkWh = 0.15 # <<<< CHANGE ### General functions @@ -138,6 +139,10 @@ def getData(method): elif method == "hpasmcli": data = getHPASMData() + + elif method == "ipmitool": + data = getIPMIdata() + else: usageError("You must specify a method.") @@ -289,6 +294,43 @@ def getHPASMData(): return hdata +def getIPMIdata(): + global error, errorString + error = 2 + errorString = "No power sensor found" + + exe = shutil.which("ipmitool") + # if not os.access(candidate, os.W_OK): + cmd = [exe, "dcmi", "power", "reading"] + warningMsg("ipmitool only runs as root") + + try: + output = subprocess.run( + cmd, capture_output=True, check=True, text=True, timeout=2 + ) + + except subprocess.CalledProcessError as e: + errorMsg(str(e) + ": " + str(e.stdout).strip("\n")) + sys.exit(1) + + psu_reading = "^\s+Instantaneous power reading:\s+" + + rawdata = str(output.stdout).replace("\t", " ").replace("\n ", "\n").split("\n") + + hdata = {} + hdata["psu"] = {} # Init PSU data structure + hdata["psu"][0] = {} # Only one value is returned. + + for line in rawdata: + if re.match(psu_reading, line): + verboseMsg("found power meter reading: " + line) + junk, meter_reading = line.split(":", 1) + hdata["psu"][0]["reading"] = psu_reading.replace("Watts", "").strip() + + return hdata + + + # Argument Parsing try: