A desktop app for my Meshtastic and MeshCore radios

from a human

Lately I've been messing around with meshtastic and meshcore. I made a web interface to interact with the cards I bought. Meshtastic has a lot of people nearby. Meshcore does not. Been fun.

I have two LoRa cards, both Seeed Tracker T1000-E. One runs Meshtastic, the other runs MeshCore. Instead of the phone apps I built a web app that drives both of them over Bluetooth from the always-on MacBook in my apartment.

A companion radio takes one Bluetooth connection at a time, so whichever phone is holding it is the only client that exists, and the two networks have separate apps that know nothing about each other. The Mac is always on, so it holds both links, logs everything to SQLite, and I reach the page over Tailscale from whatever I happen to be using.

The app on the Meshtastic radio: chats and nodes on the left, the public channel in the middle, radio instruments across the top

A switcher in the top left picks the radio and the rest of the page follows it. Both links stay up whichever one you are looking at, and each radio keeps its own conversations and unread counts.

Messaging is channels and direct messages, with delivery status that says what actually happened. Meshtastic tells a neighbour repeating your packet apart from the destination acknowledging it. MeshCore acknowledges direct messages but not channel messages, so a DM goes from sent to delivered, or retries twice and gives up.

The left column is who is out there, with signal, hop count, battery and when each node was last heard. The Meshtastic radio holds 92 nodes in its own table while the app has logged 263 it has heard, because the radio's table is smaller than the mesh around it. Anyone broadcasting a position lands on a map. MeshCore has no node table at all, just contacts it learns from adverts, so that column means something different depending on the radio.

Under Activity is every packet the radio hears, one line each, with the decoded payload underneath if you click it. 21,409 of them so far. This is the part I use most, and it is how you tell a quiet mesh apart from a broken radio.

Each radio also gets the tools only it has. Meshtastic gets traceroute, which shows which relays carried a packet and how well each one heard the hop before it, and a button that asks a store and forward server out on the mesh to replay channel history the radio itself never kept. MeshCore gets adverts, either zero hop or flooded, and a probe that asks radios in range to answer now instead of whenever they next advertise.

The same app on the MeshCore radio: contacts instead of nodes, and the modem plan in the header

The server is FastAPI plus the meshtastic and meshcore Python libraries, the page is plain HTML and JavaScript with no build step, and each radio gets its own SQLite file. The MeshCore side has no contacts in it yet, because nothing near me has advertised on that network since I turned it on.