Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/geoffwhittington/meshtastic-bridge


https://github.com/geoffwhittington/meshtastic-bridge

Last synced: 12 days ago
JSON representation

Awesome Lists containing this project

README

        

# Meshtastic Bridge

Connect [Meshtastic](https://meshtastic.org) 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 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` or `false`. 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` or `info`. Default `info`

For example:

```
debugger:
log_level: debug
```

Useful for troubleshooting.

### message_filter - Allow or block packets based on criteria

- **log_level** `debug` or `info`. Default `info`
- **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` or `info`. Default `info`
- **max_distance_km** Filter packets more than a certain distance
- **comparison** `within` or `outside`. Default `within`
- **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` or `info`. Default `info`
- **active** Plugin is active. Values: `true` or `false`. 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 or `message` from the configuration (above)
- `{FID}` - The `fromId` associated with the packet.
- `{TID}` - The `toId` 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` or `info`. Default `info`
- **active** Plugin is active. Values: `true` or `false`. 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` or `info`. Default `info`
- **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` or `info`. Default `info`
- **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` or `info`. Default `info`
- **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`, and `wss://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` or `info`. Default `info`
- **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` or `info`. Default `info`
- **active** Plugin is active. Values: `true` or `false`. Default `true`.
- **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](https://www.suse.com/support/kb/doc/?id=000018152) key files.
- Test webhooks using [Webhooks.site](https://webhook.site/)