From 6e1fc0e052ae914bd1cbae1082db42a2c940ae26 Mon Sep 17 00:00:00 2001
From: jkerdreux-imt <jerome.kerdreux@imt-atlantique.fr>
Date: Sat, 21 Dec 2024 00:42:10 +0100
Subject: [PATCH] Added ncurses support

- Added most verbose devices
- Add nice ncurses / tabulate display
- Added MSG rate
---
 scripts/msg_stats.py | 48 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/scripts/msg_stats.py b/scripts/msg_stats.py
index 3bde7ee4..79732151 100644
--- a/scripts/msg_stats.py
+++ b/scripts/msg_stats.py
@@ -1,8 +1,12 @@
 import asyncio
 import time
+import curses
+from tabulate import tabulate
 
 from xaal.lib import AsyncEngine, Message, MessageAction
 
+FMT = "rounded_grid"
+
 MSG_STATS = {
     "total": 0,
     "alive": 0,
@@ -55,24 +59,58 @@ def msg_count(msg: Message):
         MSG_STATS["reply"] += 1
     if msg.is_attributes_change():
         MSG_STATS["attributes_change"] += 1
+        return
     if msg.is_notify():
         MSG_STATS["notify"] += 1
 
 
-async def show():
+async def on_start():
+    screen = curses.initscr()
+    curses.noecho()
+    curses.cbreak()
+
+    curses.curs_set(0)
+    screen.clear()
+
     t0 = time.time()
     while 1:
-        await asyncio.sleep(5)
+        screen.clear()
         t = time.time() - t0
-        print(MSG_STATS)
-        print(DEVICE_STATS)
+        screen.addstr(1, 1, f"xAAL Messages stats since {time.ctime(t0)}")
+        r = []
+        for k, v in MSG_STATS.items():
+            # count the nb of messages / s
+            cnt = round(v / t, 1)
+            r.append([k, v, cnt])
+        data = tabulate(r, headers=["MSG Type", "Total", "Rate"], tablefmt=FMT)
+        for i, line in enumerate(data.splitlines()):
+            screen.addstr(3 + i, 1, line)
+
+        sort = sorted(DEVICE_STATS.items(), key=lambda x: x[1], reverse=True)[0:10]
+        # display the 10 most active devices, if any
+        r = []
+        for k, v in sort:
+            r.append([k, v])
+        data = tabulate(r, headers=["Device ADDR", "Total", "Rate"], tablefmt=FMT)
+        for i, line in enumerate(data.splitlines()):
+            screen.addstr(3 + i, 50, line)
+        screen.refresh()
+        await asyncio.sleep(5)
+
+
+def on_stop():
+    curses.echo()
+    curses.nocbreak()
+    curses.endwin()
 
 
 def run():
     eng = AsyncEngine()
     eng.disable_msg_filter()
     eng.subscribe(count)
-    eng.on_start(show)
+
+    eng.on_start(on_start)
+    eng.on_start(on_start)
     eng.run()
 
 
-- 
GitLab