feat: v0.2.5 - Message splitting, improved /mesh readability
- Split long messages at 170 bytes with 1.5s delay between parts - /mesh: proper sections with line breaks and indentation - Hop labels: "Direkt", "1 Hop", "2 Hops" instead of "0h", "1h" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b1e08ab720
commit
077e0032cf
|
|
@ -1,5 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## [0.2.5] - 2026-02-15
|
||||
### Added
|
||||
- Automatisches Aufteilen langer Nachrichten (max 170 Zeichen) mit 1,5s Pause
|
||||
|
||||
### Changed
|
||||
- /mesh Befehl: bessere Lesbarkeit mit Absätzen und Einrückungen
|
||||
- Hop-Verteilung: "Direkt", "1 Hop", "2 Hops" statt "0h", "1h", "2h"
|
||||
|
||||
## [0.2.4] - 2026-02-15
|
||||
### Added
|
||||
- Neuer Befehl /mesh - zeigt Mesh-Netzwerk-Infos (Nodes online/gesamt, aktiv 24h, Positionen, Hop-Verteilung, Top-Hardware)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version: "0.2.4"
|
||||
version: "0.2.5"
|
||||
|
||||
bot:
|
||||
name: "MeshDD-Bot"
|
||||
|
|
|
|||
|
|
@ -208,19 +208,51 @@ class MeshBot:
|
|||
response = f"⏱️ Uptime: {self._format_uptime()}"
|
||||
|
||||
if response:
|
||||
self._send_text(response, channel)
|
||||
await self._send_text(response, channel)
|
||||
await self.db.insert_command(cmd)
|
||||
if self.ws_manager:
|
||||
stats = await self.db.get_stats()
|
||||
await self.ws_manager.broadcast("stats_update", stats)
|
||||
|
||||
def _send_text(self, text: str, channel: int):
|
||||
if self.interface:
|
||||
async def _send_text(self, text: str, channel: int, max_len: int = 170):
|
||||
if not self.interface:
|
||||
return
|
||||
parts = self._split_message(text, max_len)
|
||||
for i, part in enumerate(parts):
|
||||
if i > 0:
|
||||
await asyncio.sleep(1.5)
|
||||
try:
|
||||
self.interface.sendText(text, channelIndex=channel)
|
||||
self.interface.sendText(part, channelIndex=channel)
|
||||
except Exception:
|
||||
logger.exception("Error sending text")
|
||||
|
||||
@staticmethod
|
||||
def _split_message(text: str, max_len: int) -> list[str]:
|
||||
if len(text.encode('utf-8')) <= max_len:
|
||||
return [text]
|
||||
lines = text.split('\n')
|
||||
parts = []
|
||||
current = ""
|
||||
for line in lines:
|
||||
candidate = f"{current}\n{line}" if current else line
|
||||
if len(candidate.encode('utf-8')) > max_len:
|
||||
if current:
|
||||
parts.append(current)
|
||||
if len(line.encode('utf-8')) > max_len:
|
||||
while line:
|
||||
chunk = line[:max_len]
|
||||
while len(chunk.encode('utf-8')) > max_len:
|
||||
chunk = chunk[:-1]
|
||||
parts.append(chunk)
|
||||
line = line[len(chunk):]
|
||||
else:
|
||||
current = line
|
||||
else:
|
||||
current = candidate
|
||||
if current:
|
||||
parts.append(current)
|
||||
return parts
|
||||
|
||||
def _format_uptime(self) -> str:
|
||||
elapsed = int(time.time() - self.start_time)
|
||||
days, remainder = divmod(elapsed, 86400)
|
||||
|
|
@ -250,7 +282,10 @@ class MeshBot:
|
|||
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()))
|
||||
hop_lines = []
|
||||
for k in sorted(hop_counts.keys()):
|
||||
label = "Direkt" if k == 0 else f"{k} Hop{'s' if k > 1 else ''}"
|
||||
hop_lines.append(f" {label}: {hop_counts[k]}")
|
||||
|
||||
# Hardware distribution (top 3)
|
||||
hw_counts = {}
|
||||
|
|
@ -259,16 +294,20 @@ class MeshBot:
|
|||
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)
|
||||
hw_lines = [f" {hw}: {cnt}" for hw, cnt in top_hw]
|
||||
|
||||
return (
|
||||
parts = [
|
||||
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 '-'}"
|
||||
)
|
||||
f"Mit Position: {with_pos}",
|
||||
]
|
||||
if hop_lines:
|
||||
parts.append("📊 Hop-Verteilung:\n" + "\n".join(hop_lines))
|
||||
if hw_lines:
|
||||
parts.append("🔧 Top Hardware:\n" + "\n".join(hw_lines))
|
||||
|
||||
return "\n\n".join(parts)
|
||||
|
||||
async def _get_weather(self, from_id: str) -> str:
|
||||
node = await self.db.get_node(from_id)
|
||||
|
|
|
|||
Loading…
Reference in a new issue