Reliable offline bridge for Atlas Command over Meshtastic radios.
Project description
Atlas Meshtastic Bridge
Reliable offline access to Atlas Command over Meshtastic radios. The bridge runs in two modes:
- Gateway - connected to Atlas Command over IP. It receives Meshtastic requests, calls the HTTP API, and returns responses over radio.
- Client - runs next to a field asset. It issues Atlas Command requests via the gateway and renders the responses locally.
The protocol and chunking design are described in
docs/SYSTEMS_DESIGN.md. This README focuses on day-to-day setup, usage, and troubleshooting.
Reliability guarantees
- Application-level ACKs are emitted for every reassembled message; senders track pending messages until ACKed.
- Outgoing messages are durably spooled to disk (JSON file) and retried with exponential backoff + jitter until acknowledged.
- Pending messages are replayed automatically after restarts; gateways flush the outbox each poll cycle and clients flush before sending.
- ACK envelopes are filtered from application handlers so existing client/gateway flows remain unchanged.
- Spool location is configurable via
--spool-path(default:~/.atlas_meshtastic_spool.json).
Payload limits
- Chunk: the smallest on-air packet sent over Meshtastic (what the transport already splits and ACKs today).
- Current behavior: the hardware harness enforces a 10 KB limit for object uploads. Larger transfers are currently disabled; use the Atlas HTTP API instead.
- Until a segment layer ships, use a staged reliability loop for big transfers: split into chunks, send them once, emit a tiny completion marker, have the receiver respond with missing chunk indices, resend only the gaps, then repeat the completion/missing/resend cycle until nothing is missing.
- Future plan: reintroduce a proper segment layer (segment = intermediate slice, chunk = on-air packet) with gateway-side reassembly. This is not implemented yet.
Prerequisites
- Python 3.10+
- Atlas Command reachable from the gateway (HTTPS recommended)
- Meshtastic radios flashed with current firmware
- Optional: virtual (in-memory) radio for local testing
Install the bridge as a standalone package (and optionally meshtastic-python for real radios):
cd Atlas_Command/connection_packages/atlas_meshtastic_bridge
pip install -e .[meshtastic] # includes meshtastic-python
# or, for simulation-only workflows without hardware drivers:
pip install -e .
Meshtastic hardware setup
- Flash both radios with the same firmware and channel settings. Verify they can message each other using the Meshtastic app.
- Connect the gateway radio to the machine that can reach Atlas Command over IP.
- Note the serial port for each device:
- Linux:
/dev/ttyUSB0,/dev/ttyACM0, ordmesg | grep tty - macOS:
/dev/cu.usbserial-* - Windows:
COM3,COM4, etc.
- Linux:
- Recommended radio config:
- Same channel name/psk on all nodes
hop_limitandpowerappropriate for your mesh size- Unique, meaningful node IDs (set via Meshtastic app)
- Run with
--radio-portpointing at the serial device. Use--simulate-radioto bypass hardware during development.
Configuration
CLI flags (client and gateway):
| Flag | Description |
|---|---|
--mode {gateway,client} |
Run as gateway or client (required). |
--gateway-node-id |
Meshtastic node ID of the gateway (required). |
--api-base-url |
Atlas Command base URL. Required by the CLI; gateway uses it for HTTP calls (clients must still supply because the flag is required). |
--api-token |
Atlas Command bearer token (gateway mode, optional). |
--timeout |
Client request timeout in seconds (default: 5). |
--simulate-radio |
Use in-memory radio instead of hardware. |
--radio-port |
Serial port path (hardware mode). |
--node-id |
Override local node ID (default: gateway or client). |
--command |
Client command to run (client mode). |
--data |
JSON payload for the command (client mode). |
--log-level |
Logging level (default: INFO). |
Environment variables (gateway):
| Variable | Purpose |
|---|---|
ATLAS_API_BASE_URL |
Convenience only; the bridge does not read this directly. Export it and pass via --api-base-url \"$ATLAS_API_BASE_URL\". |
ATLAS_API_TOKEN |
Convenience only; the bridge does not read this directly. Export it and pass via --api-token \"$ATLAS_API_TOKEN\". |
Quick start (simulated radios)
Terminal 1 - start gateway:
python -m atlas_meshtastic_bridge.cli \
--mode gateway \
--gateway-node-id gw-1 \
--api-base-url http://localhost:8000 \
--api-token "$ATLAS_API_TOKEN" \
--simulate-radio \
--node-id gw-1
Terminal 2 - run a client request:
python -m atlas_meshtastic_bridge.cli \
--mode client \
--gateway-node-id gw-1 \
--api-base-url http://localhost:8000 \
--simulate-radio \
--node-id field-1 \
--command list_entities \
--data '{"limit":5}'
Usage examples
Entity registration / creation
Entity creation is performed over the HTTP API (the mesh bridge keeps payloads small). Register the asset via HTTP first, then use the bridge for telemetry and tasking:
curl -X POST "$ATLAS_API_BASE_URL/entities" \
-H "Authorization: Bearer $ATLAS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"alias":"DRONE-001","type":"uav","status":"active"}'
Check-in workflow (over Meshtastic)
- Ensure the entity exists (HTTP as above).
- Send a check-in from the asset:
python -m atlas_meshtastic_bridge.cli \
--mode client \
--gateway-node-id gw-1 \
--simulate-radio \
--command checkin_entity \
--data '{"entity_id":"DRONE-001","location":{"lat":40.0,"lon":-105.0}}'
- Fetch outstanding tasks for the entity:
python -m atlas_meshtastic_bridge.cli \
--mode client \
--gateway-node-id gw-1 \
--simulate-radio \
--command get_tasks_by_entity \
--data '{"entity_id":"DRONE-001","limit":5}'
- Report progress or telemetry:
python -m atlas_meshtastic_bridge.cli \
--mode client \
--gateway-node-id gw-1 \
--simulate-radio \
--command update_telemetry \
--data '{"entity_id":"DRONE-001","altitude":1200,"speed":14}'
Task execution (start / complete / fail)
# Start a task
python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
--simulate-radio --command start_task --data '{"task_id":"TASK-123"}'
# Complete a task with a status note
python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
--simulate-radio --command complete_task --data '{"task_id":"TASK-123","note":"scan complete"}'
Object download
Request object metadata or bytes (small payloads only):
python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
--simulate-radio --command get_object \
--data '{"object_id":"OBJ-1","download":true}'
If download is omitted or false, only metadata is returned.
Object upload
Large uploads are intentionally not sent over Meshtastic. Use the Atlas Command HTTP API to obtain a presigned upload URL, upload the file via HTTPS, and then reference the object by ID in subsequent mesh requests.
Change feed / incremental sync
Fetch changes since a cursor:
python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
--simulate-radio --command get_changed_since \
--data '{"cursor":"2025-01-01T00:00:00Z","limit":50}'
End-to-end workflow example
- Register entity via HTTP.
- Start gateway (hardware or simulated) pointed at Atlas Command.
- Client check-in over Meshtastic; gateway forwards to Atlas Command.
- Client requests tasks; gateway responds with pending assignments.
- Client downloads any referenced objects (metadata/bytes) as needed.
- Client reports task status (start/complete/fail) and telemetry updates.
Command reference
| Command | Description | Payload keys |
|---|---|---|
list_entities |
List entities with pagination. | limit, offset |
get_entity |
Fetch entity by ID. | entity_id |
get_entity_by_alias |
Fetch entity by alias. | alias |
checkin_entity |
Check in an entity with optional telemetry. | entity_id, telemetry fields |
update_telemetry |
Update entity telemetry. | entity_id, telemetry fields |
list_tasks |
List tasks. | limit, offset |
get_task |
Fetch task by ID. | task_id |
get_tasks_by_entity |
Tasks scoped to an entity. | entity_id, limit |
start_task |
Mark a task as started. | task_id |
complete_task |
Mark task complete. | task_id, optional note |
fail_task |
Mark task failed. | task_id, optional reason |
list_objects |
List objects. | limit, offset |
get_object |
Get object metadata or bytes. | object_id, optional download |
get_objects_by_entity |
Objects linked to an entity. | entity_id, limit, offset |
get_objects_by_task |
Objects linked to a task. | task_id, limit, offset |
get_changed_since |
Incremental change feed. | cursor, limit |
test_echo |
Echo payload for connectivity testing. | free-form |
Troubleshooting
- No response from gateway: Confirm the gateway process is running, radio IDs match
--gateway-node-id, and Atlas Command is reachable at--api-base-url(check/health). - Serial port errors: Verify the port path and permissions (
sudo usermod -a -G dialout $USERon Linux). Try--simulate-radioto isolate radio issues. - Large payloads dropped: Messages are chunked to fit Meshtastic limits (~200 bytes). Avoid sending large JSON or binary content; use HTTP uploads instead.
- Duplicate or missing responses: Ensure both radios share the same channel/PSK and that clocks are roughly in sync. The CLI generates a fresh UUID for every request; custom integrations should do the same and reuse that UUID when retrying so deduplication works as expected.
- Timeouts: Increase
--timeoutfor slow links. Poor RF conditions may require retries on the client side.
Where to go next
- Protocol details:
docs/SYSTEMS_DESIGN.md - Code reference:
atlas_meshtastic_bridge.gatewayandatlas_meshtastic_bridge.transport - Atlas Command HTTP client:
connection_packages/atlas_asset_http_client_python
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file atlas_meshtastic_bridge-0.1.6.tar.gz.
File metadata
- Download URL: atlas_meshtastic_bridge-0.1.6.tar.gz
- Upload date:
- Size: 84.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf528af714d948af8f1db21683e032348fae1d277d0932c521e8f874797bb960
|
|
| MD5 |
2b433db3c88de338a2ece1e592df071d
|
|
| BLAKE2b-256 |
cbbc3c187e85a7893fc0c66d39e5040561b9c7f7ff210c57bc0276c4658babae
|
File details
Details for the file atlas_meshtastic_bridge-0.1.6-py3-none-any.whl.
File metadata
- Download URL: atlas_meshtastic_bridge-0.1.6-py3-none-any.whl
- Upload date:
- Size: 63.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a215d67f6e706069d7e8934c028e3b760ac64ed561f535e98dcad3dc5680f1ba
|
|
| MD5 |
7972c0eb03d5adc70ceebd9e40804d41
|
|
| BLAKE2b-256 |
882ceff6212a32f7db698170c313a34e24b8d2d05ba9eacb5202bc6f60dfc37a
|