fix(stats): eigene Telemetrie aus Pakettypen-Diagramm ausschließen

get_stats() filtert TELEMETRY_APP-Pakete des eigenen Nodes wenn my_node_id
übergeben wird – konsistent mit isSuppressed() im Paket-Log-Frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ppfeiffer 2026-02-20 06:31:07 +01:00
parent d6631c1554
commit a6988fbb1f
5 changed files with 31 additions and 10 deletions

View file

@ -1,5 +1,14 @@
# Changelog
## [0.8.11] - 2026-02-20
### Fixed
- **Pakettypen-Diagramm: eigene Telemetrie ausgeschlossen**: `get_stats()` akzeptiert
jetzt optionalen Parameter `my_node_id`. Ist er gesetzt, werden `TELEMETRY_APP`-Pakete
des eigenen Nodes aus `packet_type_breakdown` herausgefiltert (konsistent mit der
`isSuppressed()`-Logik im Paket-Log-Frontend). Alle Aufrufer (`bot.py`, `webserver.py`)
übergeben `get_my_node_id()`.
## [0.8.10] - 2026-02-19
### Added

View file

@ -1,4 +1,4 @@
version: "0.8.10"
version: "0.8.11"
bot:
name: "MeshDD-Bot"

View file

@ -192,7 +192,7 @@ class MeshBot:
async def _broadcast_stats(self):
if self.ws_manager:
stats = await self.db.get_stats()
stats = await self.db.get_stats(my_node_id=self.get_my_node_id())
stats["uptime"] = self._format_uptime()
stats["bot_connected"] = self._connected
await self.ws_manager.broadcast("stats_update", stats)
@ -417,7 +417,7 @@ class MeshBot:
response = await self._get_weather(from_id, plz=plz)
elif cmd == f"{prefix}stats":
stats = await self.db.get_stats()
stats = await self.db.get_stats(my_node_id=self.get_my_node_id())
response = (
f"📊 Statistiken:\n"
f"Nodes: {stats['total_nodes']}\n"

View file

@ -197,7 +197,7 @@ class Database:
)
await self.db.commit()
async def get_stats(self) -> dict:
async def get_stats(self, my_node_id: str | None = None) -> dict:
stats = {}
async with self.db.execute("SELECT COUNT(*) FROM nodes") as c:
stats["total_nodes"] = (await c.fetchone())[0]
@ -216,10 +216,20 @@ class Database:
(day_ago,),
) as cursor:
stats["channel_breakdown"] = {row[0]: row[1] async for row in cursor}
async with self.db.execute(
"SELECT portnum, COUNT(*) as cnt FROM packets WHERE timestamp >= ? GROUP BY portnum ORDER BY cnt DESC",
(day_ago,),
) as cursor:
if my_node_id:
pkt_query = (
"SELECT portnum, COUNT(*) as cnt FROM packets "
"WHERE timestamp >= ? AND NOT (portnum = 'TELEMETRY_APP' AND from_id = ?) "
"GROUP BY portnum ORDER BY cnt DESC"
)
pkt_params = (day_ago, my_node_id)
else:
pkt_query = (
"SELECT portnum, COUNT(*) as cnt FROM packets "
"WHERE timestamp >= ? GROUP BY portnum ORDER BY cnt DESC"
)
pkt_params = (day_ago,)
async with self.db.execute(pkt_query, pkt_params) as cursor:
stats["packet_type_breakdown"] = {(row[0] or "?"): row[1] async for row in cursor}
return stats

View file

@ -106,7 +106,8 @@ class WebServer:
nodes = await self.db.get_all_nodes()
await ws.send_str(json.dumps({"type": "initial", "data": nodes}))
stats = await self.db.get_stats()
my_id = self.bot.get_my_node_id() if self.bot else None
stats = await self.db.get_stats(my_node_id=my_id)
stats["version"] = config.get("version", "0.0.0")
if self.bot:
stats["uptime"] = self.bot.get_uptime()
@ -155,7 +156,8 @@ class WebServer:
return web.json_response(packets)
async def _api_stats(self, request: web.Request) -> web.Response:
stats = await self.db.get_stats()
my_id = self.bot.get_my_node_id() if self.bot else None
stats = await self.db.get_stats(my_node_id=my_id)
stats["version"] = config.get("version", "0.0.0")
if self.bot:
stats["uptime"] = self.bot.get_uptime()