From 85a14f4fa07c32bc2184db0b491ab59f03f5057c Mon Sep 17 00:00:00 2001 From: Antoine Van Elstraete Date: Sun, 24 Aug 2025 15:36:26 +0200 Subject: [PATCH] Update PySNMP (Slim is now deprecated) --- requirements.txt | 3 ++- snmp2mqtt.py | 43 +++++++++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/requirements.txt b/requirements.txt index 4de116f..0a0234a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,8 @@ # Install with: pip install -r requirements.txt # SNMP library for asynchronous SNMP operations -pysnmp>=6.0.0 +# Note: pysnmp 7.x uses a new API structure (no more Slim class) +pysnmp>=7.0.0 # MQTT client library for connecting to MQTT brokers paho-mqtt>=1.6.0 diff --git a/snmp2mqtt.py b/snmp2mqtt.py index ed36c9d..d48481c 100755 --- a/snmp2mqtt.py +++ b/snmp2mqtt.py @@ -1,7 +1,9 @@ #!/bin/env python3 import asyncio -from pysnmp.hlapi.asyncio.slim import Slim -from pysnmp.smi.rfc1902 import ObjectIdentity, ObjectType +from pysnmp.hlapi.asyncio import ( + get_cmd, CommunityData, UdpTransportTarget, ContextData, + SnmpEngine, ObjectIdentity, ObjectType +) import logging import random from paho.mqtt import client as mqtt_client @@ -204,25 +206,34 @@ def publish(topic, client, data, retain, qos): async def get_snmp(req): + """Asynchronously retrieve SNMP data from device using new pysnmp API""" data = {} + + # Create SNMP engine and transport target + snmpEngine = SnmpEngine() + authData = CommunityData(req["snmp_community"]) + transportTarget = UdpTransportTarget((req["ip"], 161)) + contextData = ContextData() + for oid in req["oids"]: - with Slim(1) as slim: - errorIndication, errorStatus, errorIndex, varBinds = await slim.get( - req["snmp_community"], - req["ip"], - 161, - ObjectType(ObjectIdentity(oid["oid"])), + try: + # Perform async SNMP GET operation + errorIndication, errorStatus, errorIndex, varBinds = await get_cmd( + snmpEngine, + authData, + transportTarget, + contextData, + ObjectType(ObjectIdentity(oid["oid"])) ) if errorIndication: - logging.error(errorIndication) + logging.error(f"{req['device_name']} SNMP error indication: {errorIndication}") + continue elif errorStatus: logging.error( - "{} at {}".format( - errorStatus.prettyPrint(), - errorIndex and varBinds[int(errorIndex) - 1][0] or "?", - ) + f"{req['device_name']} SNMP error status: {errorStatus.prettyPrint()} at {errorIndex and varBinds[int(errorIndex) - 1][0] or '?'}" ) + continue else: for varBind in varBinds: logging.debug(f"{req['device_name']} {oid['name']} => {oid['type'](varBind[1])}") @@ -233,7 +244,11 @@ async def get_snmp(req): data.update({oid["name"]: "OFF"}) else: data.update({oid["name"]: oid["type"](varBind[1])}) - logging.debug(f"JSON : {json.dumps(data)}") + except Exception as e: + logging.error(f"{req['device_name']} Exception getting OID {oid['oid']}: {e}") + continue + + logging.debug(f"{req['device_name']} JSON : {json.dumps(data)}") return data