#!/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'],
}
#.
