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: # Only include main OID in details, not temperature details = {str(var_binds[0][0]): str(var_binds[0][1])} # Extract temperature if configured (second OID in response) if temperature_oid and len(var_binds) >= 2: try: details["temperature"] = int(var_binds[1][1]) except (ValueError, TypeError): pass # Ignore if not a valid integer 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 )