From 05352b93db9a5890bad277c5c8d09a608b6412f2 Mon Sep 17 00:00:00 2001 From: tapedeck Date: Wed, 10 Jun 2026 09:46:43 -0700 Subject: [PATCH 1/2] fix: include origin and dest in traceroute path, fix embed edit crash --- mqttbridge/mqtt.py | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/mqttbridge/mqtt.py b/mqttbridge/mqtt.py index 66f965e..94e4871 100644 --- a/mqttbridge/mqtt.py +++ b/mqttbridge/mqtt.py @@ -1254,16 +1254,30 @@ async def process_traceroute(self, mp, se): route_discovery.ParseFromString(mp.decoded.payload) with self.get_db() as conn: c = conn.cursor() - for hop_num in route_discovery.route: - hop_str = str(hop_num) - c.execute("SELECT short_name, node_id_hex FROM nodes WHERE node_id = ?", (hop_str,)) + + def get_node_name(n_id): + c.execute("SELECT short_name, node_id_hex FROM nodes WHERE node_id = ?", (str(n_id),)) node_row = c.fetchone() if node_row and node_row[0]: - route_names.append(node_row[0]) + return node_row[0] elif node_row and node_row[1]: - route_names.append(node_row[1]) - else: - route_names.append(f"!{format(hop_num, '08x')}") + return node_row[1] + return f"!{format(n_id, '08x')}" + + # Add origin (the node that sent the original trace request) + trace_origin = getattr(mp, "to", 0) + if trace_origin: + route_names.append(get_node_name(trace_origin)) + + # Add intermediaries + for hop_num in route_discovery.route: + route_names.append(get_node_name(hop_num)) + + # Add destination (the node that replied to the trace) + trace_dest = getattr(mp, "from", 0) + if trace_dest: + route_names.append(get_node_name(trace_dest)) + except Exception as e: print(f"Error parsing RouteDiscovery: {e}") @@ -1273,8 +1287,8 @@ async def process_traceroute(self, mp, se): try: original_msg = await self.traceroute_channel.fetch_message(discord_msg_id) if original_msg.embeds: - # Create a new embed from the original to ensure safe editing - new_embed = discord.Embed.from_dict(original_msg.embeds[0].to_dict()) + # Create a copy of the embed to ensure safe editing + new_embed = original_msg.embeds[0].copy() # Update Description desc = new_embed.description @@ -1284,12 +1298,18 @@ async def process_traceroute(self, mp, se): desc = "Direction: REPLY (Complete)" new_embed.description = desc - new_embed.add_field(name="Route Taken", value=route_display, inline=False) + # Update or add the "Route Taken" field + route_field_index = next((index for (index, field) in enumerate(new_embed.fields) if field.name == "Route Taken"), None) + if route_field_index is not None: + new_embed.set_field_at(route_field_index, name="Route Taken", value=route_display, inline=False) + else: + new_embed.add_field(name="Route Taken", value=route_display, inline=False) + await original_msg.edit(embed=new_embed) # Flag that we successfully edited the message else: discord_msg_id = None # Fallback to new message - except (discord.NotFound, discord.HTTPException) as e: + except Exception as e: print(f"Error editing original traceroute message: {e}") # Fallback if message not found or edit fails discord_msg_id = None From 40ac9b60250d2fcacbf3ad7159b3fc989ea72e86 Mon Sep 17 00:00:00 2001 From: tapedeck Date: Wed, 10 Jun 2026 10:11:36 -0700 Subject: [PATCH 2/2] feat: include SNR data in traceroute display --- mqttbridge/mqtt.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/mqttbridge/mqtt.py b/mqttbridge/mqtt.py index 94e4871..179e41e 100644 --- a/mqttbridge/mqtt.py +++ b/mqttbridge/mqtt.py @@ -1249,7 +1249,6 @@ async def process_traceroute(self, mp, se): # Parse RouteDiscovery route_discovery = mesh_pb2.RouteDiscovery() - route_names = [] try: route_discovery.ParseFromString(mp.decoded.payload) with self.get_db() as conn: @@ -1264,24 +1263,34 @@ def get_node_name(n_id): return node_row[1] return f"!{format(n_id, '08x')}" - # Add origin (the node that sent the original trace request) trace_origin = getattr(mp, "to", 0) + trace_dest = getattr(mp, "from", 0) + + # Get nodes in order + nodes_in_order = [] if trace_origin: - route_names.append(get_node_name(trace_origin)) - - # Add intermediaries + nodes_in_order.append(get_node_name(trace_origin)) for hop_num in route_discovery.route: - route_names.append(get_node_name(hop_num)) - - # Add destination (the node that replied to the trace) - trace_dest = getattr(mp, "from", 0) + nodes_in_order.append(get_node_name(hop_num)) if trace_dest: - route_names.append(get_node_name(trace_dest)) + nodes_in_order.append(get_node_name(trace_dest)) + + # Check if we have matching SNR data + snrs = route_discovery.snr_towards + + if len(snrs) == len(route_discovery.route) + 1 and len(nodes_in_order) >= 2: + # Format with SNR: Node1 --(snr)→ Node2 + route_parts = [nodes_in_order[0]] + for i, snr in enumerate(snrs): + route_parts.append(f"--({snr})→ {nodes_in_order[i+1]}") + route_display = " ".join(route_parts) + else: + # Fallback without SNR + route_display = " → ".join(nodes_in_order) if nodes_in_order else "Unknown" except Exception as e: print(f"Error parsing RouteDiscovery: {e}") - - route_display = " → ".join(route_names) if route_names else "Unknown" + route_display = "Unknown" if discord_msg_id and self.traceroute_channel: try: