ESPamr is an ESPHome external component for receiving Itron ERT-SCM utility meter broadcasts with an ESP32 and a CC1101 radio module. Unlike implementations up to now, it does not require an RTL-SDR or a computer, just a cheap ESP32 and CC1101.
It configures the CC1101, captures the meter signal, decodes SCM frames on the ESP32, and publishes the results to Home Assistant. The intended setup is simple: wire a CC1101 to an ESP32, add the component to an ESPHome YAML file, flash it, and let the built-in autotune find the best frequency/RSSI settings for your location.
You need:
- An ESP32 board (we used this ESP-32-S one)
- A CC1101 module that supports the 900 MHz ISM band (NOT the typical 433MHz ones; we used this one from Rabbit-Labs)
- By default it comes with the "900 MHz High-Gain Antenna", which we used (it's an Ebyte TX915-JKS-20 antenna)
Default wiring used by the example config:
| CC1101 | ESP32 |
|---|---|
CS |
GPIO5 |
GDO0 |
GPIO12 |
unused |
unused |
MISO |
GPIO19 |
SCK |
GPIO18 |
MOSI |
GPIO23 |
VCC |
3.3V |
GND |
GND |
The ESP GPIOs to connect to each CC1101 pin are configurable in YAML.
If you use the Rabbit-Labs CC1101, you can see which pins are which, since they're not marked on the actual board:
The simplest workflow:
- Clone or download this repo.
- Copy
espamr.example.yamltoespamr.yamland customize it. - Copy
secrets.example.yamltosecrets.yamland customize it. - Flash with ESPHome using
esphome run espamr.yaml.
The default config leaves frequency and rssi_delta unset. That puts ESPamr in autotune mode, which is the recommended default for first boot.
The example uses the local component path:
external_components:
- source:
type: local
path: ./components
components: [espamr]espamr.yaml and secrets.yaml are ignored by Git, so you can change your pins, frequency, MQTT settings, and other local values without blocking future git pull updates.
If you want to use your own .yaml file instead of running from a local checkout, use the commented type: git block in espamr.example.yaml. In that mode ESPHome downloads ESPamr while compiling firmware. The ESP32 itself does not fetch anything from GitHub at runtime.
The minimal config is below:
esphome:
name: espamr
friendly_name: ESPamr
esp32:
board: nodemcu-32s
framework:
type: arduino
cpu_frequency: 240MHz
logger:
level: INFO
api:
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
external_components:
- source:
type: local
path: ./components
components: [espamr]
espamr:
sck_pin: GPIO18
miso_pin: GPIO19
mosi_pin: GPIO23
cs_pin: GPIO5
gdo0_pin: GPIO12ESPamr always exposes these controls through ESPHome / Home Assistant:
FrequencyRSSI DeltaAutotuneAutotune Reset
Optional sensors can be enabled in YAML:
espamr:
# ...
last_frame:
name: "Last Frame"
okph:
name: "Rolling OK/hr"
scm_attph:
name: "Rolling Attempts/hr"
autotune_status:
name: "Autotune Status"
autotune_progress:
name: "Autotune Progress"For automatic per-meter Home Assistant devices/entities, enable MQTT in your ESPHome YAML. ESPHome's native API cannot dynamically create entities for meter IDs discovered after compile time, so ESPamr uses Home Assistant MQTT Discovery for per-meter entities.
Recommended MQTT settings:
mqtt:
broker: !secret mqtt_broker
username: !secret mqtt_username
password: !secret mqtt_password
topic_prefix: !secret mqtt_topic_prefix
keepalive: 60s
discovery: false
discovery_retain: falsediscovery: false only disables ESPHome's own MQTT discovery for its static entities, to avoid clashing with the ESPHome API-provided ones. ESPamr will still publish its per-meter discovery messages.
ESPamr has two radio setup modes:
- Autotune mode: omit both
frequencyandrssi_delta. - Manual mode: specify both
frequencyandrssi_delta.
Autotune mode is the recommended default. On first boot, ESPamr scans candidate settings and saves the best result in ESP32 non-volatile storage. Future reboots reuse the saved settings.
Manual mode example:
espamr:
# ...
frequency: 914.25
rssi_delta: 2Use Autotune Reset in Home Assistant to clear saved tuning values. Use the Autotune switch to start or stop a new scan.
ESPamr supports two capture backends:
espamr:
backend: rmtrmt is the default and recommended backend on ESP32. It uses ESP32 hardware capture to reduce timing sensitivity from Wi-Fi, MQTT, and other background work.
espamr:
backend: gpiogpio is a fallback/debug backend that captures edges directly with GPIO interrupts. Use it only if RMT is unavailable or you are comparing behavior.
- The component currently targets ERT-SCM frames, not SCM+.
- The CC1101 is used in direct async OOK mode; packet-mode decoding is not part of the public release.
- Use
logger: level: INFOfor normal operation. Very verbose logging can reduce capture reliability. - Use
esp32: cpu_frequency: 240MHzfor best performance. - If MQTT disconnects with
No PING_RESP, keepwifi: power_save_mode: noneand use a longer MQTT keepalive such as60s.
This repo includes one tracked example YAML:
- espamr.example.yaml: copy this to
espamr.yamland edit it.
Your real device config belongs in espamr.yaml, and your real secret values belong in secrets.yaml. Both are ignored by Git.
ESPamr is licensed under the Apache License, Version 2.0. See LICENSE.
Contributions are covered by CONTRIBUTING.md and CLA.md.