better graphing
This commit is contained in:
@@ -402,6 +402,10 @@ Each graph contains a filled temperature area, a solid humidity line, and a
|
||||
dotted battery line. Initially, most of each graph is blank because no historic
|
||||
samples existed before the RRD was created.
|
||||
|
||||
Temperature uses the left axis with a default range of 0–30°C. Humidity and
|
||||
battery use the right axis with a default range of 0–100%. These ranges and
|
||||
labels can be changed in `config.yaml` under `graph.axes`.
|
||||
|
||||
The collector also generates `/var/www/html/sensors/index.html`. It displays
|
||||
six graphs at a time and has controls for switching between the daily, monthly,
|
||||
and two-year periods. It remembers the selected period and refreshes the PNGs
|
||||
|
||||
+9
-2
@@ -72,9 +72,16 @@ graph:
|
||||
width: 1000
|
||||
height: 360
|
||||
end: now
|
||||
vertical_label: degrees C / percent
|
||||
slope_mode: true
|
||||
alt_autoscale: true
|
||||
axes:
|
||||
temperature:
|
||||
minimum: 0
|
||||
maximum: 30
|
||||
label: degrees C
|
||||
percentage:
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
label: percent
|
||||
periods:
|
||||
day:
|
||||
start: end-1d
|
||||
|
||||
+27
-5
@@ -194,11 +194,26 @@ def render_graphs(sensor: Sensor, rrd_path: Path, config: Config) -> None:
|
||||
temperature = graph["temperature"]
|
||||
humidity = graph["humidity"]
|
||||
battery = graph["battery"]
|
||||
temperature_axis = graph["axes"]["temperature"]
|
||||
percentage_axis = graph["axes"]["percentage"]
|
||||
temperature_minimum = float(temperature_axis["minimum"])
|
||||
temperature_maximum = float(temperature_axis["maximum"])
|
||||
percentage_minimum = float(percentage_axis["minimum"])
|
||||
percentage_maximum = float(percentage_axis["maximum"])
|
||||
temperature_span = temperature_maximum - temperature_minimum
|
||||
percentage_span = percentage_maximum - percentage_minimum
|
||||
if temperature_span <= 0 or percentage_span <= 0:
|
||||
raise SystemExit("Graph axis maximums must be greater than their minimums")
|
||||
|
||||
percentage_to_temperature = temperature_span / percentage_span
|
||||
right_axis_scale = percentage_span / temperature_span
|
||||
right_axis_shift = percentage_minimum - temperature_minimum * right_axis_scale
|
||||
percentage_transform = (
|
||||
f"{percentage_minimum},-,{percentage_to_temperature},*,{temperature_minimum},+"
|
||||
)
|
||||
optional_flags = []
|
||||
if graph.get("slope_mode", False):
|
||||
optional_flags.append("--slope-mode")
|
||||
if graph.get("alt_autoscale", False):
|
||||
optional_flags.append("--alt-autoscale")
|
||||
|
||||
for suffix, period in graph["periods"].items():
|
||||
output = config.graph_dir / f"{sensor.slug}_{suffix}.png"
|
||||
@@ -206,15 +221,22 @@ def render_graphs(sensor: Sensor, rrd_path: Path, config: Config) -> None:
|
||||
"graph", str(output), "--start", str(period["start"]),
|
||||
"--end", str(graph["end"]),
|
||||
"--title", f"{sensor.name} - {period['label']}",
|
||||
"--vertical-label", str(graph["vertical_label"]),
|
||||
"--vertical-label", str(temperature_axis["label"]),
|
||||
"--right-axis", f"{right_axis_scale}:{right_axis_shift}",
|
||||
"--right-axis-label", str(percentage_axis["label"]),
|
||||
"--lower-limit", str(temperature_minimum),
|
||||
"--upper-limit", str(temperature_maximum),
|
||||
"--rigid",
|
||||
"--width", str(graph["width"]), "--height", str(graph["height"]),
|
||||
*optional_flags,
|
||||
f"DEF:temp={rrd_path}:temperature:AVERAGE",
|
||||
f"DEF:humidity={rrd_path}:humidity:AVERAGE",
|
||||
f"DEF:battery={rrd_path}:battery:AVERAGE",
|
||||
f"CDEF:humidity_scaled=humidity,{percentage_transform}",
|
||||
f"CDEF:battery_scaled=battery,{percentage_transform}",
|
||||
f"AREA:temp#{temperature['color']}:{temperature['legend']}",
|
||||
f"LINE{humidity['line_width']}:humidity#{humidity['color']}:{humidity['legend']}",
|
||||
f"LINE{battery['line_width']}:battery#{battery['color']}:{battery['legend']}:dashes={battery['dashes']}",
|
||||
f"LINE{humidity['line_width']}:humidity_scaled#{humidity['color']}:{humidity['legend']}",
|
||||
f"LINE{battery['line_width']}:battery_scaled#{battery['color']}:{battery['legend']}:dashes={battery['dashes']}",
|
||||
f"GPRINT:temp:LAST:{temperature['last_value_format']}",
|
||||
f"GPRINT:humidity:LAST:{humidity['last_value_format']}",
|
||||
f"GPRINT:battery:LAST:{battery['last_value_format']}",
|
||||
|
||||
Reference in New Issue
Block a user