async def async_setup_platform(opp, config, async_add_entities, discovery_info=None): """Set up the SNMP sensor.""" name = config.get(CONF_NAME) host = config.get(CONF_HOST) port = config.get(CONF_PORT) community = config.get(CONF_COMMUNITY) baseoid = config.get(CONF_BASEOID) unit = config.get(CONF_UNIT_OF_MEASUREMENT) version = config.get(CONF_VERSION) username = config.get(CONF_USERNAME) authkey = config.get(CONF_AUTH_KEY) authproto = config.get(CONF_AUTH_PROTOCOL) privkey = config.get(CONF_PRIV_KEY) privproto = config.get(CONF_PRIV_PROTOCOL) accept_errors = config.get(CONF_ACCEPT_ERRORS) default_value = config.get(CONF_DEFAULT_VALUE) value_template = config.get(CONF_VALUE_TEMPLATE) if value_template is not None: value_template.opp = opp if version == "3": if not authkey: authproto = "none" if not privkey: privproto = "none" request_args = [ SnmpEngine(), UsmUserData( username, authKey=authkey or None, privKey=privkey or None, authProtocol=getattr(hlapi, MAP_AUTH_PROTOCOLS[authproto]), privProtocol=getattr(hlapi, MAP_PRIV_PROTOCOLS[privproto]), ), UdpTransportTarget((host, port)), ContextData(), ] else: request_args = [ SnmpEngine(), CommunityData(community, mpModel=SNMP_VERSIONS[version]), UdpTransportTarget((host, port)), ContextData(), ] errindication, _, _, _ = await getCmd(*request_args, ObjectType(ObjectIdentity(baseoid))) if errindication and not accept_errors: _LOGGER.error("Please check the details in the configuration file") return data = SnmpData(request_args, baseoid, accept_errors, default_value) async_add_entities([SnmpSensor(data, name, unit, value_template)], True)
def __init__( self, name, host, port, community, baseoid, commandoid, version, username, authkey, authproto, privkey, privproto, payload_on, payload_off, command_payload_on, command_payload_off, ): """Initialize the switch.""" self._name = name self._baseoid = baseoid # Set the command OID to the base OID if command OID is unset self._commandoid = commandoid or baseoid self._command_payload_on = command_payload_on or payload_on self._command_payload_off = command_payload_off or payload_off self._state = None self._payload_on = payload_on self._payload_off = payload_off if version == "3": if not authkey: authproto = "none" if not privkey: privproto = "none" self._request_args = [ SnmpEngine(), UsmUserData( username, authKey=authkey or None, privKey=privkey or None, authProtocol=getattr(hlapi, MAP_AUTH_PROTOCOLS[authproto]), privProtocol=getattr(hlapi, MAP_PRIV_PROTOCOLS[privproto]), ), UdpTransportTarget((host, port)), ContextData(), ] else: self._request_args = [ SnmpEngine(), CommunityData(community, mpModel=SNMP_VERSIONS[version]), UdpTransportTarget((host, port)), ContextData(), ]
async def async_setup_platform( hass: HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the SNMP sensor.""" host = config.get(CONF_HOST) port = config.get(CONF_PORT) community = config.get(CONF_COMMUNITY) baseoid = config.get(CONF_BASEOID) version = config[CONF_VERSION] username = config.get(CONF_USERNAME) authkey = config.get(CONF_AUTH_KEY) authproto = config[CONF_AUTH_PROTOCOL] privkey = config.get(CONF_PRIV_KEY) privproto = config[CONF_PRIV_PROTOCOL] accept_errors = config.get(CONF_ACCEPT_ERRORS) default_value = config.get(CONF_DEFAULT_VALUE) unique_id = config.get(CONF_UNIQUE_ID) if version == "3": if not authkey: authproto = "none" if not privkey: privproto = "none" request_args = [ SnmpEngine(), UsmUserData( username, authKey=authkey or None, privKey=privkey or None, authProtocol=getattr(hlapi, MAP_AUTH_PROTOCOLS[authproto]), privProtocol=getattr(hlapi, MAP_PRIV_PROTOCOLS[privproto]), ), UdpTransportTarget((host, port), timeout=DEFAULT_TIMEOUT), ContextData(), ] else: request_args = [ SnmpEngine(), CommunityData(community, mpModel=SNMP_VERSIONS[version]), UdpTransportTarget((host, port), timeout=DEFAULT_TIMEOUT), ContextData(), ] errindication, _, _, _ = await getCmd( *request_args, ObjectType(ObjectIdentity(baseoid)) ) if errindication and not accept_errors: _LOGGER.error("Please check the details in the configuration file") return data = SnmpData(request_args, baseoid, accept_errors, default_value) async_add_entities([SnmpSensor(hass, data, config, unique_id)], True)
async def send_snmp_request(self, host, target): response = await getCmd( self.snmpEngine, CommunityData(self.community_string, mpModel=1), UdpTransportTarget((host, 161)), ContextData(), target, ) error_indication, error_status, error_index, varbinds = response if error_indication: logger.warning('%s with this asset: %s', error_indication, host) return elif error_status: logger.warning( '%s at %s', error_status.prettyPrint(), ) return else: return varbinds[0]
async def get_one(snmp_engine, host, community_string, objects): objs = [ObjectType(ObjectIdentity(obj_id)) for obj_id in objects.keys()] errorIndication, errorStatus, errorIndex, varBinds = await getCmd( snmp_engine, CommunityData(community_string), UdpTransportTarget(host, timeout=1.0, retries=4), ContextData(), *objs, ) if errorIndication: logging.error(host, errorIndication) return elif errorStatus: logging.error(host, '{} at {}'.format(errorStatus.prettyPrint(), errorIndex)) return else: ret = [] ts = metricq.Timestamp.now() assert (len(varBinds) == len(objects)) for bindName, val in varBinds: obj_id = ".{}".format(bindName) # add "." in front try: metric_name, multi, interval = objects[obj_id] ret.append((metric_name, ts, float(val) * multi)) except Exception as e: logging.error(host, "Invalid result: {} = {}".format(bindName, val)) return [] return ret
def run_watt(pdu_ip, pdu_node_port): snmpEngine = SnmpEngine() errorIndication, errorStatus, errorIndex, varBinds = yield from getCmd( snmpEngine, CommunityData('public', mpModel=1), UdpTransportTarget((pdu_ip, 161)), ContextData(), ObjectType( ObjectIdentity('1.3.6.1.4.1.318.1.1.26.9.4.3.1.7.' + str(pdu_node_port))), ObjectType(ObjectIdentity('1.3.6.1.4.1.318.2.1.6.1.0')), ObjectType(ObjectIdentity('1.3.6.1.4.1.318.2.1.6.2.0'))) watt = None timestamp = None if errorIndication: LOGGER.error(errorIndication) elif errorStatus: LOGGER.error('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?')) else: watt = int(varBinds[0][1]) timestamp_str = str(varBinds[1][1]) + " " + str(varBinds[2][1]) timestamp = int( time.mktime( datetime.datetime.strptime(timestamp_str, "%m/%d/%Y %H:%M:%S").timetuple())) snmpEngine.transportDispatcher.closeDispatcher() return watt, timestamp
async def async_next_snmp_request(snmpEngine,host, oids, sleep_time, comment,queue): """Walk SNMP oids asynchronously.""" def g_tick(): # for 1 sec periodic interval t = time.time() count = 0 while True: count += 1 yield max(t + count * sleep_time - time.time(), 0) g = g_tick() def is_number(num): # This is to check if 'num' is number or str. If 'num' is number, i will return True try: float(num) # Type-casting the string to `float`. # If string is not a valid `float`, # it'll raise `ValueError` exception except : return False return True N = 1 while (N == 1): print('periodic main', time.time()) try : response = await getCmd( snmpEngine, CommunityData('public', mpModel=0), UdpTransportTarget((host, 161), timeout=1,retries=0), ContextData(), ObjectType(ObjectIdentity(oids)) ) await asyncio.sleep(next(g)) error_indication, error_status, error_index, var_binds = response if error_indication or error_status or error_index : print("Error occured") queue.put(0) else: for name, val in var_binds: print('%s = %s' % (name, val)) if is_number(val): queue.put(val) else : N = 0 #This is to get out while loop, so that finish this task. except : N = 0 #When exeption occurs, this is to get out while loop, so that finish this task.
async def walk_table(device: DriverBase, oid, factory: Optional[Callable] = None) -> List[Any]: """ This coroutine implements an SNMP "walk" of a given table starting at `oid`. Parameters ---------- device: DriverBase The device instance oid: str The SNMP table OID string value, for example "1.3.6.1.2.1.1.3" factory: Callable If provided by Caller this function is called for reach var_bind ('row data') in the table so that this factory function can extract what is desired for builting up the resulting list of records. If this function is not provided, then the default factory behavior is to extract the var_bind data only (via the .prettyPrint method). """ target = device.device_host # obtain the pySnmp required objects from the device private dictionary. dev_pysnmp = device.private["pysnmp"] snmp_engine = dev_pysnmp["engine"] snmp_community = dev_pysnmp["community"] initial_var_binds = var_binds = [ObjectType(ObjectIdentity(oid))] collected = list() # if a factory function is not provided, then return the oid value if not factory: def factory(_vb): """ default row factory to return value only """ return _vb[1].prettyPrint() while True: (err_indications, err_st, err_idx, var_bind_table) = await nextCmd( snmp_engine, snmp_community, UdpTransportTarget((target, SNMP_V2_PORT)), ContextData(), *var_binds, ) if err_indications: # an error indication is reason to raise an exception and stop # processing the walk emsg = f"{device.name}: SNMP failed on OID: {oid}" device.log.error(emsg) raise RuntimeError(emsg, err_indications) elif err_st: # an error status is reason to log the error, but continue walking # the MIB table. emsg = "%s at %s" % ( err_st.prettyPrint(), err_idx and var_binds[int(err_idx) - 1][0] or "?", ) device.log.error(emsg) for var_bind_row in var_bind_table: for idx, var_bind in enumerate(var_bind_row): if not initial_var_binds[0][idx].isPrefixOf(var_bind[0]): return collected collected.append(factory(var_bind)) # setup to fetch the next item in table var_binds = var_bind_table[-1]