Skip to main content

Jason Slade

IIoT Director | SCADA | MQTT | Controls Engineering

The Meter Was Already Broadcasting: Reading Gas Usage Off the Air

There is a second way to read a gas meter, and it does not involve a drone.

The drone-and-camera approach solves the problem the meter presents to a human: four dials on an outside wall, readable only by going and looking. But the meter has not been purely mechanical for years. Like most utility meters in North America it carries an AMR endpoint that broadcasts its own reading over the air, in the clear, several times an hour, in the 900 MHz ISM band. If you can hear it, you never have to look at the dials again.

So this project is a $30 software-defined radio dongle, an antenna, and a decoder — reading the number the meter is already shouting.

The protocol

The broadcast uses SCM+ (Standard Consumption Message Plus), one of the ERT family of formats. rtlamr decodes it, and the parameters it derives tell you a lot about what the radio has to do:

ParameterValue
Centre frequency912,600,155 Hz
Sample rate2,359,296 S/s
Data rate32,768 bps
Chip length72
Preamble0001011010100011 (16 symbols)
Packet128 symbols / 18,432 samples

The sample rate is not arbitrary: it is the data rate times the chip length, 32768 × 72. Miss that relationship and the decoder cannot find a preamble at all.

A decoded packet carries the endpoint ID, a consumption count, an endpoint type, a tamper flag and a CRC. Filtering to a single endpoint ID is what turns “every meter in the neighbourhood” into “my meter” — and it is also why the ID is redacted throughout this write-up: a meter endpoint ID is effectively a street address.

The shape of the system

The dongle is an RTL2838 passed through from the NAS host into the Home Assistant VM. rtl_tcp owns the radio and serves IQ samples on a local socket; rtlamr connects to that socket, hunts for the preamble, decodes SCM+ frames, and filters to the one endpoint that matters. The rtlamr2mqtt add-on wraps both, publishes readings to MQTT, and announces the sensor to Home Assistant over discovery so it lands as a proper device_class: gas, state_class: total_increasing entity with long-term statistics.

Which means the whole chain is: radio → socket → decoder → MQTT → Home Assistant, with a failure mode available at every hop.

Status

In progress — the feed is currently down and being fixed.

This is the honest state of it: the decoder is in a restart loop. It opens the dongle successfully, reads the tuner’s gain table, declares itself ready — and then never receives a single IQ sample, times out after five seconds, and dies. Over and over. The add-on above it stays up and keeps reporting healthy to MQTT, which is exactly why it went unnoticed for a week: the thing that broke was not the thing being monitored.

The full write-up follows once it is collecting again — with the diagnosis, the fix, the watchdog that should have caught it on day one, and real consumption data.

← All posts

→ Subscribe by RSS