hue: use perlpod and other small changes

This commit is contained in:
Kim B. Heino 2021-04-06 08:06:19 +03:00 committed by Lars Kruse
parent 4f22cec97c
commit 7e48a2c8b5
1 changed files with 46 additions and 33 deletions

View File

@ -1,35 +1,48 @@
#!/usr/bin/python3 -tt #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Munin plugin to read various data from Philips Hue. """Munin plugin to read various data from Philips Hue devices.
Copyright 2019, Kim B. Heino, b@bbbs.net, Foobar Oy =head1 NAME
License GPLv2+
Munin configuration: hue - monitor various data from Philips Hue devices
[hue] =head1 APPLICABLE SYSTEMS
env.host hue-bridge-ip-or-hostname
env.auth auth-key Homes with Philips Hue light bulbs and motion sensors.
=head1 CONFIGURATION
Following config is needed:
[hue]
env.host hue-bridge-ip-or-hostname
env.auth auth-key
=head1 AUTHOR
Kim B. Heino <b@bbbs.net>
=head1 LICENSE
GPLv2
=cut
""" """
import json
import os import os
import sys import sys
import unicodedata import unicodedata
import requests import urllib.request
def cleanup(value): def safename(name):
"""Convert value to Munin key.""" """Return safe variable name."""
ret = [] # Convert ä->a as isalpha('ä') is true
for char in value: value = unicodedata.normalize('NFKD', name)
if 'a' <= char <= 'z' or '0' <= char <= '9': value = value.encode('ASCII', 'ignore').decode('utf-8')
ret.append(char)
elif 'A' <= char <= 'Z': # Remove non-alphanumeric chars
ret.append(char.lower()) return ''.join(char.lower() if char.isalnum() else '_' for char in value)
else:
ret.append('_')
return ''.join(ret)
def sensor_name(data, sensor): def sensor_name(data, sensor):
@ -40,14 +53,11 @@ def sensor_name(data, sensor):
if item.get('uniqueid', '').startswith(uniqueid): if item.get('uniqueid', '').startswith(uniqueid):
name = item['name'] name = item['name']
break break
return name
# Convert ä to a and return it as utf8 string, py2/3 compatible way
name = unicodedata.normalize('NFKD', name)
return name.encode('ASCII', 'ignore').decode('utf-8')
def print_temperatures(data, config, both): def print_temperatures(data, config, both):
"""Temperature sensors.""" """Motion sensor has temperature sensor - Read it's value."""
if not any([sensor['type'] == 'ZLLTemperature' if not any([sensor['type'] == 'ZLLTemperature'
for sensor in data['sensors'].values()]): for sensor in data['sensors'].values()]):
return return
@ -62,7 +72,7 @@ def print_temperatures(data, config, both):
for sensor in data['sensors'].values(): for sensor in data['sensors'].values():
if sensor['type'] != 'ZLLTemperature': if sensor['type'] != 'ZLLTemperature':
continue continue
label = cleanup(sensor['name']) label = safename(sensor['name'])
if config: if config:
print('{}.label {}'.format(label, sensor_name(data, sensor))) print('{}.label {}'.format(label, sensor_name(data, sensor)))
if not config or both: if not config or both:
@ -71,7 +81,7 @@ def print_temperatures(data, config, both):
def print_light_levels(data, config, both): def print_light_levels(data, config, both):
"""Light level sensors.""" """Motion sensor has light level sensor - Read it's value."""
if not any([sensor['type'] == 'ZLLLightLevel' if not any([sensor['type'] == 'ZLLLightLevel'
for sensor in data['sensors'].values()]): for sensor in data['sensors'].values()]):
return return
@ -87,7 +97,7 @@ def print_light_levels(data, config, both):
for sensor in data['sensors'].values(): for sensor in data['sensors'].values():
if sensor['type'] != 'ZLLLightLevel': if sensor['type'] != 'ZLLLightLevel':
continue continue
label = cleanup(sensor['name']) label = safename(sensor['name'])
if config: if config:
print('{}.label {}'.format(label, sensor_name(data, sensor))) print('{}.label {}'.format(label, sensor_name(data, sensor)))
if not config or both: if not config or both:
@ -96,7 +106,7 @@ def print_light_levels(data, config, both):
def print_lights(data, config, both): def print_lights(data, config, both):
"""Lights on/off.""" """Light bulbs on/off."""
if not data['lights']: if not data['lights']:
return return
@ -120,8 +130,11 @@ def print_lights(data, config, both):
def print_data(config): def print_data(config):
"""Print config or values.""" """Print config or values."""
# Get values # Get values
data = requests.get('http://{}/api/{}/'.format( url = 'http://{}/api/{}/'.format(os.getenv('host'), os.getenv('auth'))
os.getenv('host'), os.getenv('auth')), timeout=50).json() try:
data = json.loads(urllib.request.urlopen(url, timeout=50).read())
except (OSError, ValueError, TypeError):
return
both = os.getenv('MUNIN_CAP_DIRTYCONFIG') == '1' both = os.getenv('MUNIN_CAP_DIRTYCONFIG') == '1'
# Print config/values # Print config/values
@ -132,7 +145,7 @@ def print_data(config):
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'autoconf': if len(sys.argv) > 1 and sys.argv[1] == 'autoconf':
print('no') print('no (this is not autoconf plugin)')
elif len(sys.argv) > 1 and sys.argv[1] == 'config': elif len(sys.argv) > 1 and sys.argv[1] == 'config':
print_data(True) print_data(True)
else: else: