Files
HAMeter/README.md
2026-03-06 12:43:01 -05:00

11 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

  • Web UI for all configuration — setup wizard, meter management, calibration, discovery, live logs
  • Reads SCM, SCM+, IDM, NetIDM, R900, and R900BCD meter protocols
  • Home Assistant MQTT auto-discovery — sensors appear automatically
  • Four HA sensors per meter: calibrated reading, raw reading, last seen, cost (if enabled)
  • Built-in calibration tool to match raw readings to your physical meter display
  • Discovery mode to scan for nearby meter IDs
  • Cost tracking with per-unit rates and fixed charges
  • Real-time dashboard with Server-Sent Events
  • Configuration export/import (JSON)
  • Persistent config and cost state across restarts

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 \
  -p 9090:9090 \
  -v /mnt/user/appdata/hameter:/data \
  hameter:latest

Open http://<your-host-ip>:9090 in a browser. The setup wizard will guide you through MQTT configuration and adding your first meter.

Docker Configuration

Parameter Required Description
-p 9090:9090 Yes Web UI port
-v /path/to/data:/data Yes Persistent storage for config and cost state
--device=/dev/bus/usb Yes USB passthrough for the RTL-SDR dongle
-e FLASK_SECRET_KEY=... No Flask session secret (random value generated if not set)

All meter, MQTT, and general settings are configured through the web UI — no environment variables needed.

Web UI

After starting the container, open http://<your-host-ip>:9090 to access:

Page Description
Dashboard Live meter readings, costs, pipeline status
Discovery Scan for nearby meter transmissions
Meters Add, edit, delete meters; manage cost rates
Calibration Calculate and apply calibration multipliers
MQTT Settings Configure broker connection; test connectivity
General Settings SDR device ID, RTL-TCP settings, log level
Logs Real-time application log viewer
Config Export/Import Backup and restore configuration

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, go to the Discovery page in the web UI and click Start Discovery. HAMeter will listen for all nearby meter transmissions and display them in a table sorted by frequency. Your meter will likely be the one with the highest count (since it's closest). You can add a discovered meter directly from the results.

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

  1. Go to the Calibration page in the web UI
  2. Select your meter from the dropdown
  3. Enter the raw reading shown on the dashboard
  4. Read the display on your physical meter and enter that value
  5. Click Calculate — the multiplier is computed automatically
  6. Review the preview, then click Apply Multiplier

The pipeline will restart with the new multiplier, and cached readings are cleared so the dashboard shows clean data.

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. Common multipliers are 0.01 (raw is in Wh, display is kWh) or 0.1.

Cost Tracking

HAMeter can track estimated utility costs based on your rate structure.

Setup

  1. Go to Meters and edit a meter
  2. Under Rate Components (Cost Factors), add your rate entries:
    • Per Unit — variable rate charged per unit consumed (e.g., $0.12/kWh)
    • Fixed — flat monthly charges (e.g., $15 service fee)
  3. Save the meter

How It Works

  • Per-unit costs are calculated automatically with each meter reading
  • Fixed charges are applied manually from the dashboard when your billing cycle starts
  • Billing period reset sets the cumulative cost back to $0 for a new cycle
  • Cost state is persisted to disk and survives container restarts

Home Assistant

When cost tracking is enabled for a meter, an additional Cost sensor is published via MQTT auto-discovery (e.g., sensor.electric_meter_cost) with device_class: monetary and state_class: total.

Home Assistant Sensors

Each configured meter creates sensors in HA via MQTT auto-discovery:

Sensor Example Entity Description
Reading sensor.electric_meter_reading Calibrated value (e.g., 5,316 kWh)
Raw Reading sensor.electric_meter_raw_reading Unconverted register value (diagnostic)
Last Seen sensor.electric_meter_last_seen Timestamp of last received transmission
Cost sensor.electric_meter_cost Cumulative cost (only if cost_factors configured)

All sensors 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 use the cost sensor or set a static cost per kWh

Smart Defaults

When you set a device class for a meter, the unit and icon are set automatically:

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

You can override these in the meter edit form.

Configuration File

Configuration is stored at /data/config.json inside the container. You can back it up via the Config Export feature in the web UI, or by copying the file directly from the mounted volume.

Cost state is stored separately at /data/cost_state.json.

YAML Migration

If you have a legacy hameter.yaml config file at /config/hameter.yaml or /app/config/hameter.yaml, HAMeter will automatically migrate it to JSON on first startup.

Unraid Setup

Via Docker UI

  1. Go to Docker > Add Container
  2. Set Repository to hameter:latest (or your registry path)
  3. Set Network Type to Host (or bridge with port 9090 mapped)
  4. Add Device: /dev/bus/usb
  5. Add Path: Container /data mapped to /mnt/user/appdata/hameter
  6. Start the container and open the web UI at http://<unraid-ip>:9090

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

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 Flask, paho-mqtt, and pyyaml

API

HAMeter exposes a REST API at the same port as the web UI. Key endpoints:

Endpoint Method Description
/api/status GET Pipeline status
/api/readings GET Current meter readings
/api/costs GET Cost state for all meters
/api/events GET SSE stream for live updates
/api/setup POST Initial setup
/api/config/mqtt GET/POST MQTT configuration
/api/config/mqtt/test POST Test MQTT connection
/api/config/meters GET/POST List/add meters
/api/config/meters/<id> PUT/DELETE Update/delete a meter
/api/config/general GET/POST General settings
/api/config/export GET Export configuration
/api/config/import POST Import configuration
/api/discovery/start POST Start meter discovery
/api/discovery/stop POST Stop discovery
/api/discovery/results GET Get discovery results
/api/discovery/add/<id> POST Add discovered meter
/api/calibration/calculate POST Calculate multiplier
/api/calibration/apply POST Apply multiplier
/api/readings/clear POST Clear cached readings
/api/costs/<id>/reset POST Reset billing period
/api/costs/<id>/add-fixed POST Apply fixed charges
/api/pipeline/restart POST Restart pipeline

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)
NetIDM Itron Electric (net metering)
R900 Neptune Water
R900BCD Neptune Water

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 from the web UI to confirm the SDR is receiving signals
  • Check the Logs page or 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
  • Use the Test Connection button on the MQTT settings page
  • 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

Pipeline stuck or not starting

  • Check the Logs page for error details
  • Use Restart Pipeline from the dashboard
  • Verify the SDR dongle is connected and not in use by another application

License

MIT