#!/usr/bin/python # vim: set fileencoding=utf-8 : # # Munin plugin to monitor the switches in the pellematic # # Copyright 2013 Guido Guenther # # Licesnse: GPLv3 # # depends: python-requests # # FIXME: This currently doesn't probe the connected systems # #%# capabilities=autoconf #%# family=contrib import requests import os import re import sys import json username = os.getenv('username', 'oekofen') password = os.getenv('password', username) debug = os.getenv('debug') # The switches we want to plot (on/off 0/1 only): items = ["CAPPL:FA[0].L_kap_sensor_raumentnahme", "CAPPL:FA[0].L_kap_sensor_zwischenbehaelter", # Burner require "CAPPL:FA[0].L_br1", # Brandschutzklappe "CAPPL:FA[0].L_bsk_status", # Motor suction turbine "CAPPL:FA[0].ausgang_motor[0]", "CAPPL:FA[0].ausgang_motor[1]", "CAPPL:FA[0].ausgang_motor[2]", "CAPPL:FA[0].ausgang_motor[3]", "CAPPL:FA[0].ausgang_motor[4]", "CAPPL:FA[0].ausgang_motor[5]", "CAPPL:FA[0].ausgang_motor[8]", # Pellet transport inside boiler "CAPPL:FA[0].ausgang_motor[11]", "CAPPL:FA[0].ausgang_stoermelderelais", ] def canon(name): return re.sub(r"[^a-zA-Z0-9_]", "_", name) def fixup_name(item): return item['shortText'] def print_config(url): print """graph_title Pellematic Switches graph_vlabel On (1) or Off (0) graph_category Heating graph_info This graph shows the values for different on/off switches """ draw = "AREA" out = fetch_raw(url) for item in out: if item['name'] in items: name = fixup_name(item) print "%s.label %s" % (canon(name), name) print "%s.type GAUGE" % canon(name) print "%s.draw %s" % (canon(name), draw) if draw == "AREA": draw = "STACK" if 'stoermelderelais' in item['name']: print "%s.warning 0.1" % canon(name) print "%s.critical 1" % canon(name) def fetch_raw(url): # Perform authentication and get the cookie auth_formdata = {'language': 'en', 'username': username, 'password': password, 'submit': 'Login', } r = requests.post(url, data=auth_formdata) pksession = r.cookies['pksession'] cookies = { 'pksession': pksession, 'language': 'en' } params = { 'action': 'get', 'attr': '1', } # These are the headers used by the supplied application # It mostly doesn't matter what we pass but the backend # breaks with a lua error without a Accept-Language header: headers = {'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept-Language': 'en', } # The items to fetch are passed as simple json string payload = json.dumps(items) r = requests.post(url, data=payload, params=params, cookies=cookies, headers=headers) if hasattr(r.json, '__call__'): ret = r.json() else: # in requests 0.12 json isn't a callable ret = r.json if debug: print >>sys.stderr, ret return ret def fetch_values(url): out = fetch_raw(url) for item in out: if item['name'] in items: name = canon(fixup_name(item)) print "%s.value %s" % (name, item['value']) def main(args): target = os.getenv('address') if not target: print >>sys.stderr, "No ip address configured" return 1 url = 'http://%s' % target if len(args) > 1: if args[1] in [ 'autoconf', 'detect' ]: try: fetch_raw(url) print "yes" return 0 except: print "no" return 1 elif args[1] == 'config': try: print_config(url) except Exception as e: print >>sys.stderr, "Failed to fetch config: '%s'" % e return 1 return 0 try: fetch_values(url) except Exception as e: print >>sys.stderr, "Failed to fetch values: '%s'" % e raise return 1 return 0 if __name__ == "__main__": sys.exit(main(sys.argv))