Skip to main content

[LEGACY] Reliable offline bridge for Atlas Command over Meshtastic radios. Superseded by next_gen_atlas_meshtastic_link.

Project description

Atlas Meshtastic Bridge

[!WARNING] DEPRECATION NOTICE: This package is the older, legacy Meshtastic bridge. While it is still available and actively used in existing deployments, it has been superseded. We highly recommend new projects use the Next Gen Atlas Meshtastic Link package moving forward, which serves as its replacement.

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 chunk limit is up to 230 bytes (MAX_CHUNK_SIZE) before transport-level retries/ack handling.
  • The hardware harness enforces a 10 KB limit for object uploads. Larger transfers are currently disabled; use the Atlas HTTP API instead.
  • Keep request payloads small and metadata-focused when operating over radio links.

Prerequisites

  • Python 3.10+
  • Atlas Command reachable from the gateway (HTTPS recommended)
  • Meshtastic radios flashed with current firmware
  • atlas-asset-client>=0.3.0 (required)
  • meshtastic>=2.3.0 (optional for real radios; not needed for --simulate-radio)
  • Optional: virtual (in-memory) radio for local testing

Install the bridge as a standalone package (and optionally meshtastic-python for real radios):

cd Atlas_Client_SDKs/connection_packages/atlas_meshtastic_bridge
pip install -e .[meshtastic]        # includes meshtastic
# or, for simulation-only workflows without hardware drivers:
pip install -e .

Meshtastic hardware setup

  1. Flash both radios with the same firmware and channel settings. Verify they can message each other using the Meshtastic app.
  2. Connect the gateway radio to the machine that can reach Atlas Command over IP.
  3. Note the serial port for each device:
    • Linux: /dev/ttyUSB0, /dev/ttyACM0, or dmesg | grep tty
    • macOS: /dev/cu.usbserial-*
    • Windows: COM3, COM4, etc.
  4. Recommended radio config:
    • Same channel name/psk on all nodes
    • hop_limit and power appropriate for your mesh size
    • Unique, meaningful node IDs (set via Meshtastic app)
  5. Run with --radio-port pointing at the serial device. Use --simulate-radio to 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).
--metrics-host Host interface for metrics/health server (default: 0.0.0.0).
--metrics-port Port for metrics/health server (default: 9700).
--disable-metrics Disable metrics and health endpoints.

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 '{"entity_id":"DRONE-001","entity_type":"asset","subtype":"uav","alias":"DRONE-001"}'

Check-in workflow (over Meshtastic)

  1. Ensure the entity exists (HTTP as above).
  2. 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","latitude":40.0,"longitude":-105.0}'
  1. 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}'
  1. 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_m":1200,"speed_m_s":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 result data
python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
  --simulate-radio --command complete_task --data '{"task_id":"TASK-123","result":{"summary":"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 an RFC3339 timestamp:

python -m atlas_meshtastic_bridge.cli --mode client --gateway-node-id gw-1 \
  --simulate-radio --command get_changed_since \
  --data '{"since":"2025-01-01T00:00:00Z","limit_per_type":50}'

End-to-end workflow example

  1. Register entity via HTTP.
  2. Start gateway (hardware or simulated) pointed at Atlas Command.
  3. Client check-in over Meshtastic; gateway forwards to Atlas Command.
  4. Client requests tasks; gateway responds with pending assignments.
  5. Client downloads any referenced objects (metadata/bytes) as needed.
  6. 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
create_entity Create a new entity. entity_id, entity_type, alias, subtype, optional components
update_entity Update entity metadata/components. entity_id, optional subtype, components
delete_entity Delete entity by ID. entity_id
checkin_entity Check in an entity with optional telemetry and task filters. entity_id, telemetry fields, optional status_filter, limit, since, fields
update_telemetry Update entity telemetry. entity_id, telemetry fields (latitude, longitude, altitude_m, speed_m_s, heading_deg)
list_tasks List tasks (no server-side status filter). limit, offset
get_task Fetch task by ID. task_id
get_tasks_by_entity Tasks scoped to an entity. entity_id, limit
create_task Create a task. task_id, optional status, entity_id, components, extra
update_task Update an existing task. task_id, optional status, entity_id, components, extra
delete_task Delete task by ID. task_id
transition_task_status Transition task to a new status. task_id, status
start_task Mark a task as started. task_id
complete_task Mark task complete. task_id, optional result
fail_task Mark task failed. task_id, optional error_message, error_details
list_objects List objects. limit, offset
create_object Create/upload an object (small payloads only). object_id, content_b64, content_type, optional file_name, usage_hint, type, referenced_by
get_object Get object metadata or bytes. object_id, optional download
update_object Update object metadata. object_id, optional usage_hints, referenced_by
delete_object Delete object by ID. object_id
get_objects_by_entity Objects linked to an entity. entity_id, optional limit
get_objects_by_task Objects linked to a task. task_id, optional limit
add_object_reference Link object to entity/task. object_id, entity_id or task_id
remove_object_reference Unlink object from entity/task. object_id, entity_id or task_id
find_orphaned_objects Find objects with no references. optional limit, offset
get_object_references List current object references. object_id
validate_object_references Validate object references. object_id
cleanup_object_references Cleanup invalid object references. object_id
get_changed_since Incremental change feed (includes deleted_entities/deleted_tasks/deleted_objects as {id,type,deleted_at}; ~1h in-memory TTL). since, limit_per_type
get_full_dataset Fetch complete dataset snapshot. optional entity_limit, task_limit, object_limit
health_check Check Atlas Command health. none
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 $USER on Linux). Try --simulate-radio to isolate radio issues.
  • Large payloads dropped: Messages are chunked to fit Meshtastic limits (up to 230 bytes per chunk). 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 --timeout for slow links. Poor RF conditions may require retries on the client side.
  • Observability checks: Metrics and health endpoints are available by default on http://<metrics-host>:<metrics-port>/metrics, /health, /ready, and /status unless --disable-metrics is set.

Where to go next

  • Protocol details: docs/SYSTEMS_DESIGN.md
  • Code reference: atlas_meshtastic_bridge.gateway and atlas_meshtastic_bridge.transport
  • Atlas Command HTTP client: connection_packages/atlas_asset_http_client_python

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

atlas_meshtastic_bridge-0.1.26.tar.gz (71.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

atlas_meshtastic_bridge-0.1.26-py3-none-any.whl (68.6 kB view details)

Uploaded Python 3

File details

Details for the file atlas_meshtastic_bridge-0.1.26.tar.gz.

File metadata

  • Download URL: atlas_meshtastic_bridge-0.1.26.tar.gz
  • Upload date:
  • Size: 71.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for atlas_meshtastic_bridge-0.1.26.tar.gz
Algorithm Hash digest
SHA256 1a1fa4ee05bdccfe487b7f05485e13f5a85695d9c8e6351fd547dc92d4fee609
MD5 eb4dd9982e2581c3991e145c098dadcc
BLAKE2b-256 297a14a7f902d4380fc6779c0cc782fc71b48caf9d711f6f46c539763479f14c

See more details on using hashes here.

File details

Details for the file atlas_meshtastic_bridge-0.1.26-py3-none-any.whl.

File metadata

File hashes

Hashes for atlas_meshtastic_bridge-0.1.26-py3-none-any.whl
Algorithm Hash digest
SHA256 d8fec74dcd86e9ed16c151d3ab3dcdf713d9e499f7ae3e35f6219ed0504f6130
MD5 b249ab7f8927b8c47be3cd74dba40854
BLAKE2b-256 926ec7b1614c9a7e1d7afc3854a9180a1921b449b999234266cf25db7c5a2f99

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page