Awesome
Meshtastic Bridge
Connect Meshtastic radio networks using MQTT and HTTP.
WARNING: Work in progress
Requirements
- Command-line install
- Python 3.8
- git
- Outbound HTTPS (TCP/443) or SSH (TCP/22) access to github.com
- Docker-based install
- Docker
- Meshtastic radio device:
- The IP address or Serial devPath (micro USB cable needed for serial access) of a Meshtastic device
- MQTT server:
- The domain name of the server
- The port (e.g. 1883)
Refer to https://meshtastic.org/docs/settings/config/wifi#wifi-client for details on how to configure a Meshtastic device to use wifi and expose a TCP address.
Command-line installation
Download the code and install it onto a system:
$ git clone https://github.com/geoffwhittington/meshtastic-bridge.git
Create a Python virtual environment
$ python3 -m venv meshtastic-bridge
Install the bridge dependencies
$ cd meshtastic-bridge
$ source bin/activate
$ pip install -r requirements.txt
Docker installation
There is nothing to install with Docker, the bridge is downloaded at the time it is run
Configuration
The bridge is configured using a YAML file config.yaml
. It is composed of three sections, devices
, mqtt_servers
and pipelines
.
An example config.yaml
is provided below:
devices:
- name: remote
tcp: 192.168.86.39
active: true
mqtt_servers:
- name: external
server: broker.hivemq.com
port: 1883
topic: meshtastic/radio-network1
pipelines:
mqtt-to-radio:
- decrypt_filter:
key: '/home/user/keys/key.pem'
- radio_message_plugin:
device: remote
pipelines:
radio-to-mqtt:
- encrypt_filter:
key: '/home/user/keys/cert.pem'
- mqtt_plugin:
name: external
topic: mesh/tastic
devices
is a list of radios the bridge listens for packets or to where it can send packets.
- name Reference given to a radio that is used elsewhere in the
pipelines
configuration. For example,my_radio
- tcp The IP address of the radio. For example,
192.168.0.1
(Optional) - serial The name of the serial device attached to the radio. For example,
/dev/ttyUSB0
(Optional) - active Indicator whether this configuration is active. Values:
true
orfalse
. Default =true
.
NOTE: If tcp
or serial
are not given the bridge will attempt to detect a radio attached to the serial port. Additional configuration may be needed to use the serial port with the Docker option.
mqtt_servers
is a list of MQTT servers the bridge listens for shared network traffic.
- name Reference given to the MQTT server. For example,
my_mqtt_server
- server The IP address or hostname of a MQTT server. For example,
server.mqttserver.com
- port The port the MQTT server listens on
- topic The topic name associated with the network traffic. For example,
mesh/network
- insecure Use a secure connection but do not validate the server certificate
- pipelines A set of plugins (filters/actions) that run when a new message emerges for topic. Each pipeline is given a name; such as
mqtt-to-radio
(as in the example above)
pipelines
is a list of ordered plugins (filters/actions) that run when a packet is detected by any connected radio. Each set is given a name; such as radio-to-mqtt
(as in the example above). Pipelines can run in any order, however plugins run in the order they are defined.
Plugins
The following plugins can be used in the pipelines
section of config.yaml
:
Plugin | Description |
---|---|
debugger | Log the packet to the system console |
message_filter | Filters out packets from the bridge that match a specific criteria |
location_filter | Filters out packets that originate too far from a specified device |
webhook | Send HTTP requests with custom payloads using packet information |
mqtt_plugin | Send packets to a MQTT server |
encrypt_filter | Encrypt a packet for a desired MQTT recipient |
decrypt_filter | Decrypt a packet originating from MQTT |
radio_message_plugin | Send a packet to a specified device |
nostr_plugin | Send a NoStr event to a relay |
owntracks_plugin | Send location data to MQTT server for Owntracks |
debugger - Output the contents of a packet
- log_level
debug
orinfo
. Defaultinfo
For example:
debugger:
log_level: debug
Useful for troubleshooting.
message_filter - Allow or block packets based on criteria
- log_level
debug
orinfo
. Defaultinfo
- app Name of meshtastic application to allow or disallow
- from The packet
fromId
values to allow or disallow - to The packet
toId
values to allow or disallow - message The packet
message
values to allow or disallow. Supports Regex.
For example:
message_filter:
from:
allow:
- !bd5ba0ec
- !f85bc0bc
disallow:
- !c15ba2ec
message:
disallow:
- Good night
location_filter - Filter packets by location from current node (default) or specific location
- log_level
debug
orinfo
. Defaultinfo
- max_distance_km Filter packets more than a certain distance
- comparison
within
oroutside
. Defaultwithin
- compare_latitude latitude to compare against
- compare_longitude longitude to compare against
- latitude Set the latitude
- longitude Set the longitude
For example
location_filter:
max_distance_km: 1000
webhook - Send a HTTP request
- log_level
debug
orinfo
. Defaultinfo
- active Plugin is active. Values:
true
orfalse
. Default =true
. - body The JSON payload to send
- url The target URL
- headers HTTP headers to include in the request. Secrets can be passed using ENV variables
- message Override the packet message
Placeholders can be used with the body value:
{LAT}
- Latitude associated with the POSITION packet. Empty if no value available.{LNG}
- Latitude associated with the POSITION packet. Empty if no value available.{MSG}
- Packet text ormessage
from the configuration (above){FID}
- ThefromId
associated with the packet.{TID}
- ThetoId
associated with the packet.
For example:
webhook:
active: true
body: '{"lat": "{LAT}", "lng": "{LNG}", "text_message": "{MSG}"}'
url: 'https://localhost:8000/message'
headers:
Authorization: Token {AUTH_TOKEN}
Content-type: application/json
mqtt_plugin - Send a packet to a MQTT server
- log_level
debug
orinfo
. Defaultinfo
- active Plugin is active. Values:
true
orfalse
. Default =true
. - name Reference of an existing MQTT server configured in the top-level
mqtt_servers
configuration - message Override the packet message with a custom value.
- topic The message topic
For example:
mqtt_plugin:
name: external
topic: meshtastic/topic
Placeholders can be used with the message value:
{MSG}
- Packet text
encrypt_filter - Encrypt a packet before sending it to a MQTT server
- log_level
debug
orinfo
. Defaultinfo
- key The PEM filename of the public key used to encrypt the message.
For example:
encrypt_filter:
key: '/home/user/keys/cert.pem'
decrypt_filter - Decrypt message from a MQTT server
- log_level
debug
orinfo
. Defaultinfo
- key The PEM filename of the key used to decrypt the message.
For example:
decrypt_filter:
key: '/home/user/keys/key.pem'
nostr_plugin - Send a NoStr event
- log_level
debug
orinfo
. Defaultinfo
- private_key The private key for a NoStr user. Secrets can be passed using ENV variables
- public_key The public key for the NoStr user associated with the private key.
- message A specific message (Optional)
- relays List of NoStr relays. Default
wss://nostr-pub.wellorder.net
, andwss://relay.damus.io
For example:
nostr_plugin:
private_key: "{NOSTR_PRIVATE_KEY}"
public_key: "npub1d0ja5d.......xw7jys4eqnk0"
relays:
- "wss://nostr-pub.wellorder.net"
Placeholders can be used with the message value:
{MSG}
- Packet text
owntracks_plugin - Send location data to MQTT server for Owntracks
- log_level
debug
orinfo
. Defaultinfo
- server_name The mqtt server to send owntracks messages to
- tid_table Table of the numeric from IDs of each node, mapped to an Owntracks name and TID
For example:
owntracks_plugin:
server_name: external
tid_table:
"1234": ["Van", "GV"]
"-5678": ["Home", "HR"]
Placeholders can be used with the message value:
{MSG}
- Packet text
radio_message_plugin - Send a packet to a radio
- log_level
debug
orinfo
. Defaultinfo
- active Plugin is active. Values:
true
orfalse
. Defaulttrue
. - device Required. Send the packet to a Radio with this name. It should be configured in the top-level
devices
configuration - message Send a text message
- lat Send a position message having this latitude
- lng Send a position message having this longitude
- node_mapping Map the packet
to
value to another value - to Target node reference
- toId Target node reference. Ignored if
to
is used.
For example:
Broadcasts all packets to the "remote" radio network that are destined to the node 12354345
.
radio_message_plugin:
device: remote
node_mapping:
12354345: ^all
Run the bridge
Command-line
Create a config.yaml
in the meshtastic-bridge
directory. Run:
$ source bin/activate
And:
python main.py
Docker
Create a config.yaml
with the desired settings and run the following Docker command:
Linux
docker run --rm --network host -v $(pwd)/config.yaml:/code/config.yaml gwhittington/meshtastic-bridge:latest
Resources
- Example guidance for creating PEM key files.
- Test webhooks using Webhooks.site