Skip to content

Instantly share code, notes, and snippets.

@mskvortsov
Created June 11, 2024 07:33
Show Gist options
  • Save mskvortsov/5bd8045e812d2355ad62f9637556dc76 to your computer and use it in GitHub Desktop.
Save mskvortsov/5bd8045e812d2355ad62f9637556dc76 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# 1. Setup a device with a INA219 module connected and uplinking telemetry to a broker.
# 2. Acquire telemetry data
# mosquitto_sub -h mqtt.server.net -t "msh/2/json/#" >mqtt-json.log
# 3. Plot a graph
# plot.py mqtt-json.log graph.png "title"
import sys
import json
import pandas as pd
import matplotlib.pyplot as pyplot
import matplotlib.dates as mdates
import matplotlib.ticker as ticker
input_filename = sys.argv[1]
output_filename = sys.argv[2]
title = sys.argv[3]
def load_telemetry_data(filename):
ina219_data = []
espadc_data = []
with open(filename) as file:
for line in file:
j = json.loads(line)
t = j.get("timestamp")
p = j.get("payload")
if t is None or p is None:
continue
voltage = p.get("voltage")
voltage_ch3 = p.get("voltage_ch3")
current_ch3 = p.get("current_ch3")
if not voltage is None and voltage > 2.0:
espadc_data.append([t, voltage])
elif not (voltage_ch3 is None or current_ch3 is None):
ina219_data.append([t, voltage_ch3, current_ch3])
ina219_df = pd.DataFrame(ina219_data, columns=["timestamp", "voltage", "current"])
espadc_df = pd.DataFrame(espadc_data, columns=["timestamp", "voltage"])
return ina219_df, espadc_df
ina219_df, espadc_df = load_telemetry_data(input_filename)
ina219_df.set_index(pd.to_datetime(ina219_df["timestamp"], unit="s"), inplace=True)
ina219_current_df = ina219_df[["current"]].resample("1min").ffill()
ina219_df = ina219_df[["voltage"]].resample("1min").ffill()
espadc_df.set_index(pd.to_datetime(espadc_df["timestamp"], unit="s"), inplace=True)
espadc_df = espadc_df[["voltage"]].resample("1min").ffill()
deviation_df = (espadc_df - ina219_df).abs() * 1000
pyplot.rcParams['lines.linewidth'] = 1
fig, ax1 = pyplot.subplots()
fig.set_figwidth(15)
fig.set_figheight(7)
ax1.grid(True, linestyle="dashed")
ax1.set_title(title)
ax1.set_xlabel("Time")
ax1.set_ylabel("Battery Voltage, V")
espadc = ax1.plot(espadc_df, color="blue", label="espadc, V")
ina219 = ax1.plot(ina219_df, color="green", label="ina219, V")
ax1.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0]))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
ax1.yaxis.set_major_locator(ticker.MultipleLocator(base=0.05))
ax2 = ax1.twinx()
ax2.set_ylabel("Voltage Deviation =|espadc—ina219|, mV")
ax2.set_ylim((0, 250))
deviation_label = "deviation, mV\nmax {0}mV\navg {1}mV\nmin {2}mV".format(
round(deviation_df.max().iloc[0]),
round(deviation_df.mean().iloc[0]),
round(deviation_df.min().iloc[0]))
deviation = ax2.plot(deviation_df, color="black", label=deviation_label)
ax3 = ax1.twinx()
ax3.set_ylim((0, 500))
ax3.yaxis.set_major_locator(pyplot.NullLocator())
current_label = "current, mA\n%dmA avg" % round(ina219_current_df.mean().iloc[0])
current = ax3.plot(ina219_current_df, color="red", label=current_label)
lines = espadc + ina219 + deviation + current
labels = [l.get_label() for l in lines]
ax2.legend(lines, labels, loc="upper right")
pyplot.savefig(output_filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment