Skip to main content

lorawan-connection

Documentation · Building a device library

Backend-neutral LoRaWAN events and device collections for Python 3.12+. The base package has no runtime dependencies. Install the optional ChirpStack or The Things Stack backend to connect to a server.

A vendor DeviceCollection creates supported models and routes incoming events to them automatically. Applications use device-added callbacks to observe those models and subscribe to their state updates.

With a connection already created, declare and use the models your library supports:

from lorawan_connection import Device, DeviceCollection, DeviceDescriptor, DeviceEvent


class Sensor(Device):
    identifiers = {
        "chirpstack": (123, "known-model"),
        "tts": ("example-brand", "known-model"),
    }

    def __init__(self, descriptor: DeviceDescriptor) -> None:
        super().__init__(descriptor)
        self.temperature: float | None = None
        self.humidity: float | None = None

    def handle_event(self, event: DeviceEvent) -> None:
        # Decode an event, update model attributes, then call self.notify().
        pass


class Sensors(DeviceCollection[Sensor]):
    DEVICES = (Sensor,)


sensors = Sensors(connection)
unsubscribe = sensors.subscribe_device_added(
    lambda device: print(device.descriptor.name)
)

Each model declares native (brand_id, model_id) pairs by stack. The collection selects models from DEVICES; alternatively pass them to DeviceCollection(connection, [Sensor]).

Call await sensors.async_setup() to receive inventory and live events. Applications observe models through add_update_listener(). Models decode readings, update their attributes, then call notify(). Closing the collection removes subscriptions and closes models, leaving the connection open.

Events

Events are typed dataclasses. An UplinkEvent exposes data: bytes and f_port directly; an AckEvent exposes queue_item_id and acknowledged. Dispatch on event.type or use isinstance() to narrow the event type without a cast.

Inventory events take only descriptor and received_at. Their network and device identifiers are properties derived from the descriptor. The event guide lists every field.

Version 0.11 replaces the event envelopes from 0.10; see the migration notes.

Install

pip install lorawan-connection

The quickstart replays a SenseCAP S2101 capture and prints 21.4 °C and 31.4% humidity.

Backends

Server Install Import
ChirpStack pip install "lorawan-connection[chirpstack]" lorawan_connection.backend.chirpstack.ChirpStackConnection
The Things Stack pip install "lorawan-connection[tts]" lorawan_connection.backend.tts.TTSConnection

Adapters load only when explicitly imported. Both supply inventory before live activity. Collections select models by catalog identity. Provision devices on the server before connecting. The application owns connection startup, recovery, and shutdown; missed telemetry is not replayed.

ChirpStack drops retained events older than five seconds before each device stream starts. Keep server and client clocks synchronized. TTS supports separate Identity and Application Servers.

Sending commands

Models encode commands and call async_send_downlink(data=..., f_port=...). By default, the call requests a confirmed downlink and waits for its ACK. Use wait_for_ack=False to return after enqueueing an unconfirmed command.

An ACK confirms delivery; device reports update model attributes. A caller can limit its wait with asyncio.timeout(), but the queued command may still execute. Optional expires_at limits queue retention on ChirpStack. TTS rejects explicit expiry.

The Dragino example models the LT-22222-L with identities from both the ChirpStack and TTS catalogs.

Testing device libraries

Use MockConnection from lorawan_connection.mock in place of a server connection. Seed it with device descriptors, then call the collection's async_setup(). connection.emit(event) delivers events to subscribed collections. Queued commands are recorded in connection.downlinks, keyed by queue ID. Send ACK events explicitly to test command completion; connection.disconnect() simulates connection loss. See the testing guide.

Device-library CLI

For a device library named my_sensors that exports Sensors, put this in my_sensors/__main__.py:

from lorawan_connection.cli_helper import run
from . import Sensors

if __name__ == "__main__":
    run(Sensors.DEVICES)

The helper prints public model attributes and properties as updates arrive. Select --backend chirpstack (the default) or --backend tts. Add --list for inventory only, or --json for machine-readable output. --help works without backend extras installed.

pip install "lorawan-connection[chirpstack]"
python -m my_sensors --server https://chirpstack.example.com:443 --api-key-file /path/to/key

See the CLI guide and Connecting to ChirpStack.

Add a backend

The backend guide covers optional dependency packaging, complete inventory, subscription ordering, event translation, downlink acknowledgements, transport cleanup, and CLI selection. Adapters implement the connection protocol without importing an application framework.

Home Assistant

These APIs are proposed and are not yet part of Home Assistant:

Development

uv sync --group compatibility --all-extras
uv run ruff check .
uv run ruff format --check .
uv run mypy
uv run pytest --cov --cov-report=term-missing
uv run python examples/replay.py
cd docs
npm ci
npm run build

CI tests Python 3.12, 3.13, and 3.14. Compatibility tests check event translation against chirpstack-api==4.19.0. The optional backend uses the same bindings. The documentation build validates internal links and produces llms.txt.

The repository follows the packaging, documentation, and release approach of modbus-connection. The source version stays 0.0.0; the publish workflow sets the version from the release tag. See releasing for release instructions.

Metadata

Release files for lorawan-connection 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lorawan-connection 0.11.0
File Size Uploaded
lorawan_connection-0.11.0.tar.gz 114.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lorawan-connection 0.11.0
File Interpreter ABI Platform
lorawan_connection-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 172.5 kB

Release files / lorawan_connection-0.11.0.tar.gz

Download URL lorawan_connection-0.11.0.tar.gz
Size 114.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1271b397dfd679f89fd9de2ad028dfc088c1074f1ff081695cc154e20af7c745
BLAKE2b-256 checksum
How to use checksums
8556d443ce57094e3d6e9ab8075f5d22abab0aa214982733c2655072df0e82d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / lorawan_connection-0.11.0-py3-none-any.whl

Download URL lorawan_connection-0.11.0-py3-none-any.whl
Size 58.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6dd8c71f7cf7b8d44fbd039c656283016b5b1fa10f038c0aee61f9db023cc937
BLAKE2b-256 checksum
How to use checksums
652d92c7df0a6c4370856857f302b04e80ffa6f29f38a41087d5c287996d3405
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.13.0

2 release files

This release

0.11.0 This release

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page