feat: v0.2.4 - Add /mesh command for mesh network overview
Shows total/online nodes, active 24h, positions, hop distribution, and top 3 hardware models. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a1fe0a297d
commit
b1e08ab720
|
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
## [0.2.4] - 2026-02-15
|
||||
### Added
|
||||
- Neuer Befehl /mesh - zeigt Mesh-Netzwerk-Infos (Nodes online/gesamt, aktiv 24h, Positionen, Hop-Verteilung, Top-Hardware)
|
||||
|
||||
## [0.2.3] - 2026-02-15
|
||||
### Added
|
||||
- Kommando-Tracking in der Datenbank (neue Tabelle `commands`)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: "0.2.3"
|
||||
version: "0.2.4"
|
||||
|
||||
bot:
|
||||
name: "MeshDD-Bot"
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ class MeshBot:
|
|||
f"{prefix}stats - Statistiken\n"
|
||||
f"{prefix}uptime - Laufzeit\n"
|
||||
f"{prefix}weather - Wetter\n"
|
||||
f"{prefix}mesh - Mesh-Netzwerk\n"
|
||||
f"{prefix}help - Diese Hilfe"
|
||||
)
|
||||
|
||||
|
|
@ -200,6 +201,9 @@ class MeshBot:
|
|||
f"Anfragen: {stats['total_commands']}"
|
||||
)
|
||||
|
||||
elif cmd == f"{prefix}mesh":
|
||||
response = await self._get_mesh_info()
|
||||
|
||||
elif cmd == f"{prefix}uptime":
|
||||
response = f"⏱️ Uptime: {self._format_uptime()}"
|
||||
|
||||
|
|
@ -232,6 +236,40 @@ class MeshBot:
|
|||
parts.append(f"{seconds}s")
|
||||
return " ".join(parts)
|
||||
|
||||
async def _get_mesh_info(self) -> str:
|
||||
nodes = await self.db.get_all_nodes()
|
||||
total = len(nodes)
|
||||
now = time.time()
|
||||
online = sum(1 for n in nodes if n.get("last_seen") and now - n["last_seen"] < 900)
|
||||
active_24h = sum(1 for n in nodes if n.get("last_seen") and now - n["last_seen"] < 86400)
|
||||
with_pos = sum(1 for n in nodes if n.get("lat") and n.get("lon"))
|
||||
|
||||
# Hop distribution
|
||||
hop_counts = {}
|
||||
for n in nodes:
|
||||
h = n.get("hop_count")
|
||||
if h is not None:
|
||||
hop_counts[h] = hop_counts.get(h, 0) + 1
|
||||
hop_str = ", ".join(f"{k}h:{v}" for k, v in sorted(hop_counts.items()))
|
||||
|
||||
# Hardware distribution (top 3)
|
||||
hw_counts = {}
|
||||
for n in nodes:
|
||||
hw = n.get("hw_model")
|
||||
if hw:
|
||||
hw_counts[hw] = hw_counts.get(hw, 0) + 1
|
||||
top_hw = sorted(hw_counts.items(), key=lambda x: -x[1])[:3]
|
||||
hw_str = ", ".join(f"{hw}:{cnt}" for hw, cnt in top_hw)
|
||||
|
||||
return (
|
||||
f"🕸️ Mesh-Netzwerk:\n"
|
||||
f"Nodes: {total} ({online} online)\n"
|
||||
f"Aktiv 24h: {active_24h}\n"
|
||||
f"Mit Position: {with_pos}\n"
|
||||
f"Hops: {hop_str or '-'}\n"
|
||||
f"Hardware: {hw_str or '-'}"
|
||||
)
|
||||
|
||||
async def _get_weather(self, from_id: str) -> str:
|
||||
node = await self.db.get_node(from_id)
|
||||
fallback = False
|
||||
|
|
|
|||
Loading…
Reference in a new issue