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.3

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.3
File Size Uploaded
rtlamr_python-1.0.3.tar.gz 34.5 kB Details

Built distribution (wheel)

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

Total release size: 65.0 kB

Release files / rtlamr_python-1.0.3.tar.gz

Download URL rtlamr_python-1.0.3.tar.gz
Size 34.5 kB
Tags Source
SHA-256 checksum
How to use checksums
dc369763d88a9d51182f2711a8fb788e7f3aac27bbdbc2724d3d5b2c0ebc7223
BLAKE2b-256 checksum
How to use checksums
ac72a70a1dfb284a78f4ea6a47b97b7b32af20d3eeba04ebaf374081872b139f
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 17, 2026.

Transparency log

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

Download URL rtlamr_python-1.0.3-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2384dd457a969e43b40c3a1424234a20255c3343ef753d60d6d51447c0f4dd38
BLAKE2b-256 checksum
How to use checksums
06e6003cf0852f0b081b18c556773afb317ae73647cb28ceb8e4986e2a197081
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 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.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