import asyncio import time from pysnmp.hlapi.v1arch.asyncio import ( Slim, ObjectIdentity, ObjectType, ) from .base import BaseChecker, CheckResult class SnmpChecker(BaseChecker): def check(self) -> CheckResult: return asyncio.run(self._async_check()) async def _async_check(self) -> CheckResult: host = self.config["host"] port = self.config.get("port", 161) community = self.config.get("community", "public") oid = self.config.get("oid", "1.3.6.1.2.1.1.1.0") # sysDescr temperature_oid = self.config.get("temperature_oid") timeout_val = self.config.get("timeout", 5) start = time.time() try: with Slim() as slim: # Build list of OIDs to query oids = [ObjectType(ObjectIdentity(oid))] if temperature_oid: oids.append(ObjectType(ObjectIdentity(temperature_oid))) error_indication, error_status, error_index, var_binds = await slim.get( community, host, port, *oids, timeout=timeout_val, retries=1 ) response_time = (time.time() - start) * 1000 # ms if error_indication: return CheckResult( success=False, message=f"SNMP error: {error_indication}", response_time=None ) elif error_status: return CheckResult( success=False, message=f"SNMP error: {error_status.prettyPrint()}", response_time=None ) else: details = {str(oid): str(val) for oid, val in var_binds} # Extract temperature if configured if temperature_oid: for oid_key, val in var_binds: if str(oid_key) == temperature_oid: try: details["temperature"] = int(val) except (ValueError, TypeError): pass # Ignore if not a valid integer break return CheckResult( success=True, message="SNMP response OK", response_time=response_time, details=details ) except Exception as e: return CheckResult( success=False, message=f"SNMP error: {e}", response_time=None )