예제 #1
0
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)
예제 #2
0
    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(),
            ]
예제 #3
0
파일: sensor.py 프로젝트: jbouwh/core
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)
예제 #4
0
    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]
예제 #5
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
예제 #6
0
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
예제 #7
0
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.
예제 #8
0
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]