diff --git a/meshview/templates/node.html b/meshview/templates/node.html
index e27d6a1..d73edc3 100644
--- a/meshview/templates/node.html
+++ b/meshview/templates/node.html
@@ -39,6 +39,7 @@
hw model
{{node.hw_model}}
+
{% else %}
diff --git a/meshview/web.py b/meshview/web.py
index 6330328..bbe66c5 100644
--- a/meshview/web.py
+++ b/meshview/web.py
@@ -1,4 +1,5 @@
import asyncio
+import io
from dataclasses import dataclass
import datetime
@@ -6,6 +7,8 @@ from aiohttp_sse import sse_response
import ssl
import re
+import seaborn as sns
+import matplotlib.pyplot as plt
from aiohttp import web
from markupsafe import Markup
from jinja2 import Environment, PackageLoader, select_autoescape
@@ -400,6 +403,37 @@ async def packet(request):
)
+@routes.get("/graph/power/{node_id}")
+async def graph_power(request):
+ date = []
+ battery = []
+ voltage = []
+ for p in await store.get_packets_from(int(request.match_info['node_id']), PortNum.TELEMETRY_APP):
+ _, payload = decode_payload.decode(p)
+ if not payload.HasField('device_metrics'):
+ continue
+ date.append(datetime.datetime.fromtimestamp(payload.time))
+ battery.append(payload.device_metrics.battery_level)
+ voltage.append(payload.device_metrics.voltage)
+
+ fig, ax1 = plt.subplots(figsize=(10, 10))
+ ax1.set_xlabel('time')
+ ax1.set_ylabel('battery level', color='tab:blue')
+ ax2 = ax1.twinx()
+ ax2.set_ylabel('voltage', color='tab:red')
+ sns.lineplot(x=date, y=battery, ax=ax1, color='tab:blue')
+ sns.lineplot(x=date, y=voltage, ax=ax2, color='tab:red')
+
+ png = io.BytesIO()
+ plt.savefig(png, dpi=100)
+
+ return web.Response(
+ body=png.getvalue(),
+ content_type="image/png",
+ )
+
+
+
async def run_server(bind, port, tls_cert):
app = web.Application()
app.add_routes(routes)
diff --git a/requirements.txt b/requirements.txt
index b1eebd1..6bf4d90 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,3 +8,4 @@ aiodns
Jinja2
aiohttp-sse
asyncpg
+seaborn