Skip to main content

rtlamr-python

A Python implementation of rtlamr — a multi-protocol ERT (Encoder Receiver Transmitter) smart meter receiver. Reads IQ samples from an RTL-SDR dongle (or a raw sample file), decodes ERT packets, and prints each message as a JSON line to stdout.

Supported protocols

Protocol Description
scmplus Standard Consumption Message Plus (16 bytes, most electric meters)
scm Standard Consumption Message (12 bytes, older electric meters)
idm Interval Data Message (92 bytes, hourly interval data)
netidm Net Meter Interval Data Message (92 bytes, net-metering variant)
r900 Neptune R900 water meters (different center freq: 912.38 MHz)

By default, all Manchester-encoded protocols (scmplus, scm, idm, netidm) are decoded simultaneously. r900 uses a different center frequency and must be selected explicitly (alone, or alternated with the Manchester set).

Installation

Requires Python 3.11+ and an RTL-SDR dongle (or librtlsdr installed) for live capture.

pip install rtlamr-python

This installs an rtlamr command on your PATH.

Usage

# All Manchester protocols on live hardware
rtlamr

# Single protocol
rtlamr --protocol scmplus

# From a recorded capture file
rtlamr --sample-file /path/to/capture.bin

# Filter to specific meters
rtlamr --meter-id 12345678

# Alternate between Manchester and R900 (different center frequencies)
rtlamr --protocol scmplus r900

Run rtlamr --help for the full list of options (gain, frequency correction, chip length, posting readings to a REST API, etc.).

Configuration file

Options can also be supplied via a TOML config file with --config path/to/rtlamr.toml. Command-line flags always take precedence over the config file. Example:

meter_ids = [12345678, 87654321]
protocol = ["scmplus", "scm"]
gain = "auto"
api_url = "http://localhost:8000/api"
api_key = "secret"
switch_timeout = 60.0

Library usage

rtlamr-python can also be used as a library rather than a CLI, e.g. to decode readings from within another application. All three forms below share the same options as the CLI (protocols, meter_id, chip_length, gain, freq_correction, sample_file, switch_timeout, duration, verbose).

Iterate over readings as they arrive

from rtlamr_python import listen

for reading in listen(protocols=["scmplus"], meter_id=[12345678]):
    print(reading)
    # break whenever you've got what you need — the SDR is closed on exit

Block until a single reading decodes

from rtlamr_python import listen_once

reading = listen_once(protocols=["scmplus"], meter_id=[12345678])
print(reading)  # SDR is already closed here

Run in the background with a callback

from rtlamr_python import start_listening

def on_message(reading):
    print(reading)

handle = start_listening(on_message, protocols=["scmplus"])
...
handle.stop()  # signals the background thread and waits for it to exit

Each reading is a dict, e.g.:

{"time": "2026-01-01T00:00:00Z", "type": "SCM+", "endpoint_id": 12345678,
 "endpoint_type": 4, "consumption": 112233, "tamper": "0x0000", "packet_crc": "0x972F"}

Development

pip install -e ".[dev]"
pytest

License

MIT — see LICENSE.

Release files for rtlamr-python 1.0.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 rtlamr-python 1.0.0
File Size Uploaded
rtlamr_python-1.0.0.tar.gz 34.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rtlamr-python 1.0.0
File Interpreter ABI Platform
rtlamr_python-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.9 kB

Release files / rtlamr_python-1.0.0.tar.gz

Download URL rtlamr_python-1.0.0.tar.gz
Size 34.4 kB
Tags Source
SHA-256 checksum
How to use checksums
79e22471b9884c99950367629ffea86fff5af58a8d41de19cd99319503c27308
BLAKE2b-256 checksum
How to use checksums
5a0ee41b5708c2987d1360bc2701f98e4fc58a8f3766ed92d01aaaa3834c8771
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 Sep 16, 2026.

Transparency log

Release files / rtlamr_python-1.0.0-py3-none-any.whl

Download URL rtlamr_python-1.0.0-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9bb9966a5875256fd9e3ae5be437011dea0d220af5ad9d9046363c46bcb79e57
BLAKE2b-256 checksum
How to use checksums
903051e682487335d4eb040da28d1e98b3137879d02499512d736c173f05a15c
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 Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

This release

1.0.0 This release

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