rtl_433: turning a cheap SDR dongle into a weather station reader
Program to decode radio transmissions from devices on the ISM bands (and other frequencies)
At a glance
- What is it?
- A portable C program that demodulates short radio bursts from consumer sensors and prints them as JSON or CSV. It supports several hundred device protocols, several SDR backends, and runs on hardware small enough to be an embedded target.
- Who is it for?
- rtl_433 is a good fit when you own sensors that never had network hardware in the first place, a temperature probe, a doorbell button, a rain gauge, and a twenty dollar RTL2832 dongle you can point at it. The decoder library is the product, and its size is the argument for it: you are far more likely to find a protocol for the device on your windowsill than you are to find a cloud integration for it.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 12, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The name says 433 MHz and the decoder list says otherwise
rtl_433 is described in the README as a generic data receiver, and the parenthetical there is pointed: the program is named after one frequency band while working mainly on 433.92 MHz, 868 MHz in the SRD range, 315 MHz, 345 MHz and 915 MHz. Everything outside those numbers exists too. There is a general purpose decoder flag for protocols the built-in list has never seen, and a documented mechanism for writing new device decoders, so the supported set is not fixed by the binary you download.
What the program actually does is narrow and specific. A sensor wakes up, sends a short burst of radio energy, and goes back to sleep. rtl_433 sits on that frequency, watches the signal strength, decides where one pulse ends and the next begins, and hands the resulting bit pattern to a device decoder that recognises the preamble, the payload format and the checksum of one particular product family. What comes out is not audio. It is a measurement: a temperature in tenths of a degree, a humidity figure, a battery flag, a house code and a unit number.
That narrowness is the reason the project is worth using. There is no signal to listen to and no modulation to demodulate beyond what the sensor's own chip does, so the whole problem reduces to pattern recognition over a few hundred bits. The bit of engineering that matters is the pulse detector, which the README exposes as a dedicated set of options.
Installing through the package manager on three platforms
The installation section is three lines long, one per platform family, and all three come straight out of the README:
sudo apt install rtl-433
pkg install rtl-433
brew install rtl_433Debian and Ubuntu take the first, FreeBSD the second, macOS the third. Note the inconsistency in the package names, which is not the README's mistake but a real one that will cost you a minute: the Debian and FreeBSD packages are hyphenated as rtl-433, the Homebrew formula is underscored as rtl_433. Other distributions are pointed at repology and pkgs.org rather than enumerated, which is the honest choice for a project packaged into most of the major Linux distributions.
Docker is handled indirectly. Rather than publishing an image in this repository, the README points at a separate rtl_433_docker repository maintained under the hertzg account. That split matters if you were planning to rely on a first-party container: the official source is here, the container is not. It also means the container's own tag policy and update cadence live somewhere you would have to read separately.
For building from source, the README is unusually brief and points at docs/BUILDING.md in the tree. What it does say is worth knowing before you start: the code is C99, it targets older compilers and toolchains on purpose, and low resource use with few dependencies is a stated design goal so it can run on embedded hardware.
The pulse detector options are where the real tuning happens
Running the binary with the help flag dumps the full option list, and it is the most complete documentation in the project:
rtl_433 -hThe demodulator options are where an installation that decodes nothing gets fixed. There is a pulse detector mode with three presets, auto, classic and minmax, plus manual thresholds measured in dB. You can set a minimum level, a minimum signal to noise ratio, ask the detector to derive the noise floor itself with an autolevel flag, and enable squelch so frames below the estimated noise floor are skipped to cut processor load. There is also a manual low-pass filter cutoff, expressed in microseconds, hertz or as a ratio of the sample rate, whose stated purpose is separating transmissions that overlap in frequency.
Two more flags make a decoding problem tractable. The analyzer flag turns on pulse analysis and a decode attempt, and the README notes that pairing it with a decoder disable flag gives you analyzer output only, which is what you want when the sensor is transmitting but no device decoder claims it. The verify flag takes a demodulated code and asks the enabled devices whether they can decode it, so once you have captured a bit pattern by hand you can find out which protocol it belongs to.
The tuner side is smaller: a device selector, a gain setting defaulting to auto, a frequency that defaults to 433920000 Hz, and a sample rate defaulting to 250000 Hz. A ppm correction option handles tuner frequency offset error, which matters because cheap crystal references are not exactly on frequency and that error alone can defeat a decoder.
Narrowing the decoder set when a building full of sensors makes noise
In a dense radio environment the protocol list becomes a liability. Every enabled decoder watches every pulse stream, so a neighbour's weather station and your own doorbell both generate work. The device selection flag solves this, and it takes a negative number to disable a protocol as well as a positive number to enable one:
rtl_433 -R 0Passing zero disables every decoder, which is the documented way to start from nothing and add only the families you own. You can repeat the flag to enable a specific device number, and the usage output lists them numerically against product names, from the Silvercrest remote control through LaCrosse, Oregon Scientific, Fine Offset weather stations and a long tail of doorbells, power meters, soil sensors and meat thermometers.
That list is the project's real specification, more so than any feature list. Each numbered entry is a decoder somebody reverse engineered from a device they owned, and the numbering carries information: entries marked with an asterisk in the usage output are a different category from the rest. There are also decoder configuration files under conf/ in the repository tree, and the release history shows why. A recent change altered the unit prefix for UV sensor fields, a breaking change to the output schema, which is exactly the kind of edit that makes this tool convenient for a Home Assistant or MQTT consumer and awkward for anything expecting a stable schema across versions.
JSON, CSV, MQTT and a directory of example relays
Output format is a first class concern here, which is unusual for a signal tool. The output flag takes log, kv, json, csv, mqtt, influx, syslog, trigger, rtl_tcp, http and null, and it accepts a filename suffix so the same flag both selects the format and redirects the stream:
rtl_433 -F json
rtl_433 -F csv:log.csvThe metadata flag attaches time, protocol, level, noise, stats and bits to each output line, the tag flag attaches an expanded token or a fixed string to every line, and the unit flag converts between native, SI and customary units. That unit switch is a small detail that saves real work, because a sensor that reports a temperature as an integer in tenths of a degree and a temperature in hundredths are both common, and downstream consumers rarely agree on which one they want.
The examples directory is the second half of the project and is arguably more useful to a newcomer than the decoder list. It holds more than twenty scripts: MQTT relays, a Home Assistant MQTT bridge, InfluxDB and Graphite relays, collectd and statsd pipes, Prometheus and rrd relays, HTTP event and stream endpoints in both Python and PHP, and a JSON to rtlwmbus bridge for European meter readers. The wiki page linked from the README points at third-party software built on top of rtl_433, so the relay layer has grown past what the repository ships.
Supported radio hardware, and the boundary of the documentation
The README is explicit about which hardware it stands behind. Realtek RTL2832 based DVB television dongles driven by RTL-SDR are described as actively tested and supported, alongside LimeSDR in USB and mini form, PlutoSDR, HackRF One through the SoapySDR drivers, and SoapyRemote. That is an unusually concrete support statement for a hobby-adjacent project, and it also tells you what to buy: the twenty dollar dongle is not a compromise here, it is the reference configuration.
Where the README stops is documented elsewhere. The build instructions live in docs/BUILDING.md, the process for adding an unsupported sensor is a contributing document, and the site at triq.org carries further documentation plus related tooling for people working on rtl_433 itself. The wiki holds the built-with list. The repository tree reinforces the split: cmake/ for the build system, src/ and include/ for the implementation, tests/ for the test suite, docs/ for the guides, man/ for the manual page, and a Doxyfile.in for generated API documentation.
Activity here is easy to judge from the release history. The releases are named by year and month, with 25.12 published on 2025-12-12 and 25.02 on 2025-02-19, and a nightly pre-release tag published on 2026-09-20 whose notes are a list of individual decoder fixes: a Govee water sensor rejecting an all-zero payload, a Renault TPMS field reclassified from checksum to CRC, a DeltaDore payload parsing fix. The last push was on 2026-09-20. A project whose releases are dominated by per-device fixes is telling you its shape: the work never stops, and it is rarely architectural.
Editorial conclusion
rtl_433 is a good fit when you own sensors that never had network hardware in the first place, a temperature probe, a doorbell button, a rain gauge, and a twenty dollar RTL2832 dongle you can point at it. The decoder library is the product, and its size is the argument for it: you are far more likely to find a protocol for the device on your windowsill than you are to find a cloud integration for it. The limits are honest ones. It reads what the transmitter emits and nothing more, it will not reach a sensor inside a metal box, and its growing protocol list means a decoder can stop matching when a manufacturer changes a firmware version. Start with the package manager route for your platform, run the binary with no arguments against a live frequency, and only reach for the flex decoder and the examples relay scripts once the plain decoder output has told you what you actually have.
Frequently asked questions
What is RTL 433?
It is a program that decodes radio transmissions from devices on the ISM bands, principally 433.92 MHz, 868 MHz, 315 MHz, 345 MHz and 915 MHz. Despite the name it is a generic data receiver rather than a single-band tool. It reads short bursts from consumer sensors and prints the decoded measurements as JSON, CSV or another output format.
What is the sample rate of rtl_433?
The default is 250000 Hz, set with the sample rate option, and the frequency default is 433920000 Hz. Both are tuner options in the usage output, alongside a gain setting that defaults to auto. Because the sample rate affects which overlapping transmissions the filter stage can separate, it is worth raising it on a busy band.
Can you provide some examples of commands in rtl_433?
Running the binary with the help flag prints the full usage list, which is the most complete reference the project ships. Typical invocations are rtl_433 -F json for JSON on standard output, rtl_433 -F csv:log.csv to write CSV to a file, and rtl_433 -R 0 to disable every decoder and start from an empty protocol set. The analyze flag, -A, turns on pulse analysis for an unrecognised sensor.
How do I add rtl_433 to Home Assistant?
The README points to a wiki page listing software built with rtl_433, which is the place to find current integrations. The repository itself ships an MQTT bridge, examples/rtl_433_mqtt_hass.py, alongside InfluxDB, Graphite, Prometheus, collectd and statsd relays. The MQTT path is the common route because Home Assistant consumes MQTT natively, and the project also publishes an MQTT output format directly.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/merbanan-rtl-433)