#!/usr/bin/python3

'''
Check for temperature sensors from papouch.com devices.

Usage:
  XML (http) access:
    check_papouch -H hostname
  SNMP access:
    check_papouch -S hostname
'''

import sys, os, getopt
from xml.dom.minidom import parse, parseString
if sys.version_info[0]>2:
  from urllib.request import urlopen, URLError
else:
  from urllib2 import urlopen, URLError

id2name = {
  '1': ['Temperature', 'C', 0, 100],
  '2': ['Humidity', '%', 0, 100],
  '3': ['Dew_point', 'C', -100, 100]
}

def getdata_snmp(host, crit_min, crit_max):
    from netsnmp import Session, VarList, Varbind
    session = Session(DestHost=host, Community="public", Version=1)
    ret = session.get(VarList(Varbind("1.3.6.1.4.1.18248.1.1.1", 0)))
    if ret:
      value = float(ret[0] or 0)/10.0
    else:
      print("SNMP get error")
    return dict(temp=[value, crit_min, crit_max, 'C'])

def getdata(host):
    f = urlopen('http://%s/fresh.xml' % host)
    dom = parse(f)
    ret = {}
    for sns in dom.getElementsByTagName('sns'):
      id = sns.getAttribute('id')
      if not id:
        # temperature sensor only
        return dict(temp=[
          float(sns.getAttribute('val'))/10.0,
          float(sns.getAttribute('min'))/10.0,
          float(sns.getAttribute('max'))/10.0,
          'C'
        ])
      else:
        # temperature and humidity sensor
        name, cp, min, max = id2name[id]
        ret[name] = [
          float(sns.getAttribute('val')),
          float(sns.getAttribute('w-min') or min),
          float(sns.getAttribute('w-max') or max),
          cp
        ]
    return ret

def status(s, d):
    ret = []
    for name, (val, min, max, cp) in d.items():
      ret.append("%s=%3.2f;%3.2f;%3.2f" % (name, val, min, max))
    print(s+"|"+' '.join(ret))

opts,files = getopt.gnu_getopt(sys.argv[1:], 'SHw:c:', [])

snmp_mode = False
warn = (10, 40)
crit = (0, 100)
for key, value in opts:
  if key=="-S":
    snmp_mode = True
  elif key=="-H":
    snmp_mode = False
  elif key=="-w":
    warn = [float(x) for x in value.split(',', 1)]
  elif key=="-c":
    crit = [float(x) for x in value.split(',', 1)]

if snmp_mode:
  # use SNMP access
  d = getdata_snmp(files[0], crit[0], crit[1])
else:
  # use XML access
  d = getdata(files[0])

sum = []
for name, (val, min, max, cp) in d.items():
  if min<=val<=max:
    sum.append("%s=%s%s" % (name.lower(), val, cp))
  else:
    status('CRITICAL %s=%s%s' % (name.lower(), val, cp), d)
    sys.exit(2)

status('OK %s' % ', '.join(sum), d)
sys.exit(0)
