diff --git a/meshview/templates/node.html b/meshview/templates/node.html index a317b16..a90d7de 100644 --- a/meshview/templates/node.html +++ b/meshview/templates/node.html @@ -48,6 +48,9 @@ {% if has_telemetry %} {% endif %} + {% if neighbors %} + + {% endif %} {% else %}
diff --git a/meshview/web.py b/meshview/web.py index 2feaa8a..3ff7520 100644 --- a/meshview/web.py +++ b/meshview/web.py @@ -7,6 +7,7 @@ from aiohttp_sse import sse_response import ssl import re +from pandas import DataFrame import seaborn as sns import matplotlib.pyplot as plt import matplotlib.ticker as ticker @@ -470,6 +471,51 @@ async def graph_power(request): ) +@routes.get("/graph/neighbors/{node_id}") +async def graph_neighbors(request): + oldest = datetime.datetime.utcnow() - datetime.timedelta(days=4) + + data = {} + dates =[] + for p in await store.get_packets_from(int(request.match_info['node_id']), PortNum.NEIGHBORINFO_APP): + _, payload = decode_payload.decode(p) + if p.import_time < oldest: + break + + dates.append(p.import_time) + for v in data.values(): + v.append(None) + + for n in payload.neighbors: + data.setdefault(n.node_id, [None] * len(dates))[-1] = n.snr + + nodes = {} + async with asyncio.TaskGroup() as tg: + for node_id in data: + nodes[node_id] = tg.create_task(store.get_node(node_id)) + + data_by_short_name = {} + for node_id, data in data.items(): + node = await nodes[node_id] + if node: + data_by_short_name[node.short_name] = data + else: + data_by_short_name[node_id_to_hex(node_id)] = data + + fig, ax1 = plt.subplots(figsize=(10, 10)) + ax1.set_xlabel('time') + ax1.set_ylabel('SNR') + df = DataFrame(data_by_short_name, index=dates) + sns.lineplot(data=df) + + 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()