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 # 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 ## [0.8.10] - 2026-02-19
### Added ### Added

View file

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

View file

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

View file

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

View file

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