A big rework is needed

A rework of exhaust temp, everything for PSU2 and
CPU2 temp is needed.

On R430 there is only Inlet Temp sensor
which crashes the program.

Also if there is only one cpu installed then the program
will also crash as there is no OID for cpu2

Adding a try: for above mentioned OIDs and then
combining output into one Queue entry should fix it
This commit is contained in:
2026-03-01 21:29:28 +01:00
parent 583a72ac98
commit d3d274b2a1
4 changed files with 190 additions and 29 deletions

View File

@@ -99,6 +99,7 @@ class snmpPyIDRACData():
uptimeD: float | None = None uptimeD: float | None = None
cpu2Temp: float | None = None cpu2Temp: float | None = None
powerDrawPSU2: int | None = None powerDrawPSU2: int | None = None
powerDrawBoard: int | None = None
voltagePSU2: int | None = None voltagePSU2: int | None = None
@@ -107,6 +108,7 @@ class snmpPyIDRACData():
f"{self.hostname}\n" f"{self.hostname}\n"
f"PSU1 {self.powerDrawPSU1} Watts\n" f"PSU1 {self.powerDrawPSU1} Watts\n"
f"PSU2 {self.powerDrawPSU2} Watts\n" f"PSU2 {self.powerDrawPSU2} Watts\n"
f"Board {self.powerDrawBoard} Watts\n"
f"PSU1 {self.voltagePSU1} Volts\n" f"PSU1 {self.voltagePSU1} Volts\n"
f"PSU2 {self.voltagePSU2} Volts\n" f"PSU2 {self.voltagePSU2} Volts\n"
f"Inlet {self.inletTemp} C\n" f"Inlet {self.inletTemp} C\n"

View File

@@ -263,8 +263,8 @@ async def ciscoPoolRemote(remoteIP: str, queueToInsrt: asyncio.Queue):
# return returnObj # return returnObj
await queueToInsrt.put(returnDict) await queueToInsrt.put(returnDict)
# IDRAC get data for snmpPyIDRACData class # IDRAC78 get data for snmpPyIDRACData class
async def idracPoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue): async def idrac7_8PoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
snmpEngine = SnmpEngine() snmpEngine = SnmpEngine()
iterator = get_cmd( iterator = get_cmd(
@@ -281,17 +281,17 @@ async def idracPoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.1")), #1 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.1")), #1
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.2")), #2 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.2")), #2
# (Volts) # (Volts)
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.31")), #3 # ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.31")), #3
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.32")), #4 # ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.32")), #4
# Get Inlet, Exhaust, CPU1, CPU2 # Get Inlet, Exhaust, CPU1, CPU2
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.1")), #5 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.1")), #3
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.2")), #6 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.2")), #4
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.3")), #7 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.3")), #5
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #8 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #6
# Uptime in seconds # Uptime in seconds
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #9 ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #7
) )
errorIndication, errorStatus, errorIndex, varBinds = await iterator errorIndication, errorStatus, errorIndex, varBinds = await iterator
@@ -309,8 +309,54 @@ async def idracPoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
for oid, val in varBinds: for oid, val in varBinds:
print(f"{oid.prettyPrint()} = {val.prettyPrint()}") print(f"{oid.prettyPrint()} = {val.prettyPrint()}")
# for element in varBinds: iterator2 = get_cmd(
# print(element) snmpEngine,
# SNMPv1 = mpModel=0 (SNMPv2c would be mpModel=1)
# CommunityData("public", mpModel=0),
USMUSRDATA,
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
# Hostname (sysName.0)
ObjectType(ObjectIdentity(".1.3.6.1.2.1.1.5.0")), #0
# PSU1 powerDraw and PSU2 powerDraw (Amps)
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.1")), #1
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.2")), #2
# (Volts)
# ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.31")), #3
# ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.32")), #4
# Get Inlet, Exhaust, CPU1, CPU2
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.1")), #3
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.2")), #4
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.3")), #5
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #6
# Uptime in seconds
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #7
)
errorIndication2, errorStatus2, errorIndex2, varBinds2 = await iterator2
if errorIndication2:
print(errorIndication2)
elif errorStatus2:
print(
"{} at {}".format(
errorStatus2.prettyPrint(),
errorIndex2 and varBinds[int(errorIndex2) - 1][0] or "?",
)
)
else:
for oid, val in varBinds2:
print(f"{oid.prettyPrint()} = {val.prettyPrint()}")
voltResult = await walk_column_v3(snmpEngine, remoteIP, ".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1")
voltList = []
for thing in voltResult:
voltList.append(voltResult[thing])
snmpEngine.close_dispatcher() snmpEngine.close_dispatcher()
# print(varBinds[1][-1]) # print(varBinds[1][-1])
@@ -319,27 +365,27 @@ async def idracPoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
hostname=varBinds[0][-1], hostname=varBinds[0][-1],
# Hostname # Hostname
powerDrawPSU1=round((int(varBinds[1][-1]) / 10) * (int(varBinds[3][-1]) / 1000), ROUND_PREC), powerDrawPSU1=round((int(varBinds[1][-1]) / 10) * (int(voltList[0]) / 1000), ROUND_PREC),
powerDrawPSU2=round((int(varBinds[2][-1]) / 10) * (int(varBinds[4][-1]) / 1000), ROUND_PREC), powerDrawPSU2=round((int(varBinds[2][-1]) / 10) * (int(voltList[1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 power draw in Watts # PSU1 and PSU2 power draw in Watts
voltagePSU1=round((int(varBinds[3][-1]) / 1000), ROUND_PREC), voltagePSU1=round((int(voltList[0]) / 1000), ROUND_PREC),
voltagePSU2=round((int(varBinds[4][-1]) / 1000), ROUND_PREC), voltagePSU2=round((int(voltList[1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 voltages # PSU1 and PSU2 voltages
inletTemp=int(varBinds[5][-1] / 10), inletTemp=int(varBinds[3][-1] / 10),
exhaustTemp=int(varBinds[6][-1] / 10), exhaustTemp=int(varBinds[4][-1] / 10),
# Inlet and Exhaust temp # Inlet and Exhaust temp
cpu1Temp=int(varBinds[7][-1] / 10), cpu1Temp=int(varBinds[5][-1] / 10),
cpu2Temp=int(varBinds[8][-1] / 10), cpu2Temp=int(varBinds[6][-1] / 10),
# CPU1 and CPU2 temp # CPU1 and CPU2 temp
uptimeS=int(varBinds[9][-1]), uptimeS=int(varBinds[7][-1]),
# seconds # seconds
uptimeH=round(((int(varBinds[9][-1]) / 60) / 60), ROUND_PREC), uptimeH=round(((int(varBinds[7][-1]) / 60) / 60), ROUND_PREC),
# seconds->minutes->hours # seconds->minutes->hours
uptimeD=round((((int(varBinds[9][-1]) / 60) / 60) / 24), ROUND_PREC) uptimeD=round((((int(varBinds[7][-1]) / 60) / 60) / 24), ROUND_PREC)
# seconds->minutes->hours->days # seconds->minutes->hours->days
) )
@@ -352,6 +398,110 @@ async def idracPoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
await queueToInsrt.put(returnDict) await queueToInsrt.put(returnDict)
# IDRAC get data for snmpPyIDRACData class
async def idrac9PoolRemote_v3(remoteIP: str, queueToInsrt: asyncio.Queue):
snmpEngine = SnmpEngine()
iterator = get_cmd(
snmpEngine,
# SNMPv1 = mpModel=0 (SNMPv2c would be mpModel=1)
# CommunityData("public", mpModel=0),
USMUSRDATA,
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
# Hostname (sysName.0)
ObjectType(ObjectIdentity(".1.3.6.1.2.1.1.5.0")), #0
# PSU1 powerDraw and PSU2 powerDraw (Amps)
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.1")), #1
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.2")), #2
# (Volts) nevermid, do not querry
# ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.33")), #3
# ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1.34")), #4
# Get Inlet, Exhaust, CPU1, CPU2
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.3")), #3
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #4
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.1")), #5
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.2")), #6
# Uptime in seconds
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #7
# Raw board power draw
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.600.30.1.6.1.3")), #8
)
errorIndication, errorStatus, errorIndex, varBinds = await iterator
if errorIndication:
print(errorIndication)
elif errorStatus:
print(
"{} at {}".format(
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or "?",
)
)
else:
for oid, val in varBinds:
print(f"{oid.prettyPrint()} = {val.prettyPrint()}")
# .1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1
voltResult = await walk_column_v3(snmpEngine, remoteIP, ".1.3.6.1.4.1.674.10892.5.4.600.20.1.6.1")
voltList = []
for thing in voltResult:
voltList.append(voltResult[thing])
snmpEngine.close_dispatcher()
# print(varBinds[1][-1])
# print(type(varBinds[1][-1]))
returnObj = snmpPyIDRACData(
hostname=varBinds[0][-1],
# Hostname
powerDrawPSU1=round((int(varBinds[1][-1]) / 10) * (int(voltList[0]) / 1000), ROUND_PREC),
powerDrawPSU2=round((int(varBinds[2][-1]) / 10) * (int(voltList[1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 power draw in Watts
# Total board power consumption
powerDrawBoard=int(varBinds[8][-1]),
voltagePSU1=round((int(voltList[0]) / 1000), ROUND_PREC),
voltagePSU2=round((int(voltList[1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 voltages
inletTemp=int(varBinds[3][-1] / 10),
exhaustTemp=int(varBinds[4][-1] / 10),
# Inlet and Exhaust temp
cpu1Temp=int(varBinds[5][-1] / 10),
cpu2Temp=int(varBinds[6][-1] / 10),
# CPU1 and CPU2 temp
uptimeS=int(varBinds[7][-1]),
# seconds
uptimeH=round(((int(varBinds[7][-1]) / 60) / 60), ROUND_PREC),
# seconds->minutes->hours
uptimeD=round((((int(varBinds[7][-1]) / 60) / 60) / 24), ROUND_PREC)
# seconds->minutes->hours->days
)
returnDict = {
"source": "IDRAC",
"value": returnObj,
"type": "snmpPyIDRACData"
}
# return returnObj
await queueToInsrt.put(returnDict)
# IDRAC get FAN data # IDRAC get FAN data
async def walk_column_v3(snmpEngine, remoteIP: str, base_oid: str) -> dict: async def walk_column_v3(snmpEngine, remoteIP: str, base_oid: str) -> dict:
rows = {} rows = {}

View File

@@ -10,7 +10,8 @@ from classes import *
# Program ENV--------------------------------------- # Program ENV---------------------------------------
try: try:
IDRAC_HOST_LIST: Final[list] = os.getenv("IDRAC_HOST_LIST", None).split(";") IDRAC78_HOST_LIST: Final[list] = os.getenv("IDRAC78_HOST_LIST", None).split(";")
IDRAC9_HOST_LIST: Final[list] = os.getenv("IDRAC9_HOST_LIST", None).split(";")
CISCO_HOST_LIST: Final[list] = os.getenv("CISCO_HOST_LIST", None).split(";") CISCO_HOST_LIST: Final[list] = os.getenv("CISCO_HOST_LIST", None).split(";")
except: except:
raise Exception("No IDRAC hosts variable") raise Exception("No IDRAC hosts variable")
@@ -19,19 +20,24 @@ except:
# Flightchecks------------------------------------------- # Flightchecks-------------------------------------------
# if HOST_LIST empty, raise Exception No hosts passed # if HOST_LIST empty, raise Exception No hosts passed
if not IDRAC_HOST_LIST and not CISCO_HOST_LIST: if not IDRAC78_HOST_LIST and not CISCO_HOST_LIST and not IDRAC9_HOST_LIST:
raise Exception("No hosts passed\nExiting...") raise Exception("No hosts passed\nExiting...")
# for host in HOST_LIST check if valid IP and create a list with strings # for host in HOST_LIST check if valid IP and create a list with strings
for idracHost in IDRAC_HOST_LIST: for idrac78Host in IDRAC78_HOST_LIST:
try: try:
ip = str(ipaddress.IPv4Address(idracHost)) ip = str(ipaddress.IPv4Address(idrac78Host))
except ValueError: except ValueError:
raise Exception(f" IP {ip} for IDRAC devices is invalid.\nExiting...") raise Exception(f" IP {ip} for IDRAC7/8 devices is invalid.\nExiting...")
for ciscoHost in CISCO_HOST_LIST: for ciscoHost in CISCO_HOST_LIST:
try: try:
ip = str(ipaddress.IPv4Address(ciscoHost)) ip = str(ipaddress.IPv4Address(ciscoHost))
except ValueError: except ValueError:
raise Exception(f" IP {ip} for Cisco devices is invalid.\nExiting...") raise Exception(f" IP {ip} for Cisco devices is invalid.\nExiting...")
for idrac9Host in IDRAC9_HOST_LIST:
try:
ip = str(ipaddress.IPv4Address(idrac9Host))
except ValueError:
raise Exception(f" IP {ip} for IDRAC9 devices is invalid.\nExiting...")
# Done under "Program ENV" on line ~18 # Done under "Program ENV" on line ~18
@@ -52,8 +58,10 @@ async def main():
# IDRAC part # IDRAC part
async with asyncio.TaskGroup() as tg: async with asyncio.TaskGroup() as tg:
for IdracIP in IDRAC_HOST_LIST: for Idrac78IP in IDRAC78_HOST_LIST:
tg.create_task(idracPoolRemote_v3(IdracIP, mainQueue)) tg.create_task(idrac7_8PoolRemote_v3(Idrac78IP, mainQueue))
for Idrac9IP in IDRAC9_HOST_LIST:
tg.create_task(idrac9PoolRemote_v3(Idrac9IP, mainQueue))
# FANS # FANS
# tg.create_task(idracPoolRemoteFAN_v3(IdracIP, mainQueue)) # tg.create_task(idracPoolRemoteFAN_v3(IdracIP, mainQueue))

View File

@@ -11,6 +11,7 @@ idracMeasurement = Table(
Column("powerDrawPSU1", Numeric(7, 2)), Column("powerDrawPSU1", Numeric(7, 2)),
Column("powerDrawPSU2", Numeric(7, 2)), Column("powerDrawPSU2", Numeric(7, 2)),
Column("powerDrawBoard", Numeric(7, 2)),
Column("voltagePSU1", Numeric(7, 2)), Column("voltagePSU1", Numeric(7, 2)),
Column("voltagePSU2", Numeric(7, 2)), Column("voltagePSU2", Numeric(7, 2)),