#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2016             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.



#   .--example output------------------------------------------------------.
#   |                                               _                      |
#   |                 _____  ____ _ _ __ ___  _ __ | | ___                 |
#   |                / _ \ \/ / _` | '_ ` _ \| '_ \| |/ _ \                |
#   |               |  __/>  < (_| | | | | | | |_) | |  __/                |
#   |                \___/_/\_\__,_|_| |_| |_| .__/|_|\___|                |
#   |                                        |_|                           |
#   |                               _               _                      |
#   |                    ___  _   _| |_ _ __  _   _| |_                    |
#   |                   / _ \| | | | __| '_ \| | | | __|                   |
#   |                  | (_) | |_| | |_| |_) | |_| | |_                    |
#   |                   \___/ \__,_|\__| .__/ \__,_|\__|                   |
#   |                                  |_|                                 |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'
# .1.3.6.1.4.1.30155.2.1.2.1.2.18 temp0
# .1.3.6.1.4.1.30155.2.1.2.1.2.20 temp2
# .1.3.6.1.4.1.30155.2.1.2.1.2.27 fan3
# .1.3.6.1.4.1.30155.2.1.2.1.2.31 fan7
# .1.3.6.1.4.1.30155.2.1.2.1.2.40 VTT
# .1.3.6.1.4.1.30155.2.1.2.1.2.47 volt9

# .1.3.6.1.4.1.30155.2.1.2.1.3.18 0
# .1.3.6.1.4.1.30155.2.1.2.1.3.20 0
# .1.3.6.1.4.1.30155.2.1.2.1.3.27 1
# .1.3.6.1.4.1.30155.2.1.2.1.3.31 1
# .1.3.6.1.4.1.30155.2.1.2.1.3.40 2
# .1.3.6.1.4.1.30155.2.1.2.1.3.47 2

# .1.3.6.1.4.1.30155.2.1.2.1.5.18 -273.15
# .1.3.6.1.4.1.30155.2.1.2.1.5.20 56.00
# .1.3.6.1.4.1.30155.2.1.2.1.5.27 4179
# .1.3.6.1.4.1.30155.2.1.2.1.5.31 329
# .1.3.6.1.4.1.30155.2.1.2.1.5.40 1.15
# .1.3.6.1.4.1.30155.2.1.2.1.5.47 0.00

# .1.3.6.1.4.1.30155.2.1.2.1.6.18 degC
# .1.3.6.1.4.1.30155.2.1.2.1.6.20 degC
# .1.3.6.1.4.1.30155.2.1.2.1.6.27 RPM
# .1.3.6.1.4.1.30155.2.1.2.1.6.31 RPM
# .1.3.6.1.4.1.30155.2.1.2.1.6.40 V DC
# .1.3.6.1.4.1.30155.2.1.2.1.6.47 V DC

# .1.3.6.1.4.1.30155.2.1.2.1.7.18 0
# .1.3.6.1.4.1.30155.2.1.2.1.7.20 0
# .1.3.6.1.4.1.30155.2.1.2.1.7.27 0
# .1.3.6.1.4.1.30155.2.1.2.1.7.31 0
# .1.3.6.1.4.1.30155.2.1.2.1.7.40 0
# .1.3.6.1.4.1.30155.2.1.2.1.7.47 0


#.
#   .--parse---------------------------------------------------------------.
#   |                                                                      |
#   |                      _ __   __ _ _ __ ___  ___                       |
#   |                     | '_ \ / _` | '__/ __|/ _ \                      |
#   |                     | |_) | (_| | |  \__ \  __/                      |
#   |                     | .__/ \__,_|_|  |___/\___|                      |
#   |                     |_|                                              |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

def parse_openbsd_sensors(info):
    parsed = {}
    used_descriptions = set()
    def get_item_name(name):
        idx = 0
        new_name = name
        while True:
            if new_name in used_descriptions:
                new_name = "%s/%d" % (name, idx)
                idx += 1
            else:
                used_descriptions.add(new_name)
                break
        return new_name

    openbsd_map_state = {
        '0' : 3,
        '1' : 0,
        '2' : 1,
        '3' : 2,
    }

    openbsd_map_type = {
        '0' : 'temp',
        '1' : 'fan',
        '2' : 'voltage'
    }

    for descr, sensortype, value, unit, state in info:
        if sensortype not in openbsd_map_type:
            continue
        if (sensortype == '0' and value == '-273.15') or \
           (sensortype in [ '1', '2'] and float(value) == 0):
            continue

        item_name = get_item_name(descr)
        parsed[item_name] = {
            'state' : openbsd_map_state[state],
            'value' : float(value),
            'unit'  : unit,
            'type'  : openbsd_map_type[sensortype],
        }
    return parsed


#.
#   .--inventory-----------------------------------------------------------.
#   |             _                      _                                 |
#   |            (_)_ ____   _____ _ __ | |_ ___  _ __ _   _               |
#   |            | | '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | |              |
#   |            | | | | \ V /  __/ | | | || (_) | |  | |_| |              |
#   |            |_|_| |_|\_/ \___|_| |_|\__\___/|_|   \__, |              |
#   |                                                  |___/               |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

def inventory_openbsd_sensors(parsed, sensortype):
    inventory = []
    for key, values in parsed.items():
         if values['type'] == sensortype:
            inventory.append( (key, {}) )
    return inventory

#.
#   .--temperature---------------------------------------------------------.
#   |      _                                      _                        |
#   |     | |_ ___ _ __ ___  _ __   ___ _ __ __ _| |_ _   _ _ __ ___       |
#   |     | __/ _ \ '_ ` _ \| '_ \ / _ \ '__/ _` | __| | | | '__/ _ \      |
#   |     | ||  __/ | | | | | |_) |  __/ | | (_| | |_| |_| | | |  __/      |
#   |      \__\___|_| |_| |_| .__/ \___|_|  \__,_|\__|\__,_|_|  \___|      |
#   |                       |_|                                            |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

def check_openbsd_sensors(item, params, parsed):
    if item in parsed:
        return check_temperature(parsed[item]['value'], params, "openbsd_sensors_%s" % item)


check_info['openbsd_sensors'] = {
    'parse_function'        : parse_openbsd_sensors,
    'inventory_function'    : lambda parsed: inventory_openbsd_sensors(parsed, 'temp'),
    'check_function'        : check_openbsd_sensors,
    'service_description'   : 'Temperature %s',
    'has_perfdata'          : True,
    'snmp_info'             : ('.1.3.6.1.4.1.30155.2.1.2.1', [
                                    "2",    # sensorDescr
                                    "3",    # sensorType
                                    "5",    # sensorValue
                                    "6",    # sensorUnits
                                    "7",    # sensorStatus
                              ]),
    'snmp_scan_function'    : lambda oid: oid(".1.3.6.1.4.1.30155.2.1.1.0"),
    'group'                 : 'temperature',
    'includes'              : [ 'temperature.include' ],
}

#.
#   .--fan-----------------------------------------------------------------.
#   |                            __                                        |
#   |                           / _| __ _ _ __                             |
#   |                          | |_ / _` | '_ \                            |
#   |                          |  _| (_| | | | |                           |
#   |                          |_|  \__,_|_| |_|                           |
#   |                                                                      |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

factory_settings['openbsd_sensors_fan_default_levels'] = {
        'lower' : (500, 300),
        'upper' : (8000, 8400),
}

def check_openbsd_sensors_fan(item, params, parsed):
    if item in parsed:
        return check_fan(parsed[item]['value'], params)


check_info['openbsd_sensors.fan'] = {
    'inventory_function'        : lambda parsed: inventory_openbsd_sensors(parsed, 'fan'),
    'check_function'            : check_openbsd_sensors_fan,
    'service_description'       : 'Fan %s',
    'has_perfdata'              : True,
    'default_levels_variable'   : 'openbsd_sensors_fan_default_levels',
    'group'                     : 'hw_fans',
    'includes'                  : [ 'fan.include' ],
}
#.
#   .--voltage-------------------------------------------------------------.
#   |                             _ _                                      |
#   |                 __   _____ | | |_ __ _  __ _  ___                    |
#   |                 \ \ / / _ \| | __/ _` |/ _` |/ _ \                   |
#   |                  \ V / (_) | | || (_| | (_| |  __/                   |
#   |                   \_/ \___/|_|\__\__,_|\__, |\___|                   |
#   |                                        |___/                         |
#   +----------------------------------------------------------------------+
#   |                                                                      |
#   '----------------------------------------------------------------------'

def check_openbsd_sensors_voltage(item, params, parsed):
    if item in parsed:
        item_elphase = {}
        parsed_elphase = {}
        item_elphase['voltage'] = parsed[item]['value']
        parsed_elphase[item] = item_elphase

    return check_elphase(item, params, parsed_elphase)

check_info['openbsd_sensors.voltage'] = {
    'inventory_function'    : lambda parsed: inventory_openbsd_sensors(parsed, 'voltage'),
    'check_function'        : check_openbsd_sensors_voltage,
    'service_description'   : 'Voltage Type %s',
    'has_perfdata'          : True,
    'group'                 : 'el_inphase',
    'includes'              : [ 'elphase.include' ],
}
#.
