Files
HAMeter/README.md
2026-03-06 12:25:27 -05:00

9.4 KiB

HAMeter

Read utility meters (electric, gas, water) via SDR and publish to Home Assistant over MQTT.

HAMeter uses an RTL-SDR dongle to receive wireless transmissions from ERT-equipped utility meters, decodes them with rtlamr, and publishes readings to Home Assistant via MQTT auto-discovery.

Features

  • Reads SCM, SCM+, IDM, and R900 (Neptune) meter protocols
  • Built-in calibration multiplier per meter
  • Home Assistant MQTT auto-discovery — sensors appear automatically
  • Three HA sensors per meter: calibrated reading, raw reading, last seen
  • Discovery mode to find nearby meter IDs
  • Fully configurable via Docker environment variables — no config files needed
  • Smart defaults based on meter type (energy, gas, water)
  • Supports up to 9 meters simultaneously

Requirements

  • RTL-SDR dongle (tested with Nooelec RTL-SDR v5)
  • 915 MHz antenna (or telescopic whip at ~8 cm for 900 MHz band)
  • Docker host with USB access (tested on Unraid)
  • MQTT broker (e.g., Mosquitto)
  • Home Assistant with MQTT integration

Quick Start

1. Install Mosquitto MQTT Broker

Install via your Docker host's app store or:

docker run -d --name mosquitto -p 1883:1883 eclipse-mosquitto

2. Add MQTT Integration to Home Assistant

Settings → Devices & Services → Add Integration → MQTT

  • Broker: your Docker host IP
  • Port: 1883

3. Connect the SDR Dongle

Plug the RTL-SDR into a USB 2.0 port (USB 3.0 can cause interference).

Blacklist the kernel DVB driver so it doesn't claim the device:

# On Unraid (persists across reboots):
mkdir -p /boot/config/modprobe.d
echo "blacklist dvb_usb_rtl28xxu" >> /boot/config/modprobe.d/rtlsdr.conf
rmmod dvb_usb_rtl28xxu 2>/dev/null

# On other Linux:
echo "blacklist dvb_usb_rtl28xxu" | sudo tee /etc/modprobe.d/rtlsdr.conf
sudo rmmod dvb_usb_rtl28xxu 2>/dev/null

4. Run HAMeter

docker run -d \
  --name hameter \
  --restart unless-stopped \
  --device=/dev/bus/usb \
  -e MQTT_HOST=192.168.1.74 \
  -e METER_1_ID=23040293 \
  -e METER_1_PROTOCOL=scm \
  -e METER_1_NAME="Electric Meter" \
  -e METER_1_DEVICE_CLASS=energy \
  -e METER_1_MULTIPLIER=1.0 \
  hameter:latest

Your meter should appear in Home Assistant within a minute.

Configuration

All configuration is done via environment variables. No config file needed.

Required Variables

Variable Description
MQTT_HOST MQTT broker IP address
METER_1_ID Meter radio serial number (ERT ID, not the billing number)
METER_1_PROTOCOL Protocol: scm, scm+, idm, r900, r900bcd, netidm

Optional Variables

Variable Default Description
MQTT_PORT 1883 MQTT broker port
MQTT_USER (empty) MQTT username
MQTT_PASSWORD (empty) MQTT password
MQTT_BASE_TOPIC hameter Base MQTT topic
METER_1_NAME Electric Meter Friendly name in HA
METER_1_MULTIPLIER 1.0 Calibration multiplier (see below)
METER_1_DEVICE_CLASS energy HA device class — sets smart defaults
METER_1_UNIT (auto) Unit of measurement
METER_1_ICON (auto) HA icon
METER_1_STATE_CLASS total_increasing HA state class
SDR_DEVICE_ID 0 RTL-SDR device index
LOG_LEVEL INFO DEBUG, INFO, WARNING, ERROR

Smart Defaults by Device Class

When you set METER_1_DEVICE_CLASS, the icon and unit are set automatically:

Device Class Icon Unit
energy mdi:flash kWh
gas mdi:fire ft³
water mdi:water gal

You can override any of these with the explicit METER_1_ICON or METER_1_UNIT variables.

Multiple Meters

Add meters using METER_2_*, METER_3_*, etc. (up to METER_9_*):

-e METER_1_ID=23040293 \
-e METER_1_PROTOCOL=scm \
-e METER_1_NAME="Electric Meter" \
-e METER_1_DEVICE_CLASS=energy \
-e METER_2_ID=55512345 \
-e METER_2_PROTOCOL=r900 \
-e METER_2_NAME="Water Meter" \
-e METER_2_DEVICE_CLASS=water \

Gaps are fine (e.g., meter 1 and 3 without 2).

Finding Your Meter ID

Your meter has two numbers:

  • Billing number — printed on the faceplate (e.g., 2698881). Don't use this.
  • Radio serial number (ERT ID) — transmitted over RF (e.g., 23040293). Use this one.

To find the ERT ID, run HAMeter in discovery mode:

docker run --rm \
  --device=/dev/bus/usb \
  -e MQTT_HOST=localhost \
  -e METER_1_ID=0 \
  -e METER_1_PROTOCOL=scm \
  hameter:latest --discover --discover-duration 120

This listens for all nearby meter transmissions for 2 minutes and prints a summary:

DISCOVERY SUMMARY — 12 unique meters found
============================================================
Meter ID      Protocol  Count   Last Reading
--------------------------------------------------
23040293      SCM       8       519161
55512345      R900      3       12345678
...

Cross-reference the IDs with your physical meters to identify which is yours. Your meter will likely be the one with the highest count (since it's closest).

Calibration

The raw value from the meter's radio does not directly equal the reading on the meter display. You need a calibration multiplier to convert raw values to actual units (kWh, gallons, etc.).

How to Calibrate

Step 1: Read your physical meter

Go to the meter and write down the display reading. For example: 59,669 kWh

Step 2: Get the raw reading from HA

In Home Assistant, go to Developer Tools → States and find your meter's raw reading sensor. For example: sensor.electric_meter_raw_reading shows 516,030

Take both readings at roughly the same time so they correspond.

Step 3: Calculate the multiplier

Divide the physical reading by the raw reading:

multiplier = physical_reading / raw_reading
multiplier = 59669 / 516030
multiplier = 0.1156

Step 4: Set the multiplier

Set METER_1_MULTIPLIER=0.1156 in your Docker environment variables and restart the container.

Verifying Calibration

After setting the multiplier, the Reading sensor in HA should closely match your physical meter display. If it drifts over time, repeat the process to recalculate.

The Raw Reading sensor (shown as a diagnostic entity in HA) always shows the unconverted value, so you can recalibrate at any time without removing the multiplier first.

Why Is Calibration Needed?

ERT meters transmit a raw register value, not the displayed reading. The relationship between the two depends on the meter's internal configuration (Kh factor, register multiplier, number of dials). The multiplier accounts for all of these.

Home Assistant Sensors

Each configured meter creates three sensors in HA:

Sensor Example Entity Description
Reading sensor.electric_meter_reading Calibrated value (e.g., 59,669 kWh)
Raw Reading sensor.electric_meter_raw_reading Unconverted register value (diagnostic)
Last Seen sensor.electric_meter_last_seen Timestamp of last received transmission

All three are grouped under a single device in HA with the manufacturer shown as "HAMeter".

Energy Dashboard

To add your electric meter to the HA Energy Dashboard:

  1. Go to Settings → Dashboards → Energy
  2. Under Electricity Grid, click Add Consumption
  3. Select sensor.electric_meter_reading
  4. Optionally set a cost per kWh

Building from Source

git clone https://github.com/your-username/HAMeter.git
cd HAMeter
docker build -t hameter:latest .

The Dockerfile is a multi-stage build:

  1. Go — compiles rtlamr from source
  2. C — compiles rtl-sdr (librtlsdr + rtl_tcp) from source
  3. Python — runtime with paho-mqtt and pyyaml

Unraid Setup

Via Docker UI

  1. Go to Docker → Add Container
  2. Set Repository to hameter:latest
  3. Set Network to Host
  4. Set Extra Parameters to --device=/dev/bus/usb
  5. Add environment variables for MQTT_HOST, METER_1_ID, METER_1_PROTOCOL, etc.
  6. Start the container

USB Passthrough

The SDR dongle must be accessible inside the container. Use --device=/dev/bus/usb to pass the entire USB bus (simplest and most reliable across reboots).

Troubleshooting

No readings appearing

  • Verify the SDR dongle is on a USB 2.0 port (USB 3.0 causes interference)
  • Check that the antenna is attached
  • Run discovery mode to confirm the SDR is receiving signals
  • Check logs: docker logs hameter

"usb_open error -3"

The kernel DVB driver is claiming the device:

rmmod dvb_usb_rtl28xxu

MQTT connection refused

  • Verify Mosquitto is running: docker ps | grep mosquitto
  • Check MQTT_HOST and MQTT_PORT are correct
  • If using Docker bridge networking, use the host IP (not 127.0.0.1)

Sensors not appearing in HA

  • Verify the MQTT integration is configured in HA
  • In HA, go to Developer Tools → MQTT → Listen and subscribe to hameter/# to check if messages are arriving
  • Restart HA if sensors don't appear after the first discovery publish

Supported Meters

HAMeter supports any ERT meter that transmits on the 900 MHz ISM band:

Protocol Typical Manufacturer Meter Type
SCM Itron Electric, Gas
SCM+ Itron Electric, Gas
IDM Itron Electric (with interval data)
R900 Neptune Water
R900BCD Neptune Water
NetIDM Itron Electric (net metering)

License

MIT