Developing my first SNMP plugin

Good to know, maybe there is some standard among the different brands after all!

I added performance charts for the CPU usage, the memory usage and the time offset. I removed most of the (useless) data as well.

Code:

#!/usr/bin/env python3
# http://www.circitor.fr/Mibs/Mib/H/HIK-DEVICE-MIB.mib

from cmk.base.plugins.agent_based.agent_based_api.v1 import exists, register, render, SNMPTree, Service, Result, State, Metric
from datetime import datetime

def parse_trendnet_camera(string_table):
    mib = {
        1:  ('deviceType'),
        2:  ('hardwVersion'),
        3:  ('softwVersion'),
        4:  ('macAddr'),
        5:  ('deviceID'),
        6:  ('manufacturer'),
        7:  ('cpuPercent'),
        8:  ('diskSize'),
        9:  ('diskPercent'),
        10: ('memSize'),
        11: ('memUsed'),
        12: ('restartDev'),
        13: ('dynIpAddr'),
        14: ('dynNetMask'),
        15: ('dynGateway'),
        16: ('staticIpAddr'),
        17: ('staticNetMask'),
        18: ('staticGateway'),
        19: ('sysTime'),
        20: ('videoInChanNum'),
        21: ('videoEncode'),
        22: ('videoNetTrans'),
        23: ('audioAbility'),
        24: ('audioInNum'),
        25: ('videoOutNum'),
        26: ('clarityChanNum'),
        27: ('localStorage'),
        28: ('rtspPlayBack'),
        29: ('netAccessType'),
        30: ('alarmInChanNum'),
        31: ('alarmOutChanNum'),
        32: ('manageServAddr'),
        33: ('ntpServIpAddr'),
        34: ('managePort'),
    }

    parsed = {}
    x = 0

    for value in string_table[0]:
        x += 1
        parsed[mib[x]] = value
    return parsed

def discover_trendnet_camera(section):
    # there are some OIDs which we don't really need such as the network addresses, so we filter what we discover here
    discovery_mibs = [
                'deviceType',
                'softwVersion',
                'cpuPercent',
                'memUsed',
                'sysTime',
        ]
    for key in section:
        if key in discovery_mibs: yield Service(item=key)

def check_trendnet_camera(item, params, section):
    if section[item] == '': section[item] = 'No data provided'
    if item == 'cpuPercent':
        yield Metric(name='util', value=int(section[item].split()[0]))
        summary = f"Total CPU : {render.percent(int(section[item].split()[0]))}"
    elif item == 'memUsed':
        yield Metric(name='mem_used_percent', value=int(section[item].split()[0]))
        summary = f"Total : {render.percent(int(section[item].split()[0]))}, {int(int(section[item].split()[0])/100*int(section['memSize'].split()[0]))} MB of {section['memSize']}"
    elif item == 'sysTime':
        diff = int((datetime.now() - datetime.strptime(section[item],'%Y-%m-%d %H:%M:%S')).total_seconds())
        yield Metric(name='time_offset', value=diff)
        if abs(diff) > 120: # tolerance offset
            state=State.CRIT
        else:
            state=State.OK
        yield Result(state=state, summary=f"Offset: {diff} s")
        return
    else:
        summary = section[item]
    yield Result(state=State.OK, summary=summary)

register.snmp_section(
    name = 'trendnet_camera',
    detect = exists('.1.3.6.1.4.1.39165.1.1.0'),
    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.39165.1',
        oids = [
            '1.0',  # deviceType
            '2.0',  # hardwVersion
            '3.0',  # softwVersion
            '4.0',  # macAddr
            '5.0',  # deviceID
            '6.0',  # manufacturer
            '7.0',  # cpuPercent
            '8.0',  # diskSize
            '9.0',  # diskPercent
            '10.0', # memSize
            '11.0', # memUsed
            '12.0', # restartDev
            '13.0', # dynIpAddr
            '14.0', # dynNetMask
            '15.0', # dynGateway
            '16.0', # staticIpAddr
            '17.0', # staticNetMask
            '18.0', # staticGateway
            '19.0', # sysTime
            '20.0', # videoInChanNum
            '21.0', # videoEncode
            '22.0', # videoNetTrans
            '23.0', # audioAbility
            '24.0', # audioInNum
            '25.0', # videoOutNum
            '26.0', # clarityChanNum
            '27.0', # localStorage
            '28.0', # rtspPlayBack
            '29.0', # netAccessType
            '30.0', # alarmInChanNum
            '31.0', # alarmOutChanNum
            '32.0', # manageServAddr
            '33.0', # ntpServIpAddr
            '34.0', # managePort
        ],
    ),
    parse_function=parse_trendnet_camera,
)

register.check_plugin(
    name='trendnet_camera',
    service_name='IPTV %s',
    discovery_function=discover_trendnet_camera,
    check_function=check_trendnet_camera,
    check_default_parameters={}
)