- Posted on
Mon Apr 02, 2018 9:15 am
-
Different Computers
offline
-
- Posts: 2579
- Joined: Jan 02, 2016
- Location: East Coast
-
How do I represent a device's battery level on a control page? I can't seem to find any built-in images to use for control pages for this. Indigo client has some custom support for displaying battery level for certain device types in the Item Detail window - would be nice if I could re-use or replicate something like that in a control page.
I use a forum script someone else came up with to automatically generate a graph of this. Bonus, when I add a new device that is battery powered, the script automatically adds it to the graph.
No credit to me, and sorry I forget who came up with it. One of the usual suspects, I'm sure.
- Code: Select all
#! /usr/bin/env python2.6
# -*- coding: utf-8 -*-
try:
import sys
import matplotlib.pyplot as plt
import numpy as np
except ImportError, e:
sys.exit(u"The matplotlib and numpy modules are required to use this script.")
# =================== User Settings ===================
output_file = '/Library/Application Support/Perceptive Automation/Indigo 7/IndigoWebServer/images/controls/static/battery_test.png'
chart_title = 'Battery Levels'
x_axis_title = ''
y_axis_title = ''
background_color = '#000000'
chart_height = 4.5
chart_width = 6.15
font_color = '#000000'
font_name = 'Verdana'
font_size = 9
grid_color = '#888888'
grid_style = 'dotted'
show_data_labels = True
title_font_size = 9
battery_full_color = '#0000CC'
battery_caution_color = '#FFFF00'
battery_caution_level = 10
battery_low_color = '#FF0000'
battery_low_level = 5
# =================== kwarg Settings ===================
k_bar_fig = {'align': 'center',
'alpha': 1.0,
'height': 0.5,
'zorder': 3
}
k_grid_fig = {'which': 'major',
'color': grid_color,
'linestyle': grid_style,
'zorder': 0
}
k_plot_fig = {'bbox_extra_artists': None,
'bbox_inches': 'tight',
'dpi': 100,
'format': None,
'frameon': None,
'orientation': None,
'pad_inches': 0.1,
'papertype': None,
'transparent': True,
}
k_title_fig = {'fontname': font_name,
'fontsize': title_font_size,
'color': font_color,
'position': (0.35, 1.0)
}
# =====================================================
bar_colors = []
device_dict = {}
x_values = []
y_values = []
# Create a dict of battery powered devices and their battery levels
try:
for dev in indigo.devices.itervalues():
if dev.batteryLevel is not None:
device_dict[dev.name] = dev.states['batteryLevel']
if device_dict == {}:
device_dict['No Battery Devices'] = '0'
except Exception, e:
indigo.server.log(u"Error reading battery devices: %s" % e)
# Parse the battery device dict into X and Y values
try:
for key, value in sorted(device_dict.iteritems(), reverse=True):
x_values.append(float(value))
y_values.append(key.replace(' - ', '\n')) # This line is specific to my install, as I name devices "Room - Device Name"
# Create a list of colors for the bars based on battery health
battery_level = float(value)
if battery_level <= battery_low_level:
bar_colors.append(battery_low_color)
elif battery_low_level < battery_level <= battery_caution_level:
bar_colors.append(battery_caution_color)
else:
bar_colors.append(battery_full_color)
except Exception, e:
indigo.server.log(u"Error parsing chart data: %s" % e)
# Create a list of values to plot on the Y axis, since we can't plot on device names.
y_axis = np.arange(len(y_values))
# Plot the figure
plt.figure(figsize=(chart_width, chart_height))
# Adding 1 to the y_axis pushes the bar to spot 1 instead of spot 0 -- getting it off the axis.
plt.barh((y_axis + 1), x_values, color=bar_colors, **k_bar_fig)
if show_data_labels:
for ii in range(len(y_axis)):
plt.annotate("%3d" % x_values[ii], xy=((x_values[ii] - 5), (y_axis[ii]) + 0.88), xycoords='data', textcoords='data', fontsize=font_size, color=font_color)
# Chart
plt.title(chart_title, **k_title_fig)
plt.grid(**k_grid_fig)
# X Axis
plt.xticks(fontsize=font_size, color=font_color)
plt.xlabel(x_axis_title, fontsize=font_size, color=font_color)
plt.gca().xaxis.grid(True)
plt.xlim(xmin=0, xmax=100)
# Y Axis
# The addition of 0.05 to the y_axis better centers the labels on the bars
# (for 2-line labels.) For 1 line labels, change 1.07 to 1.0.
plt.yticks((y_axis + 1.05), y_values, fontsize=font_size, color=font_color)
plt.ylabel(y_axis_title, fontsize=font_size, color=font_color)
plt.gca().yaxis.grid(False)
plt.ylim(ymin=0)
# Output the file
plt.tight_layout()
plt.gca().spines['top'].set_visible((False))
plt.gca().spines['bottom'].set_visible((False))
plt.gca().spines['left'].set_visible((False))
plt.gca().spines['right'].set_visible((False))
plt.savefig(output_file, **k_plot_fig)
plt.close()
Sonoma on a Mac Mini M1 running Airfoil Pro, Bond Home, Camect, Roku Network Remote, Hue Lights, DomoPad, Adapters, Home Assistant Agent, HomeKitLinkSiri, EPS Smart Dimmer, Fantastic Weather, Nanoleaf, LED Simple Effects, Grafana. UnifiAP