Introduction

Le projet Meshtastic est un réseau maillé, en voici la description tirée du site fr-emcom.com 1.

Meshtastic est un projet qui permet d’utiliser des radios LoRa bon marché pour établir un système de communication hors réseau à longue portée, sans dépendre des infrastructures de communication existantes. Il fonctionne sur les bandes ISM (bande industrielle, scientifique et médicale) sur 433Mhz, 868Mhz et 2,4Ghz. Ce projet met en place un réseau maillé. Meshtastic est entièrement soutenu par la communauté et open source.

Les émetteurs-récepteurs sont communément appelés “noeuds” et peuvent être administrés avec un smartphone ou un ordinateur.

Il est possible de dialoguer avec un noeud via une communication série. Sous Linux, un chemin vers la ressource série apparait au branchement du noeud, dans mon cas j’obtiens /dev/ttyACM0. Un utilitaire Python permet de gérer la configuration du noeud pour tous ses aspects (configuration du module, de la radio, des intervalles de communications,…) 2. Un client web est également disponible à cette fin 3.

Objectif

Dans l’optique de bénéficier d’un client de visualisation local, sans pour autant sortir l’artillerie lourde et Docker (utile pour lancer le client web en local), j’ai opté pour le développement d’une application desktop. C’est aussi pour une compréhension du protocole réseau et des fonctionnalités de Meshtastic que cette petite application a vu le jour. Je souhaite principalement pouvoir superviser l’état du réseau maillé, envoyer des messages, lancer des traceroutes, et bien sûr exporter les données et métriques.

Développement

Utilisant Python3 et PyQt6, on peut proposer une application graphique. Son architecture repose sur un “data store” backend, et certains évènements vont mettre à jour le front-end. Le data store se présente comme une dataclass.

@dataclass
class MeshtasticDataStore:
    device_path: Optional[str] = None
    channels: Optional[List[Channel]] = None
    local_node_config: Optional[MeshtasticNode] = None
    connected: bool = False
    nodes: Dict[str, MeshtasticNode] = field(
        default_factory=dict)  # Dict[node_id, Node object]
    messages: Dict[str, MeshtasticMessage] = field(
        default_factory=dict)  # Dict[message_id, Message object]
[...]

Le thread backend alimente ce store et celui du front-end vient à sont tour en afficher le contenu. Des méthodes sont présentes pour gérer la mise à jour des attributs. La base de données native du noeud Meshtastic nodeDB ne permet pas un rafraichissement en temps-réel et c’est l’une des raisons pour lesquelles j’ai défini une classe dédiée pour décrire un noeud, et également pour enregistrer les séries temporelles radio (SNR, RSSI,…).

@dataclass
class MeshtasticNode:
    long_name: Optional[str] = None
    short_name: Optional[str] = None
    id: Optional[str] = None
    role: Optional[str] = None
    hardware: Optional[str] = None
    lat: Optional[str] = None
    lon: Optional[str] = None
    alt: Optional[str] = None
    batterylevel: Optional[int] = None
    chutil: Optional[str] = None
    txairutil: Optional[str] = None
    rssi: Optional[str] = None
    snr: Optional[str] = None
    neighbors: Optional[List[str]] = None
    hopsaway: Optional[str] = None
    firstseen: Optional[str] = None
    lastseen: Optional[str] = None
    uptime: Optional[int] = None
    is_local: bool = False

La mise à jour globale de l’application se base sur une méthode qui est déclenchée par souscription. Lorsque de nouveaux paquets entrants sont détectés, le store est mis à jour avec leurs propres informations: position, consommation énergétique, identité, télémétrie…

pub.subscribe(self.on_receive, "meshtastic.receive")

Ensuite des signaux Qt comme notify_data(...) ou notify_node(...) se chargent de déclencher une mise à jour de la partie du front-end concernée, et ainsi afficher les nouvelles informations.

Le design de l’application s’est rapidement fait avec QtDesigner, qui comme son nom l’indique, est un outil de conception d’interface graphique.

Remarques diverses

  • La nodeDB n’est pas temps-réel,
  • La gestion des ack est facilité par le packet type ROUTING_APP,
  • La configuration du noeud et de ses voisins est essentielle pour tester le développement correctement,
  • la carte issue du package folium s’intègre bien dans une web view, mais la mise à jour de la carte sans sa recréation totale n’est pas directe.
  • L’affichage temps-réel des informations nécessite des astuces d’affichage graphique.

Conclusion

Après quelques découvertes sur le protocole, les paramètres des noeuds, le cycle de vie des informations (sur l’air et en mémoire), je dispose d’une petite application rapide à lancer qui informe sur l’écosystème local LoRa et Meshastic. Voici un aperçu de l’application, et pour le code, c’est ici 4. Encore beaucoup d’améliorations sont possibles, que ce soit sur la cosmétique ou le fonctionnement interne… A faire évoluer !

Devices Nodes Map Messages