Because neighbor info propagation on LoRa is deprecated on Meshtastic now (but still available via MQTT for direct neighbors), we must use Traceroute request frames to build the network graph topology.
Here’s my PHP code to use on the project database to get all links with SNR. The limitation is the last hop, as it’s from the receiver’s perspective.
This is the backend code I use on my network topology grapher (https://www.serveurperso.com/) – sharing it here in case it can help anyone port it to JavaScript. I added comments in English to clarify functionality. This code works in real-world scenarios.
$links = [];
// Query to fetch traceroute data with various metrics
$result = $MYSQLI->query(
"SELECT UNIX_TIMESTAMP(updated_at) AS updated_at, `from`, `to`, route, route_back, snr_towards, snr_back, want_response FROM traceroutes ORDER BY updated_at ASC"
);
if ($result) {
while ($row = $result->fetch_assoc()) {
// Check if the entry is older than 168 hours (7 days), skip if so
$updatedat = (int)$row["updated_at"];
if ($now - $updatedat > 168 * 3600) {
continue;
}
// Skip entries where 'want_response' indicates this is a request packet
$wantresponse = (int)$row["want_response"];
if ($wantresponse == 1) {
continue;
}
// Retrieve 'from' and 'to' node IDs and confirm they are valid nodes in the filtered set
$to = (int)$row["from"];
$from = (int)$row["to"];
if (!isset($filterednodes[$from]) || !isset($filterednodes[$to])) {
continue;
}
// Decode route and SNR data
$route = json_decode($row["route"], true);
$route_back = json_decode($row["route_back"], true);
$snr_towards = json_decode($row["snr_towards"], true);
$snr_back = json_decode($row["snr_back"], true);
// Case 1: Direct link without intermediate hops
if (empty($route) && isset($snr_towards[0]) && $snr_towards[0] != -128) {
// Remove any existing duplicate link and add a direct link with SNR
foreach ($links as $key => $link) {
if ($link["source"] == $from && $link["target"] == $to) {
unset($links[$key]);
break;
}
}
$links[] = [
"source" => $from,
"target" => $to,
"snr" => $snr_towards[0] / 4
];
}
// Case 2: Multi-hop route with forward SNR values
if (!empty($route)) {
$previousnode = $from;
foreach ($route as $i => $nextnode) {
if (!isset($filterednodes[$previousnode]) || !isset($filterednodes[$nextnode])) {
continue;
}
// Remove any existing duplicate link and add new link
foreach ($links as $key => $link) {
if ($link["source"] == $previousnode && $link["target"] == $nextnode) {
unset($links[$key]);
break;
}
}
if (isset($snr_towards[$i]) && $snr_towards[$i] != -128) {
$links[] = [
"source" => $previousnode,
"target" => $nextnode,
"snr" => $snr_towards[$i] / 4
];
}
$previousnode = $nextnode;
}
// Add final link to the destination if SNR is available
if (isset($filterednodes[$previousnode]) && isset($filterednodes[$to]) && isset($snr_towards[count($route)]) && $snr_towards[count($route)] != -128) {
foreach ($links as $key => $link) {
if ($link["source"] == $previousnode && $link["target"] == $to) {
unset($links[$key]);
break;
}
}
$links[] = [
"source" => $previousnode,
"target" => $to,
"snr" => $snr_towards[count($route)] / 4
];
}
}
// Case 3: Multi-hop route with backward SNR values (route_back)
if (!empty($route_back)) {
$previousnode = $to;
foreach ($route_back as $i => $nextnode) {
if (!isset($filterednodes[$previousnode]) || !isset($filterednodes[$nextnode])) {
continue;
}
// Remove any existing duplicate link and add backward link
foreach ($links as $key => $link) {
if ($link["source"] == $previousnode && $link["target"] == $nextnode) {
unset($links[$key]);
break;
}
}
if (isset($snr_back[$i]) && $snr_back[$i] != -128) {
$links[] = [
"source" => $previousnode,
"target" => $nextnode,
"snr" => $snr_back[$i] / 4
];
}
$previousnode = $nextnode;
}
}
}
$result->free();
}
Because neighbor info propagation on LoRa is deprecated on Meshtastic now (but still available via MQTT for direct neighbors), we must use Traceroute request frames to build the network graph topology.
Here’s my PHP code to use on the project database to get all links with SNR. The limitation is the last hop, as it’s from the receiver’s perspective.
This is the backend code I use on my network topology grapher (https://www.serveurperso.com/) – sharing it here in case it can help anyone port it to JavaScript. I added comments in English to clarify functionality. This code works in real-world scenarios.