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

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

Built distribution (wheel)

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

Total release size: 65.0 kB

Release files / rtlamr_python-1.0.2.tar.gz

Download URL rtlamr_python-1.0.2.tar.gz
Size 34.5 kB
Tags Source
SHA-256 checksum
How to use checksums
77e176fa1132e97e6037c84a7243d30ca5598d09556bb9d9732c87ad4589452d
BLAKE2b-256 checksum
How to use checksums
e52ee13d68ae16d79ceadead5133f5e41a48d63311fafd3ce19f7da7749d50f4
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.2-py3-none-any.whl

Download URL rtlamr_python-1.0.2-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98aa329f4924d037cc5bac334e1f207be00b57feae12b09a61eae845d49240de
BLAKE2b-256 checksum
How to use checksums
7e350ad6449fca6d81423dc8dac07081d621dc443f446d0b04de91d363e97827
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

1.0.3

2 release files

This release

1.0.2 This release

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