Moved the project to asyncio

This commit is contained in:
2026-02-28 17:48:01 +01:00
parent 45ab7d2761
commit cdf3b983bc
5 changed files with 429 additions and 283 deletions

View File

@@ -11,29 +11,31 @@ from dataclasses import dataclass
AlchemyBase = declarative_base() AlchemyBase = declarative_base()
# DATABASE "CLASSESS"-------------------------------------------- # DATABASE "CLASSESS"--------------------------------------------
def sensorsqldata(table_name: Annotated[str, "Name of the table"]): # class idracSQLTable(AlchemyBase):
# def __init__(self, inputData: snmpPyIDRACData):
# __table_args__ = {'extend_existing': True}
class SensorSQLDataClass(AlchemyBase): # __tablename__ = table_name
__table_args__ = {'extend_existing': True}
__tablename__ = table_name # id = Column(MEDIUMINT(unsigned=True), primary_key=True, autoincrement=True)
# time_stamp = Column(
id = Column(MEDIUMINT(unsigned=True), primary_key=True, autoincrement=True) # TIMESTAMP,
time_stamp = Column( # server_default=text("CURRENT_TIMESTAMP"),
TIMESTAMP, # server_onupdate=text("CURRENT_TIMESTAMP"),
server_default=text("CURRENT_TIMESTAMP"), # nullable=False,
server_onupdate=text("CURRENT_TIMESTAMP"), # )
nullable=False,
) # inputData.hostname = Column(TEXT)
TEMP = Column(TINYINT) # inputData.powerDrawPSU1 = Column(Float)
TEMP = Column(TEXT) # inputData.powerDrawPSU2 = Column(Float, nullable=True)
TEMP = Column(Float) # inputData.voltagePSU1 = Column(Float)
TEMP = Column(Float) # inputData.voltagePSU2 = Column(Float, nullable=True)
TEMP = Column(Float, nullable=True) # inputData.inletTemp = Column(Float)
TEMP = Column(Float, nullable=True) # inputData.exhaustTemp = Column(Float)
TEMP = Column(Float, nullable=True) # inputData.cpu1Temp = Column(Float)
# inputData.cpu2Temp = Column(Float, nullable=True)
return SensorSQLDataClass # inputData.uptimeH = Column(Float)
# inputData.uptimeD = Column(Float, nullable=True)
# Custom-------------------------------------------- # Custom--------------------------------------------
@@ -115,5 +117,37 @@ class snmpPyIDRACData():
) )
@dataclass @dataclass
class idracFanStatus: class snmpPyCiscoData():
fans: Dict[str, int] # name/index -> rpm """Dataclass for snmp data"""
hostname: str
powerDrawPSU1: int
voltagePSU1: int
inletTemp: float
exhaustTemp: float
cpu1Temp: float
uptimeH: float
# optional fields
uptimeD: float | None = None
cpu2Temp: float | None = None
powerDrawPSU2: int | None = None
voltagePSU2: int | None = None
def __str__(self):
return (
f"{self.hostname}\n"
f"PSU1 {self.powerDrawPSU1} Watts\n"
f"PSU2 {self.powerDrawPSU2} Watts\n"
f"PSU1 {self.voltagePSU1} Volts\n"
f"PSU2 {self.voltagePSU2} Volts\n"
f"Inlet {self.inletTemp} C\n"
f"Exhaust {self.exhaustTemp} C\n"
f"CPU1 {self.cpu1Temp} C\n"
f"CPU2 {self.cpu2Temp} C\n"
f"Uptime {self.uptimeH} Hours\n"
f"Uptime {self.uptimeD} Days"
)
# @dataclass
# class idracFanStatus:
# fans: Dict[str, int] | None = Dict[None, None] # name/index -> rpm

View File

@@ -1,17 +1,21 @@
import influxdb_client, sqlalchemy, random, os import influxdb_client, sqlalchemy, random, os, asyncio
# from sqlmodel import Field, Session, SQLModel, create_engine, select # from sqlmodel import Field, Session, SQLModel, create_engine, select
from sqlalchemy import create_engine, exc # , Column, Integer, String, Numeric # from sqlalchemy import create_engine, exc # , Column, Integer, String, Numeric
# from sqlalchemy.ext.declarative import declarative_base # from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker # from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.asyncio import create_async_engine
from classes import * from classes import *
from typing import Annotated, Final from typing import Annotated, Final
from influxdb_client import InfluxDBClient, Point, WritePrecision from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS, ASYNCHRONOUS, WriteOptions from influxdb_client.client.write_api import SYNCHRONOUS, ASYNCHRONOUS, WriteOptions
# import pymysql
# SNMP
from pysnmp.hlapi.v3arch.asyncio import *
# FluxQL ENV---------------------------------------- # FluxQL ENV----------------------------------------
USEINFLUX: Final[bool] = os.getenv("USEINFLUX", True) USEINFLUX: Final[int] = int(os.getenv("USEINFLUX", 1))
if USEINFLUX: if USEINFLUX:
INFLXDBTOKEN: Final[str] = os.getenv("INFLXDBTOKEN", "123" ) INFLXDBTOKEN: Final[str] = os.getenv("INFLXDBTOKEN", "123" )
INFLUXBCKT: Final[str] = os.getenv("INFLUXBCKT", "SNMPyth") INFLUXBCKT: Final[str] = os.getenv("INFLUXBCKT", "SNMPyth")
@@ -20,110 +24,367 @@ if USEINFLUX:
INFXLUXDB_MEASUEREMENT: Final[str] = os.getenv("INFXLUXDB_MEASUEREMENT", "SNMPyth-containrr") INFXLUXDB_MEASUEREMENT: Final[str] = os.getenv("INFXLUXDB_MEASUEREMENT", "SNMPyth-containrr")
INFLX_SEPARATE_POINTS: Final[float] = float(os.getenv("INFLX_SEPARATE_POINTS", 0.1)) INFLX_SEPARATE_POINTS: Final[float] = float(os.getenv("INFLX_SEPARATE_POINTS", 0.1))
# SQL ENV------------------------------------------- # SQL ENV-------------------------------------------
USESQL: Final[bool] = os.getenv("USESQL", False) USESQL: Final[int] = int(os.getenv("USESQL", 0))
if USESQL: if USESQL:
DBENGINE: Final[str] = os.getenv("DBENGINE", "mysql+pymysql") DBENGINE: Final[str] = os.getenv("DBENGINE", "mysql+asyncmy")
DBADDR: Final[str] = os.getenv("DBADDR", "127.0.0.1") DBADDR: Final[str] = os.getenv("DBADDR", "127.0.0.1")
DBUSR: Final[str] = os.getenv("DBUSR", "root") DBUSR: Final[str] = os.getenv("DBUSR", "root")
DBPWD: Final[str] = os.getenv("DBPWD", "6767") DBPWD: Final[str] = os.getenv("DBPWD", "6767")
DBNAME: Final[str] = os.getenv("DBNAME", "TEMP_SENSR") DBNAME: Final[str] = os.getenv("DBNAME", "TEMP_SENSR")
# SNMP ENV-------------------------------------------
ROUND_PREC: Final[int] = int(os.getenv("ROUND_PREC", 6))
SNMPUSER: Final[str] = os.getenv("SNMPUSER", None)
SNMPPRIVKEY: Final[str] = os.getenv("SNMPPRIVKEY", None)
SNMPAUTHKEY: Final[str] = os.getenv("SNMPAUTHKEY", None)
# Right now I'll only use SHA
# SNMPAUTHPROTO: Final[str] = os.getenv("SNMPAUTHPROTO", "SHA")
# SNMPPRIVPROTO: Final[str] = os.getenv("SNMPPRIVPROTO", "SHA")
SNMPORT: Final[int] = int(os.getenv("SNMPORT", 161))
# Flightchecks------------------------------------------- # Flightchecks-------------------------------------------
# Check if some neccesary ENVs are passed # Check if some neccesary ENVs are passed
if not USEINFLUX and not USESQL: if not USEINFLUX and not USESQL:
raise Exception("No database selected to store the data") raise Exception("No database selected to store the data")
# Check if SNMP ENV are empty
if not SNMPUSER or not SNMPPRIVKEY or not SNMPAUTHKEY:
raise Exception("No SNMP user or/and PrivAuth passed")
# DBprepare------------------------------------------- # Prepare-------------------------------------------
# INFLUX # INFLUX
if USEINFLUX: if USEINFLUX:
fluxdb_client = influxdb_client.InfluxDBClient(url=INFLXDBURL, token=INFLXDBTOKEN, org=INFLUXORG) fluxdb_client = influxdb_client.InfluxDBClient(url=INFLXDBURL, token=INFLXDBTOKEN, org=INFLUXORG)
write_fluxdb_api = fluxdb_client.write_api(write_options=SYNCHRONOUS) write_fluxdb_api = fluxdb_client.write_api(write_options=ASYNCHRONOUS)
query_fluxdb_api = fluxdb_client.query_api() query_fluxdb_api = fluxdb_client.query_api()
else:
fluxdb_client = write_fluxdb_api = query_fluxdb_api = None
# SQL # SQL
if USESQL: if USESQL:
engine = create_engine( engine = create_async_engine(
f"{DBENGINE}://{DBUSR}:{DBPWD}@{DBADDR}/{DBNAME}", f"{DBENGINE}://{DBUSR}:{DBPWD}@{DBADDR}/{DBNAME}",
pool_pre_ping=True, # Check connection liveness before using and if needed, recconect # pool_pre_ping=True, # Check connection liveness before using and if needed, recconect
pool_recycle=3600 # recycle connections older than N (3600 in this case) seconds # pool_recycle=3600, # recycle connections older than N (3600 in this case) seconds
) echo=True,
Session = sessionmaker(bind=engine) )
else:
engine = None
# SNMP
USMUSRDATA = UsmUserData(
userName=SNMPUSER,
authKey=SNMPAUTHKEY,
privKey=SNMPPRIVKEY,
authProtocol=usmHMACSHAAuthProtocol,
privProtocol=usmAesCfb128Protocol,
)
def tempsnsrIntoSQLDB( # DB functions-------------------------------------------
tableInp: Annotated[int, "Name of the table"],
insertData: Annotated[str, "Data to insert"] async def sqlDataWriter(
inpDict: dict
) -> int: ) -> int:
f"""
Insert {DBNAME} data into MariaDB
:tableInp: Name of the table
:return: 0 if succesfull, 1 if rolled back on error, 2 if SQL is not enabled 3 if no such table
"""
if not USESQL: # inputQueue have multiple such Dicts
# {
# "source": "IDRAC",
# "value": returnObj,
# "type": "snmpPyIDRACData"
# }
if engine is None:
return 3
try:
async with engine.begin() as eng:
match inpDict["source"]:
case "CISCO":
await eng.execute(
# changeMeLater
t1.insert(), [{"name": "some name 1"}, {"name": "some name 2"}]
)
case "IDRAC":
await eng.execute(
# changeMeLater
t1.insert(), [{"name": "some name 1"}, {"name": "some name 2"}]
)
case "FANS":
await eng.execute(
# changeMeLater
t1.insert(), [{"name": "some name 1"}, {"name": "some name 2"}]
)
case _:
print(f"No such source of data as {inpDict['source']}")
return 1
except Exception as e:
print(e)
return 2 return 2
# Check if table exists return 0
if not sqlalchemy.inspect(engine).has_table(tableInp):
return 3 # asyncio.sleep(5)
with Session() as session:
try:
sqlData = sensorsqldata(tableInp)
# print("2")
if inpayload:
# print("3")
session.add(sqlData(
data = insertData,
))
# print("4")
session.commit() #Attempt to commit all the records
# print("good")
return 0
except Exception as e:
print(f"Error {e} when sending to mariadb")
session.rollback() #Rollback the changes on error
return 1
def tempsnsrIntoFluxQLDB( async def fluxWriter(
inIdracPayload: Annotated[snmpPyIDRACData, "Payload"] | None = None, inpDict: dict
inCiscoPayload: Annotated[int, "yes"] | None = None
) -> int: ) -> int:
""" """
Insert temperature data into InfluxDB Insert temperature data into InfluxDB
:inpayload: Payload :inputQueue: Asyncio Queue that has what is needed to be sent
:return: 0 if succesfull, 1 if general error, 2 if Influx is not enabled
""" """
if not USEINFLUX: # inputQueue have multiple such Dicts
# {
# "source": "IDRAC",
# "value": returnObj,
# "type": "snmpPyIDRACData"
# }
if write_fluxdb_api is None:
return 2 return 2
# Prep InfluxDB data # Prep InfluxDB data
inflxdb_Data_To_Send = ( inflxdb_Data_To_Send = (
influxdb_client.Point(f"{INFXLUXDB_MEASUEREMENT}") influxdb_client.Point(f"{INFXLUXDB_MEASUEREMENT}")
.tag("PLACE", inpayload.name) .tag("PLACE", inpayload.name)
.tag("TEMP", sensorIDinp) .tag("TEMP", sensorIDinp)
.tag("TEMP", whatTheSensor) .tag("TEMP", whatTheSensor)
.field("TEMP", inpayload.temp) .field("TEMP", inpayload.temp)
.field("TEMP", inpayload.humid) .field("TEMP", inpayload.humid)
.field("TEMP", inpayload.hicc) .field("TEMP", inpayload.hicc)
.field("TEMP", inpayload.presss) .field("TEMP", inpayload.presss)
.field("TEMP", inpayload.alttd) .field("TEMP", inpayload.alttd)
) )
# print(write_fluxdb_api.write(bucket=INFLUXBCKT, org=INFLUXORG, record=inflxdb_Data_To_Send)) try:
# if write_fluxdb_api.write(bucket=INFLUXBCKT, org=INFLUXORG, record=inflxdb_Data_To_Send) == None: write_fluxdb_api.write(bucket=INFLUXBCKT, org=INFLUXORG, record=inflxdb_Data_To_Send)
except Exception as e:
if write_fluxdb_api.write(bucket=INFLUXBCKT, org=INFLUXORG, record=inflxdb_Data_To_Send): print(e)
# return {"STATUS": "succesfully inserted to InfluxDB"}
print("0")
return 0
else:
print("1")
return 1 return 1
return 0
# return {"STATUS": "succesfully inserted to InfluxDB"}
async def ALLdbWriter(inputQueue: asyncio.Queue) -> None:
while True:
qu = await inputQueue.get()
try:
if USESQL:
sqlResult = await sqlDataWriter(qu)
match sqlResult:
case 1:
print("Wrong source")
case 2:
print("Error inserting to database")
case 3:
print("No engine defined")
case _:
print("nice")
if USEINFLUX:
fluxResult = await fluxWriter(qu)
match fluxResult:
case 1:
print("could not insert")
case 2:
print("Error with initializing Inxlux variables")
case _:
print("nice")
except Exception as e:
print(e)
finally:
inputQueue.task_done()
# SNMP functions-------------------------------------------
# Helper functions
# def wattageCalc(amperageInp: float, voltageInp: float) -> float:
# return amperageInp * voltageInp
# Cisco
async def ciscoPoolRemote(remoteIP: str, queueToInsrt: asyncio.Queue):
snmpEngine = SnmpEngine()
iterator = get_cmd(
snmpEngine,
USMUSRDATA,
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
# Get Hostname
ObjectType(ObjectIdentity(".1.3.6.1.2.1.1.5.0")),
#
)
print(iterator)
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 varBind in varBinds:
print(" = ".join([x.prettyPrint() for x in varBind]))
snmpEngine.close_dispatcher()
returObj = snmpPyCiscoData()
returObj(
hostname="X"
)
returnDict = {
"source": "CISCO",
"value": returObj,
"type": "snmpPyCiscoData"
}
# return returnObj
queueToInsrt.put(returnDict)
# IDRAC get data for snmpPyIDRACData class
async def idracPoolRemote_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)
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")), #5
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.3")), #7
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #8
# Uptime in seconds
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #9
)
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()}")
# for element in varBinds:
# print(element)
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(varBinds[3][-1]) / 1000), ROUND_PREC),
powerDrawPSU2=round((int(varBinds[2][-1]) / 10) * (int(varBinds[4][-1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 power draw in Watts
voltagePSU1=round((int(varBinds[3][-1]) / 1000), ROUND_PREC),
voltagePSU2=round((int(varBinds[4][-1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 voltages
inletTemp=int(varBinds[5][-1] / 10),
exhaustTemp=int(varBinds[6][-1] / 10),
# Inlet and Exhaust temp
cpu1Temp=int(varBinds[7][-1] / 10),
cpu2Temp=int(varBinds[8][-1] / 10),
# CPU1 and CPU2 temp
uptimeH=round(((int(varBinds[9][-1]) / 60) / 60), ROUND_PREC),
# seconds->minutes->hours
uptimeD=round((((int(varBinds[9][-1]) / 60) / 60) / 24), ROUND_PREC)
# seconds->minutes->hours->days
)
returnDict = {
"source": "IDRAC",
"value": returnObj,
"type": "snmpPyIDRACData"
}
# return returnObj
queueToInsrt.put(returnDict)
# IDRAC get FAN data
async def walk_column_v3(snmpEngine, remoteIP: str, base_oid: str) -> dict:
rows = {}
async for errInd, errStat, errIdx, varBinds in walk_cmd(
snmpEngine,
# CommunityData("public", mpModel=0),
USMUSRDATA,
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
ObjectType(ObjectIdentity(base_oid)),
lexicographicMode=False,
):
if errInd:
raise RuntimeError(errInd)
if errStat:
raise RuntimeError(errStat.prettyPrint())
for oid, val in varBinds:
# index is typically the last sub-identifier
idx = int(oid.prettyPrint().split(".")[-1])
rows[idx] = val.prettyPrint()
return rows
async def idracPoolRemoteFAN_v3(remoteIP: str, queueToInsrt: asyncio.Queue) -> dict:
snmpEngine = SnmpEngine()
rpm_oid = "1.3.6.1.4.1.674.10892.5.4.700.12.1.6"
name_oid = "1.3.6.1.4.1.674.10892.5.4.700.12.1.19"
rpms, names = await asyncio.gather(
walk_column_v3(snmpEngine, remoteIP, rpm_oid),
walk_column_v3(snmpEngine, remoteIP, name_oid),
)
snmpEngine.close_dispatcher()
# merge by index
out = {}
for idx, rpm in rpms.items():
out[idx] = {"rpm": rpm, "name": names.get(idx).split(".")[2]}
returnDict = {
"source": "FANS",
"value": out,
"type": "Dict"
}

View File

@@ -9,28 +9,15 @@ from funct import *
from classes import * from classes import *
# Program ENV--------------------------------------- # Program ENV---------------------------------------
ROUND_PREC: Final[int] = os.getenv("ROUND_PREC", 6)
IDRAC_HOST_LIST: Final[list] = os.getenv("IDRAC_HOST_LIST").split(";") IDRAC_HOST_LIST: Final[list] = os.getenv("IDRAC_HOST_LIST").split(";")
CISCO_HOST_LIST: Final[list] = os.getenv("CISCO_HOST_LIST").split(";") CISCO_HOST_LIST: Final[list] = os.getenv("CISCO_HOST_LIST").split(";")
SNMPUSER: Final[str] = os.getenv("SNMPUSER", None)
SNMPPRIVKEY: Final[str] = os.getenv("SNMPPRIVKEY", None)
SNMPAUTHKEY: Final[str] = os.getenv("SNMPAUTHKEY", None)
# Right now I'll only use SHA
# SNMPAUTHPROTO: Final[str] = os.getenv("SNMPAUTHPROTO", "SHA")
# SNMPPRIVPROTO: Final[str] = os.getenv("SNMPPRIVPROTO", "SHA")
SNMPORT: Final[int] = os.getenv("SNMPORT", 161)
# Flightchecks------------------------------------------- # Flightchecks-------------------------------------------
# Check if SNMP ENV are empty
if not SNMPUSER or not SNMPPRIVKEY or not SNMPAUTHKEY:
raise Exception("No SNMP user or/and PrivAuth passed")
# 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 IDRAC_HOST_LIST and not CISCO_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 idracHost in IDRAC_HOST_LIST:
try: try:
@@ -48,186 +35,54 @@ for ciscoHost in CISCO_HOST_LIST:
# Code------------------------------------------- # Code-------------------------------------------
# Helper functions async def main():
def wattageCalc(amperageInp: float, voltageInp: float) -> float:
return amperageInp * voltageInp # Queues for storing states that a database needs to insert
# idracQueue = asyncio.Queue()
# ciscoQueue = asyncio.Queue()
# fanQueue = asyncio.Queue()
mainQueue(maxsize=225)
while True:
tasks = []
# IDRAC part
async with asyncio.TaskGroup() as tg:
for IdracIP in IDRAC_HOST_LIST:
tasks.append(tg.create_task(idracPoolRemote_v3(IdracIP, mainQueue)))
# tasks.append(tg.create_task(idracPoolRemoteFAN_v3(IdracIP, mainQueue)))
# for CiscoIP in CISCO_HOST_LIST:
# tasks.append(tg.create_task(ciscoPoolRemote(CiscoIP, mainQueue)))
sleep(20)
async def ciscoPoolRemote(remoteIP: str):
snmpEngine = SnmpEngine()
iterator = get_cmd( # yes = asyncio.run(idracPoolRemote_v3("192.168.20.7"))
snmpEngine, # fan = asyncio.run(idracPoolRemoteFAN_v3("192.168.20.7"))
UsmUserData(
userName=SNMPUSER,
authKey=SNMPPRIVKEY,
privKey=SNMPAUTHKEY,
authProtocol=usmHMACSHAAuthProtocol,
privProtocol=usmHMACSHAAuthProtocol,
),
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
# Get Hostname
ObjectType(ObjectIdentity(".1.3.6.1.2.1.1.5.0")),
#
)
print(iterator) # print("fanThingy")
# # print(fan)
# for thing in fan:
# print(fan[thing]["name"], fan[thing]["rpm"])
# for thing in fan:
# print(thing)
errorIndication, errorStatus, errorIndex, varBinds = await iterator # print("for loop")
# print(yes)
if errorIndication: # print("End of code")
print(errorIndication)
elif errorStatus: if __name__ == "__main__":
print(
"{} at {}".format(
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or "?",
)
)
else:
for varBind in varBinds:
print(" = ".join([x.prettyPrint() for x in varBind]))
snmpEngine.close_dispatcher()
async def idracPoolRemote(remoteIP: str):
snmpEngine = SnmpEngine()
iterator = get_cmd(
snmpEngine,
UsmUserData(
userName=SNMPUSER,
authKey=SNMPPRIVKEY,
privKey=SNMPAUTHKEY,
authProtocol=usmHMACSHAAuthProtocol,
privProtocol=usmHMACSHAAuthProtocol,
),
await UdpTransportTarget.create((remoteIP, SNMPORT)),
ContextData(),
# Get Hostname
ObjectType(ObjectIdentity(".1.3.6.1.2.1.1.5.0")),
#
)
print(iterator)
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 varBind in varBinds:
print(" = ".join([x.prettyPrint() for x in varBind]))
snmpEngine.close_dispatcher()
async def idracPoolRemote_v1(remoteIP: str): loop = asyncio.get_event_loop()
snmpEngine = SnmpEngine() task = loop.create_task(main())
iterator = get_cmd(
snmpEngine,
# SNMPv1 = mpModel=0 (SNMPv2c would be mpModel=1)
CommunityData("public", mpModel=0),
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")), #5
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.3")), #7
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.4.700.20.1.6.1.4")), #8
# Uptime in seconds
ObjectType(ObjectIdentity(".1.3.6.1.4.1.674.10892.5.2.5.0")), #9
)
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()}")
# for element in varBinds:
# print(element)
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(varBinds[3][-1]) / 1000), ROUND_PREC),
powerDrawPSU2=round((int(varBinds[2][-1]) / 10) * (int(varBinds[4][-1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 power draw in Watts
voltagePSU1=round((int(varBinds[3][-1]) / 1000), ROUND_PREC),
voltagePSU2=round((int(varBinds[4][-1]) / 1000), ROUND_PREC),
# PSU1 and PSU2 voltages
inletTemp=int(varBinds[5][-1] / 10),
exhaustTemp=int(varBinds[6][-1] / 10),
# Inlet and Exhaust temp
cpu1Temp=int(varBinds[7][-1] / 10),
cpu2Temp=int(varBinds[8][-1] / 10),
# CPU1 and CPU2 temp
uptimeH=round(((int(varBinds[9][-1]) / 60) / 60), ROUND_PREC),
# seconds->minutes->hours
uptimeD=round((((int(varBinds[9][-1]) / 60) / 60) / 24), ROUND_PREC)
# seconds->minutes->hours->days
)
return returnObj
yes = asyncio.run(idracPoolRemote_v1("192.168.20.7"))
print("for loop")
print(yes)
x = idracFanStatus(6)
# print(yes.hostname)
# print(yes.powerDrawPSU1)
# print(yes.powerDrawPSU2)
# print(yes.voltagePSU1)
# print(yes.voltagePSU2)
# print(yes.inletTemp)
# print(yes.exhaustTemp)
# print(yes.uptimeH)
# print(yes.uptimeD)
# poolRemote(HOST_LIST[0]) # poolRemote(HOST_LIST[0])
# while True: # while True:
@@ -239,12 +94,6 @@ x = idracFanStatus(6)
# await asyncio.sleep(20) # await asyncio.sleep(20)
# Create connections for MySQL and InfluxDB # Create connections for MySQL and InfluxDB
# functions for inserting data into two DBs # functions for inserting data into two DBs

View File

@@ -1,11 +1,13 @@
# mysql-connector-python==9.2.0 # mysql-connector-python==9.2.0
PyMySQL==1.1.1 PyMySQL==1.1.1
sqlmodel==0.0.24 sqlmodel==0.0.24
sqlalchemy[asyncio]
pydantic==2.10.6 pydantic==2.10.6
pydantic_core==2.27.2 pydantic_core==2.27.2
annotated-types==0.7.0 annotated-types==0.7.0
typing==3.7.4.3 typing==3.7.4.3
pysnmp==7.1.22 pysnmp==7.1.22
cryptography==46.0.5
# requests==2.32.3 # requests==2.32.3
influxdb-client==1.49.0 influxdb-client==1.49.0
# influxdb3-python==0.18.0 # influxdb3-python==0.18.0

0
cont/sqlFunct.py Normal file
View File