Table of Contents
This is a post about writing code to run on a computer or server that then connects to a meshtastic node.
Overview
meshtastic supports sending data as either a protobuf (protocol buffer, a universal data standard set by google (it's basically just a struct)) or as a raw binary. These packets can be directed to certain endpoints. On connection to the node we have a certain expected packet exchange before we enter normal operations where we send messages and listen to messages.
HTTP Endpoints
endpoint | permissions | purpose |
---|---|---|
fromradio | read | this is the endpoint for data travelling from the node to the client. it is a FIFO queue. |
toradio | write | this is the endpoint for data travelling from the client to the node |
fromnum | read, notify, write | this is the number of the message currently waiting in the fromradio endpoint. note that this number should only increase, unless the node is rebooted. |
log | notify | this is where debug messages go |
pubsub
The python library uses a message bus to handle all meshtastic events. We then create a callback and subscribe it to the relevant "topic". Each topic is a string with dot notation to indicate levels of specificity, for example: "meshtastic.receive.text"
is the topic for only text packets, "meshtastic.receive"
is the topic for all packets, "meshtastic"
is the topic for all events.
import pubsub
import meshtastic.serial_interface
connection = meshtastic.serial_interface.SerialInterface()
# we need to establish a connection in order to have the bus receive messages
def callback(packet, interface):
print(packet)
pub.subscribe(callback, "meshtastic.receive") #callback called on any packet
The packet takes the form of a dictionary, but the fields of that dictionary DON'T APPEAR TO BE DOCUMENTED ANYWHERE since technically anything could be using meshtastic as a transport layer the responsibility to document anything is passed on. (look at the portnums for more details, essentially portnum indicates what protocol the packet is implementing)
example packets
below are two example packet dictionaries so you can see the sort of fields they have. Notice that only the 'decoded'
field changes. Also notice that 'portnum'
tells you what kind of data it is (Although the actual list of fields for each portnum isn't necessarily listed anywhere). See here for a full list.
TELEMETRY
{
'from': <id>,
'to': <id>,
'decoded': {
'portnum': 'TELEMETRY_APP',
'payload': b'\r*\x02\x11\x00\x12\x13\x08e\x15L7\xc9@\x1d\xb8\x1ee?%\x08et<(B',
'bitfield': 1,
'telemetry': {
'time': 1114666,
'deviceMetrics': {
'batteryLevel': 101,
'voltage': 6.288,
'channelUtilization': 0.895,
'airUtilTx': 0.014916666,
'uptimeSeconds': 66
},
'raw':
time: 1114666
device_metrics {
battery_level: 101,
voltage: 6.288000106811523,
channel_utilization: 0.8949999809265137,
air_util_tx: 0.014916665852069855,
uptime_seconds: 66
}
}
},
'id': <id>,
'hopLimit': 5,
'priority': 'BACKGROUND',
'hopStart': 5,
'relayNode': 224,
'raw':
from: <id>
to: <id>
decoded {
portnum: TELEMETRY_APP
payload: "\r*\002\021\000\022\023\010e\025L7\311@\035\270\036e?%\010et<(B"
bitfield: 1
}
id: <id>
hop_limit: 5
priority: BACKGROUND
hop_start: 5
relay_node: 224
'fromId': '<id>',
'toId': '^all'
}
TEXT MESSAGE
{
'from': <id>,
'to': <id>,
'decoded': {
'portnum': 'TEXT_MESSAGE_APP',
'payload': b'hi',
'bitfield': 0,
'text': 'hi'
},
'id': 944823075,
'rxTime': 1758739701,
'rxSnr': 6.5,
'hopLimit': 7,
'wantAck': True,
'rxRssi': -51,
'hopStart': 7,
'publicKey': 'FyvMvBZ1TRRWUNsZkDPX7JTW4ZuEymOMxiTRSrsu9Bg=',
'pkiEncrypted': True,
'raw':
from: <id>
to: <id>
decoded {
portnum: TEXT_MESSAGE_APP
payload: "hi"
bitfield: 0
}
id: <id>
rx_time: 1758739701
rx_snr: 6.5
hop_limit: 7
want_ack: true
rx_rssi: -51
hop_start: 7
public_key: "\027+\314\274\026uM\024VP\333\031\2203\327\354\224\326\341\233\204\312c\214\306$\321J\273.\364\030"
pki_encrypted: true,
'fromId': '<id>',
'toId': '<id>'
}
links
since I found the documentation pretty frustrating to navigate so here's a list of documentation pages that have been actually useful. https://meshtastic.org/docs/configuration/radio/device/ https://github.com/meshtastic/python/blob/master/TODO.md https://python.meshtastic.org/ https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.PortNum