@@ -55,24 +55,25 @@ public Table PrintNodesTable(bool compactTable = false)
5555 {
5656 var table = new Table ( ) ;
5757 table . Expand ( ) ;
58- table . Border ( TableBorder . Rounded ) ;
58+ table . Border ( compactTable ? TableBorder . Minimal : TableBorder . Rounded ) ;
5959 table . BorderColor ( StyleResources . MESHTASTIC_GREEN ) ;
6060 table . Centered ( ) ;
6161 if ( compactTable )
6262 table . AddColumns ( "Name" , "Latitude" , "Longitude" , "Battery" , "SNR" , "Last Heard" ) ;
63- else
64- table . AddColumns ( "ID#" , "Name" , "Latitude" , "Longitude" , "Battery" , "Air Util" , "Ch. Util" , "SNR" , "Last Heard" ) ;
63+ else
64+ table . AddColumns ( "ID#" , "Name" , "Latitude" , "Longitude" , "Battery" , "Air Util" , "Ch. Util" , "SNR" , "Last Heard" ) ;
6565
6666 foreach ( var node in container . Nodes )
6767 {
6868 if ( compactTable )
6969 {
70- table . AddRow ( container . GetNodeDisplayName ( node . Num , hideNodeNum : true ) ,
71- ( node . Position ? . LatitudeI * 1e-7 ?? 0 ) . ToString ( "N6" ) ?? String . Empty ,
72- ( node . Position ? . LongitudeI * 1e-7 ?? 0 ) . ToString ( "N6" ) ?? String . Empty ,
73- $ "{ node . DeviceMetrics ? . BatteryLevel } %",
74- node . Snr . ToString ( ) ,
75- DisplayRelativeTime ( new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( node . LastHeard ) ) ) ;
70+ table . AddRow (
71+ new Text ( container . GetNodeDisplayName ( node . Num , hideNodeNum : true ) , new Style ( GetColorFromNum ( node . Num ) ) ) ,
72+ new Text ( ( node . Position ? . LatitudeI * 1e-7 ?? 0 ) . ToString ( "N6" ) ?? String . Empty ) ,
73+ new Text ( ( node . Position ? . LongitudeI * 1e-7 ?? 0 ) . ToString ( "N6" ) ?? String . Empty ) ,
74+ new Text ( $ "{ node . DeviceMetrics ? . BatteryLevel } %") ,
75+ new Text ( node . Snr . ToString ( ) ) ,
76+ new Text ( new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( node . LastHeard ) . AsTimeAgo ( ) ) ) ;
7677 }
7778 else
7879 {
@@ -84,44 +85,20 @@ public Table PrintNodesTable(bool compactTable = false)
8485 $ "{ node . DeviceMetrics ? . AirUtilTx . ToString ( "N2" ) } %" ?? String . Empty ,
8586 $ "{ node . DeviceMetrics ? . ChannelUtilization . ToString ( "N2" ) } %" ?? String . Empty ,
8687 node . Snr . ToString ( ) ,
87- DisplayRelativeTime ( new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( node . LastHeard ) ) ) ;
88+ new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( node . LastHeard ) . AsTimeAgo ( ) ) ;
8889 }
8990 }
9091 return table ;
9192 }
9293
93- private static string DisplayRelativeTime ( DateTime dateTime )
94+ public Panel PrintNodesPanel ( )
9495 {
95- TimeSpan span = DateTime . Now . Subtract ( dateTime ) ;
96-
97- int dayDiff = ( int ) span . TotalDays ;
98-
99- int secDiff = ( int ) span . TotalSeconds ;
100-
101- if ( dayDiff >= 31 )
102- return "A long time ago" ;
103-
104- if ( dayDiff == 0 )
96+ return new Panel ( PrintNodesTable ( true ) )
10597 {
106- if ( secDiff < 60 )
107- return "just now" ;
108- if ( secDiff < 120 )
109- return "1 minute ago" ;
110- if ( secDiff < 3600 )
111- return $ "{ Math . Floor ( ( double ) secDiff / 60 ) } minutes ago";
112- if ( secDiff < 7200 )
113- return "1 hour ago" ;
114- if ( secDiff < 86400 )
115- return $ "{ Math . Floor ( ( double ) secDiff / 3600 ) } hours ago";
116- }
117- if ( dayDiff == 1 )
118- return "yesterday" ;
119- if ( dayDiff < 7 )
120- return $ "{ dayDiff } days ago";
121- if ( dayDiff < 31 )
122- return $ "{ Math . Ceiling ( ( double ) dayDiff / 7 ) } weeks ago";
123-
124- return String . Empty ;
98+ Header = new PanelHeader ( "Nodes" ) ,
99+ Expand = true ,
100+ BorderStyle = new Style ( StyleResources . MESHTASTIC_GREEN )
101+ } ;
125102 }
126103
127104
@@ -303,20 +280,43 @@ public void PrintRoute(RepeatedField<uint> route)
303280 AnsiConsole . Write ( root ) ;
304281 }
305282 }
306- public BarChart PrintTrafficChart ( )
283+
284+ public Panel PrintTrafficCharts ( )
307285 {
308286 var myInfo = container . Nodes . FirstOrDefault ( n => n . Num == container . MyNodeInfo . MyNodeNum ) ;
309- var airTimeStats = myInfo != null ? $ "(Ch. Util { myInfo . DeviceMetrics . ChannelUtilization : N2} % / Airtime { myInfo . DeviceMetrics . AirUtilTx : N2} %)" : String . Empty ;
310-
311- return new BarChart ( )
312- . Label ( $ "[green bold underline]Mesh traffic by Port { airTimeStats } [/]")
313- . CenterLabel ( )
314- . AddItem ( "Admin" , GetMessageCountByPortNum ( PortNum . AdminApp ) , Color . Red )
315- . AddItem ( "Text" , GetMessageCountByPortNum ( PortNum . TextMessageApp ) + GetMessageCountByPortNum ( PortNum . TextMessageCompressedApp ) , Color . Yellow )
316- . AddItem ( "Position" , GetMessageCountByPortNum ( PortNum . PositionApp ) , Color . Green )
317- . AddItem ( "Waypoint" , GetMessageCountByPortNum ( PortNum . WaypointApp ) , Color . Pink1 )
318- . AddItem ( "NodeInfo" , GetMessageCountByPortNum ( PortNum . NodeinfoApp ) , Color . White )
319- . AddItem ( "Telemetry" , GetMessageCountByPortNum ( PortNum . TelemetryApp , ignoreLocal : true ) , Color . Blue ) ;
287+ var airTimeStats = myInfo != null ? $ "Ch. Util { myInfo . DeviceMetrics . ChannelUtilization : N2} % / Airtime { myInfo . DeviceMetrics . AirUtilTx : N2} %" : String . Empty ;
288+
289+ var byNodeChart = new BreakdownChart ( )
290+ . FullSize ( ) ;
291+
292+ foreach ( var node in container . Nodes . Select ( n => new { n . Num , Name = container . GetNodeDisplayName ( n . Num , hideNodeNum : true ) , Count = container . FromRadioMessageLog . Count ( fr => fr . Packet ? . From == n . Num ) } ) )
293+ {
294+ byNodeChart . AddItem ( node . Name , node . Count , GetColorFromNum ( node . Num ) ) ;
295+ }
296+
297+ var charts = new Rows ( new Text ( String . Empty ) ,
298+ new Text ( airTimeStats ) . Centered ( ) ,
299+ new Text ( String . Empty ) ,
300+ new Text ( "By Port:" ) . Centered ( ) ,
301+ new BarChart ( )
302+ . AddItem ( "Admin" , GetMessageCountByPortNum ( PortNum . AdminApp ) , Color . Red )
303+ . AddItem ( "Text" , GetMessageCountByPortNum ( PortNum . TextMessageApp ) + GetMessageCountByPortNum ( PortNum . TextMessageCompressedApp ) , Color . Yellow )
304+ . AddItem ( "Routing" , GetMessageCountByPortNum ( PortNum . RoutingApp ) , Color . Grey )
305+ . AddItem ( "Position" , GetMessageCountByPortNum ( PortNum . PositionApp ) , Color . Green )
306+ . AddItem ( "Waypoint" , GetMessageCountByPortNum ( PortNum . WaypointApp ) , Color . Pink1 )
307+ . AddItem ( "NodeInfo" , GetMessageCountByPortNum ( PortNum . NodeinfoApp ) , Color . White )
308+ . AddItem ( "Telemetry" , GetMessageCountByPortNum ( PortNum . TelemetryApp , ignoreLocal : true ) , Color . Blue ) ,
309+ new Text ( String . Empty ) ,
310+ new Text ( "By Node:" ) . Centered ( ) ,
311+ byNodeChart ) ;
312+
313+ var panel = new Panel ( charts )
314+ {
315+ Header = new PanelHeader ( $ "Mesh traffic") ,
316+ Expand = true ,
317+ BorderStyle = new Style ( StyleResources . MESHTASTIC_GREEN )
318+ } ;
319+ return panel ;
320320 }
321321
322322 public Panel PrintMessagesPanel ( )
@@ -325,18 +325,22 @@ public Panel PrintMessagesPanel()
325325 . Where ( fr => fr . Packet ? . Decoded ? . Portnum == PortNum . TextMessageApp || fr . Packet ? . Decoded ? . Portnum == PortNum . TextMessageCompressedApp )
326326 . Select ( fr => new
327327 {
328- from = $ "[green bold underline]{ container . GetNodeDisplayName ( fr . Packet . From , hideNodeNum : true ) } [/]",
328+ time = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( fr . Packet . RxTime ) . AsTimeAgo ( ) ,
329+ num = fr . Packet . From ,
330+ from = $ "[bold]{ container . GetNodeDisplayName ( fr . Packet . From , hideNodeNum : true ) } [/]",
329331 message = fr . Packet ? . Decoded ? . Payload . ToStringUtf8 ( )
330332 } )
331333 . SelectMany ( text =>
332334 {
333335 return new List < IRenderable > ( ) {
334- new Rule ( text . from ) ,
336+ new Rule ( $ "{ text . from } - { text . time } ")
337+ {
338+ Style = new Style ( GetColorFromNum ( text . num ) )
339+ } ,
335340 new Text ( text . message ! )
336341 } ;
337342 } ) ;
338343
339-
340344 if ( ! texts . Any ( ) )
341345 {
342346 return new Panel ( "Messages" )
@@ -356,8 +360,13 @@ public Panel PrintMessagesPanel()
356360 return panel ;
357361 }
358362
363+ private Color GetColorFromNum ( uint num )
364+ {
365+ return new Color ( BitConverter . GetBytes ( num ) [ 0 ] , BitConverter . GetBytes ( num ) [ 1 ] , BitConverter . GetBytes ( num ) [ 2 ] ) ;
366+ }
367+
359368 private int GetMessageCountByPortNum ( PortNum portNum , bool ignoreLocal = false )
360369 {
361- return container . FromRadioMessageLog . Count ( fr => fr . Packet ? . Decoded ? . Portnum == portNum && ( ! ignoreLocal || fr . Packet ? . From = = container . MyNodeInfo . MyNodeNum ) ) ;
370+ return container . FromRadioMessageLog . Count ( fr => fr . Packet ? . Decoded ? . Portnum == portNum && ( ! ignoreLocal || fr . Packet ? . From ! = container . MyNodeInfo . MyNodeNum ) ) ;
362371 }
363372}
0 commit comments