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
- Go to the Calibration page in the web UI
- Select your meter from the dropdown
- Enter the raw reading shown on the dashboard
- Read the display on your physical meter and enter that value
- Click Calculate — the multiplier is computed automatically
- 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
- Go to Meters and edit a meter
- 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)
- 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:
- Go to Settings > Dashboards > Energy
- Under Electricity Grid, click Add Consumption
- Select
sensor.electric_meter_reading - 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
- Go to Docker > Add Container
- Set Repository to
hameter:latest(or your registry path) - Set Network Type to Host (or bridge with port 9090 mapped)
- Add Device:
/dev/bus/usb - Add Path: Container
/datamapped to/mnt/user/appdata/hameter - 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:
- Go — compiles
rtlamrfrom source - C — compiles
rtl-sdr(librtlsdr + rtl_tcp) from source - 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