meshtastic-map
meshtastic-map copied to clipboard
Neighbor info over LoRa deprecation, code for decoding traceroute as links (oriented graph) from this project db.
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();
}
oh that's interesting there's a different approach I've got, but might see if I can merge them together
Let me know we can easily test this on clean datasets of the Paris mesh, there is 93 nodes and 543 link active here
I've implemented something similar for my fork, https://map.sthlm-mesh.se. I'm not yet sure about its usefulness. Feel free to check it out, you need to enable it as a layer, and there is a setting for maximum age.
I added traceroute link date, here is my complete backend file to make JSON. Easy to convert for other usecases with LLM