The HLW8012 is a single-phase AC electricity-metering chip found in some older smart plugs and switches, including the original Sonoff POW R1. With ESPHome, it can expose RMS voltage, RMS current, active power and accumulated energy to Home Assistant. Unlike the UART-based CSE7766 and BL0942 covered in our previous guides, it communicates through two pulse outputs and one mode-selection pin. The configuration is simple once the chip and device-specific GPIO wiring have been identified correctly.
This guide focuses on adapting a verified, commercially enclosed HLW8012 device that already runs ESPHome, rather than constructing a mains-voltage circuit around a bare chip. The worked configuration uses documented Sonoff POW R1 pin assignments. A model marketed under a similar name may contain another metering IC, different pins or a different Wi-Fi processor; check the exact board revision before applying the example. Official references include the ESPHome HLW8012 documentation and Sonoff POW R1 device profile.
Electrical safety: the digital pins may be live
Danger: On some mains-powered smart plugs, the ESP, metering chip and their GPIO ground are not galvanically isolated from the AC supply. A header labelled 3.3 V, GND, RX or TX may be at a hazardous potential relative to earth. Do not connect a computer, USB adapter, oscilloscope, breadboard, exposed ESP32 or other grounded equipment to a powered device. Do not open, probe, modify or flash a mains-connected unit while it is energised.
Choose a product appropriate for your local supply voltage, plug standard and load rating, keep its certified enclosure intact, and use its existing network update path wherever supported. If a unit needs disassembly or an initial serial flash, follow the manufacturer’s model-specific service procedure or use a qualified professional; this article does not provide live-mains bench wiring instructions. Software power readings are not overcurrent protection, a safety interlock or a substitute for a certified electricity meter. If you are assembling a new ESP32 project, a properly isolated, purpose-built metering interface is the safer starting point.
What the HLW8012 measures
The HLW8012 produces frequency-coded pulses. CF represents active power, while CF1 represents either RMS current or RMS voltage according to the logic level on SEL. ESPHome counts these pulses and applies the configured scale factors to publish engineering units. Its driver alternates the SEL state automatically, so the two CF1 quantities are updated in turn, not at precisely the same instant. Active power can still update while the selected CF1 measurement changes.
| Signal / quantity | Purpose | Practical implication |
|---|---|---|
| CF | Pulse frequency proportional to active power | Incorrect GPIO mapping can produce zero or implausible watts. |
| CF1 | Pulse frequency proportional to voltage or current | The driver needs time in both modes for current and voltage to refresh. |
| SEL | Selects which quantity CF1 represents | An inverted or fixed hardware connection changes the required configuration. |
| Voltage and current | RMS electrical quantities | Their product estimates apparent power, not necessarily active power. |
| Power | Active power in watts | This is the appropriate quantity for energy integration and electricity cost estimates. |
| Energy | Accumulation of measured power over time | Check the unit and reset behaviour before using it as a lifetime billing total. |
For a purely resistive load the apparent-power estimate (volts multiplied by amps) is close to active power. Motors, switching supplies and other reactive or non-linear loads can have a power factor below one, so 230 V × 1 A does not guarantee 230 W. Do not “correct” a valid active-power reading merely because it differs from voltage times current. The HLW8012 integration measures a single phase and is not a three-phase meter.
HLW8012, BL0937, CSE7759 and CSE7766 are not interchangeable
ESPHome’s hlw8012 platform also supports two related chips: CSE7759 and BL0937. The BL0937 requires its own model: setting and commonly an inverted SEL pin; copying an HLW8012 configuration can produce switched or mis-scaled values. The similarly named CSE7759B is different and is handled by ESPHome’s cse7766 platform. Do not infer the chip from the plug’s external appearance or product listing alone.
| Confirmed metering IC | ESPHome platform | Connection to the Wi-Fi MCU |
|---|---|---|
| HLW8012 | hlw8012 | CF, CF1 and SEL pulse/mode lines |
| BL0937 | hlw8012 with model: BL0937 | Similar interface; SEL polarity must match the board |
| CSE7759 | hlw8012 with applicable model/default constants | Confirm board revision and GPIO connections |
| CSE7759B / CSE7766 | cse7766 | UART; do not use an HLW8012 pulse configuration |
| BL0942 | bl0942 | UART; follow the specific device profile |
If you are comparing smart-plug platforms, the related site guides cover BL0942 UART smart-plug monitoring and CSE7766 on the Sonoff POW R2. The original POW R1 example below uses an ESP8266, not an ESP32; ESPHome supports the same HLW8012 component on compatible ESP32-based hardware when its real GPIO map is known.
Hardware and information you need before configuring ESPHome
- A known HLW8012-based power-monitoring device, already flashed with ESPHome or otherwise safely provisioned for compatible firmware.
- The exact model and board revision, including the three connections from the metering IC to the Wi-Fi processor: CF, CF1 and SEL.
- The device’s correct microcontroller definition and any existing relay, status LED and push-button configuration.
- Its existing working ESPHome YAML, Wi-Fi credentials and API/OTA encryption key. Preserve these before editing.
- A commercially enclosed, known load and an independent plug-in reference power meter rated for the load, for non-invasive calibration.
Do not choose GPIO numbers merely because they appear in another plug’s GitHub configuration. The same retail name can be reused with an ESP8266, ESP32 or a different Wi-Fi module, while later hardware revisions may move CF1 to another pin. A wrong relay pin can be particularly disruptive because the relay state might change unexpectedly. Keep any existing switch and boot-time safety settings unchanged while you test the metering sensors.
Sonoff POW R1: verified metering pin assignments
The ESPHome device profile for the original Sonoff POW R1 documents the following connections. These are specific to the R1, not to the POW R2, POW Elite or every later Sonoff power-monitoring model.
| POW R1 function | ESP8266 GPIO | Used in this guide |
|---|---|---|
| HLW8012 SEL | GPIO5 | sel_pin |
| HLW8012 CF1 | GPIO13 | cf1_pin |
| HLW8012 CF | GPIO14 | cf_pin |
| Relay and relay LED | GPIO12 | Existing relay configuration; not required for metering |
| Push-button | GPIO0 | Existing button configuration; not required for metering |
The metering component only needs the three HLW8012 GPIO assignments. If you start from a working POW R1 configuration, append the sensor section below rather than replacing the entire configuration or silently discarding important switch behaviour. In an existing YAML file, there must be only one top-level sensor: block: merge new entries into that list.
Complete ESPHome example for an already provisioned POW R1
This example uses the documented POW R1 GPIOs and the historical Sonoff POW calibration defaults of current_resistor: 0.001 and voltage_divider: 2351. Those numbers are starting values, not universal characteristics of an HLW8012; check the physical device and calibrate against a reference. The sample intentionally does not define a relay: on a working commercial plug, preserve its existing switch configuration separately. It also assumes you have retained the device’s current API key and completed any required staged OTA-encryption migration before switching an older installed device to mandatory encryption.
substitutions:
device_name: pow-r1-meter
esphome:
name: ${device_name}
friendly_name: POW R1 Meter
esp8266:
board: esp01_1m
logger:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
api:
encryption:
key: !secret pow_r1_api_key
ota:
- platform: esphome
encryption:
sensor:
- platform: hlw8012
model: HLW8012
sel_pin: GPIO5
cf_pin: GPIO14
cf1_pin: GPIO13
current_resistor: 0.001
voltage_divider: 2351
update_interval: 30s
change_mode_every: 4
voltage:
name: "Mains Voltage"
id: mains_voltage
accuracy_decimals: 1
current:
name: "Load Current"
id: load_current
accuracy_decimals: 3
power:
name: "Active Power"
id: active_power
accuracy_decimals: 1
energy:
name: "Meter Energy Since Boot"
id: boot_energy
entity_category: diagnostic
accuracy_decimals: 1
- platform: total_daily_energy
name: "Energy Today"
id: energy_today
power_id: active_power
unit_of_measurement: kWh
accuracy_decimals: 3
state_class: total_increasing
device_class: energy
filters:
- multiply: 0.001
time:
- platform: homeassistant
id: homeassistant_time
Secrets and update note: pow_r1_api_key must contain a valid API encryption key, and on an existing device it must be the same key the device is already using. The OTA encryption: block requires a compatible running ESPHome version; an old password-protected device must be updated first while retaining its old OTA password. If you are adapting an existing working installation, preserve its current api:, ota: and Wi-Fi blocks and copy only the hlw8012, energy and time entries until the migration is finished.
The YAML’s two energy sensors deliberately have different purposes. The HLW8012 energy: field reports the chip driver’s accumulated reading in Wh and is labelled “since boot” to discourage treating it as a guaranteed non-resetting billing register. The total_daily_energy sensor integrates the active_power reading, expresses the result in kWh, and resets each day according to the Home Assistant time source. The two sensors should not be added together.
How to adapt the configuration to another ESP32 or ESP8266 device
There is no universal “HLW8012 ESP32 GPIO21/GPIO22” pinout: those numbers are often used for I²C, whereas this chip uses pulse outputs and a selection signal. If you have a commercially enclosed, verified ESP32-based product using the HLW8012, keep its existing esp32: board definition and change only the three metering pins to match its documented schematic or verified ESPHome device profile. Do not copy the esp8266: stanza from the POW R1 sample.
# Illustration only — replace every GPIOXX using your EXACT device profile.
# Merge into an existing, working ESP32 ESPHome configuration.
sensor:
- platform: hlw8012
sel_pin: GPIOXX
cf_pin: GPIOXX
cf1_pin: GPIOXX
voltage:
name: "Voltage"
current:
name: "Current"
power:
name: "Active Power"
update_interval: 30s
These GPIOXX placeholders are not flashable firmware. Use the complete POW R1 example only for that confirmed hardware, or the proper device-specific profile for another model. In particular, an ESP32 dev board’s availability of GPIOs tells you nothing about mains isolation on an unrelated metering breakout.
Why SEL switching affects update speed
Every time ESPHome changes SEL, the first post-switch sample can be unstable; its HLW8012 driver discards that first reading. The option change_mode_every controls how many update cycles occur before the next change. At the documented default value of 8 and an update_interval of 60 seconds, voltage or current can remain on the previous value for several minutes while the other mode is selected. That is normal driver behaviour, not necessarily a disconnected sensor.
For a dashboard where you want both quantities to refresh more often, the example uses update_interval: 30s and change_mode_every: 4. This is a practical starting point, not a guarantee of simultaneous or high-speed readings. Faster polling does not improve calibration and may be inappropriate for low-frequency pulse readings or constrained ESP8266 devices. Power monitoring for household appliances generally does not require a millisecond-level update rate.
What if the board has SEL tied permanently high or low?
Some boards fix the SEL pin in hardware. ESPHome supports initial_mode: CURRENT or VOLTAGE together with change_mode_every: "never". Use the mode that matches the actual fixed wiring and expect only that CF1 quantity to be meaningful. CF can still report active power. It is not possible to recover both current and voltage from a permanently fixed CF1 mode by changing YAML alone. The exact GPIO assigned to sel_pin still has to satisfy the ESPHome component’s pin requirements; do not reroute or modify the live circuit to force dual-mode measurements.
# Place these keys INSIDE the same hlw8012 platform entry
# only for a device whose SEL is documented as fixed:
initial_mode: CURRENT
change_mode_every: "never"
Calibrate voltage, current and active power properly
The defaults in the POW R1 profile correspond to the original board design, but chip tolerance, the fitted shunt, resistor-divider values and device revisions affect accuracy. A small zero-current reading is not a reason to arbitrarily multiply every measurement. First check whether the reference meter, your ESPHome sensor and the load are measuring the same appliance at the same time. Let the device reach a stable operating point and record voltage, current and active power from both meters.
Use a commercial, appropriately rated reference meter and a normal, enclosed resistive appliance such as an electric heater operated within both devices’ ratings. Do not disassemble a heater or use an exposed dummy load. A resistor-like load with power factor close to one makes the calibration easier to interpret. Take readings after the driver has refreshed both voltage and current following SEL mode changes; otherwise you may compare a fresh reference measurement with an old ESPHome value.
- Wrong voltage, correct current: investigate the board’s
voltage_dividervalue and any voltage filter rather than modifying the shunt parameter. - Wrong current, correct voltage: investigate
current_resistor, sensor-model selection and any current multiplier. - Both current and power consistently wrong: check the physical shunt assumptions and model constants; changing the current resistor can affect more than one output.
- Voltage and current plausible but watts wrong: compare active power with a reference meter that reports watts, not just V × A, particularly on a low-power-factor load.
- Very small loads read as zero or fluctuate: account for meter resolution, pulse-frequency limits, update interval and the device’s specified operating range.
ESPHome provides a calibration calculator in the official HLW8012 documentation. Enter the existing configuration values, the ESPHome readings and your simultaneous reference measurements; apply the resulting settings to that individual device. Save the original YAML first. Avoid copying a random calibration number from another smart plug, even when both products use an HLW8012 IC.
Why a software multiplier is not a substitute for safe hardware ratings
The current_resistor field describes the scale of the fitted physical shunt. It cannot make a low-current connector, relay, PCB trace or shunt safely carry more current. Likewise, adjusting voltage_divider changes how the pulse reading is interpreted; it does not make a 120 V-rated appliance suitable for a 230 V outlet. Obey the smallest actual electrical rating stated by the completed product manufacturer, not a hypothetical value inferred from firmware.
Choosing the right energy sensor for Home Assistant
Power is an instantaneous or averaged rate in watts. Energy is the integral of power over time in watt-hours or kilowatt-hours; 100 W sustained for ten hours is 1 kWh. ESPHome can expose a raw accumulated HLW8012 energy register, produce a daily total from the active-power sensor, or integrate that sensor into a longer-running total. These are alternatives with different reset and recovery behaviour. Incorrect units or a frequently resetting total are common causes of misleading energy statistics.
| Energy representation | Normal use | Reset / persistence consideration |
|---|---|---|
HLW8012 energy:, Wh | Diagnostic accumulated reading from the metering driver | Treat as potentially reset on device reboot; verify on actual device. |
total_daily_energy, kWh | Today’s use, daily cards or automations | Resets at local midnight; relies on a valid time source and saved state for reboot recovery. |
integration, kWh | A running calculated total for the Energy dashboard | restore: true saves state but frequent flash writes can create wear. |
| Home Assistant energy integration / statistics | Longer-term reporting managed in HA | Requires consistent entity units, device class, statistics and recorder history. |
If you need a cumulative sensor in addition to daily energy, ESPHome’s integration sensor can calculate kWh from watts with time_unit: h and a multiply: 0.001 filter. Only enable on-device restore: true after considering how often the device will write to flash, especially on older ESP8266 hardware. A Home Assistant-side integral helper with appropriate recorder and availability settings can be preferable when the node has limited storage.
# Optional: add under the existing top-level sensor: list.
# Use this INSTEAD OF treating the boot-only Wh counter as lifetime kWh.
- platform: integration
name: "Calculated Total Energy"
sensor: active_power
time_unit: h
integration_method: trapezoid
restore: false
unit_of_measurement: kWh
accuracy_decimals: 3
device_class: energy
state_class: total_increasing
filters:
- multiply: 0.001
This optional example sets restore: false deliberately: its total starts over whenever the device reboots, making it unsuitable as a stand-alone lifetime billing counter. If you enable restoration, evaluate flash endurance and check how your Home Assistant statistics handle device replacement and counter resets. For a straightforward daily view, use the complete example’s total_daily_energy sensor instead; do not enable every possible energy counter just to produce more entities.
Set up useful Home Assistant views
After uploading the configuration, confirm that the node is connected through the ESPHome integration and that Home Assistant receives current, voltage and active power. Add a history or statistics card for watts to see when a kettle, heater or pump turns on. A separate daily-energy card is useful for comparing the appliance’s use from day to day. Use the Energy dashboard only with a sensor whose unit, device_class: energy and state_class are appropriate and whose reset behaviour you understand.
Avoid calculating energy by multiplying a single live power value by 24 hours. A washing machine or refrigerator has varying power draw, so the resulting estimate can be wildly inaccurate. Similarly, switch OFF does not necessarily mean zero measured watts: the meter or Wi-Fi module may still draw standby power, and some devices measure only the switched load rather than the entire product’s supply. Verify what the particular meter physically monitors.
Appliance-running notifications
A threshold automation can notify you when a dishwasher or washing machine has finished, but set the threshold using a power history from a real cycle and account for pauses. For example, require the appliance to exceed a meaningful threshold first, then remain below a separate lower threshold for several minutes before notifying. Do not use a simple “watts below 5” alert from an idle state; it will report completion repeatedly when nothing has started. Home Assistant automations should treat an unavailable reading as a device fault, not proof that a load has stopped.
Use the meter for monitoring and convenience automations, not as the sole protection against overloads, overheating or malfunctioning mains appliances. A software-controlled smart plug is not a replacement for a correctly rated fuse, circuit breaker, protective earth or appliance thermal cut-out.
Troubleshooting: no readings, reversed modes and inaccurate totals
| Observed symptom | Likely explanation | Check first |
|---|---|---|
| Voltage and current missing, power present | CF is working but CF1 or SEL is mis-mapped or its mode never changes. | Confirm the exact hardware profile and the CF1/SEL GPIO assignments. |
| Power always zero but voltage is reasonable | CF pulse input is wrong, inactive or the monitored load is not in circuit. | Check cf_pin, the device’s metering path and whether the load is actually drawing power. |
| Current displays mains voltage or the reverse | Wrong SEL polarity, wrong model, or wrong initial_mode. | Identify the chip and verified board-specific configuration. |
| Voltage or current updates very slowly | SEL switches only after multiple polling intervals and a transition sample is discarded. | Review update_interval, change_mode_every and update timestamps. |
| Voltage looks realistic but watts are wildly wrong | Wrong chip model, resistor/shunt constants or CF input. | Restore the verified model defaults and calibrate with a reference meter. |
| Daily energy does not reset at midnight | Time source is unavailable or local time is not configured as intended. | Check the time: source and Home Assistant connection/time zone. |
| Energy appears to drop after restart | You used a boot-only total or a non-restored integration sensor. | Use a daily total or a deliberately managed cumulative counter with suitable statistics. |
| Device unavailable following firmware update | Wi-Fi/API/OTA mismatch, incorrect board definition or corrupted configuration. | Use the previously saved YAML and the ESPHome OTA recovery guide. |
If the device reports nan, unexpected spikes or an intermittent reading, avoid filtering aggressively before finding the actual cause. A median or throttling filter can hide an incorrect SEL setup, calibration error or missing pulses. Conversely, a small non-zero watt reading with no connected load can be measurement noise or internal consumption; compare it against a reference before adding a zeroing threshold that might also erase legitimate standby energy.
HLW8012 versus newer metering options
An existing, functional HLW8012 plug is often worth keeping if it meets your electrical and networking requirements. For a new installation, though, choose the measurement architecture based on the load and required accuracy rather than the chip’s age. A built-in smart-plug meter monitors one appliance; a DIN-rail or CT-based system monitors a dedicated circuit; a multi-channel energy IC can aggregate several loads with appropriately engineered voltage references and current sensors. Those designs have different electrical installation requirements.
- For a compatible Sonoff POW R2 with UART metering, read the CSE7766 guide; its 4,800-baud serial configuration cannot be substituted for HLW8012 pulse pins.
- For enclosed smart plugs using a BL0942 UART chip, use the BL0942 article.
- For three AC current inputs and appropriately designed voltage sensing, see the ATM90E32 multi-circuit guide; three CT connections alone do not imply three independent phase-voltage measurements.
- For separate low-voltage DC loads, the INA3221 three-channel DC guide describes a completely different, non-mains measurement arrangement.
Frequently asked questions
Can I connect an HLW8012 smart-plug board directly to an ESP32 development board?
Not safely by assumption. The metering board’s “GND” may be tied to mains, and its voltage, supply isolation and logic interface must be verified from the exact circuit design. Never connect a mains-powered, non-isolated board to a USB-connected ESP32, laptop or oscilloscope. This article’s software example assumes a complete enclosed product with its original processor, not a bare metering PCB wired to a hobby development board.
Does ESPHome report true power or just voltage multiplied by current?
The HLW8012 power: channel uses the CF active-power pulse output. Voltage times current is apparent power, which can differ from active power for motors and non-linear loads. Calibrate against a reference meter that actually reports watts; a simple multimeter voltage measurement cannot establish the power calibration.
Why does my smart plug say BL0937 when this article is about HLW8012?
ESPHome supports BL0937 with the same hlw8012 component, but it needs model: BL0937 and the correct SEL polarity for its board. Do not reuse the Sonoff POW R1 GPIOs or constants. Locate a profile for the exact device and revision before editing firmware.
Can I use the HLW8012 to monitor solar export or three phases?
A typical single-phase smart-plug implementation is intended to measure its designated load and does not, by itself, provide certified import/export accounting or three-phase measurements. Bidirectional energy metering requires an appropriately designed and rated meter with documented treatment of reverse flow. For whole-home solar, grid exchange or three-phase circuits, select purpose-built equipment and have any mains work performed by a qualified installer.
Will higher update frequency make the energy total more accurate?
Not necessarily. Pulse resolution, calibration, the electrical load, SEL-mode scheduling, integration method and missing data often matter more. A moderate interval such as 30 seconds is reasonable for observing appliance patterns; compare the total measured across a known period against a reference meter before changing polling settings solely to improve apparent precision.
Sources and further reading
- ESPHome: HLW8012 Power Sensor — component options, supported models, SEL behaviour and calibration.
- ESPHome Devices: Sonoff POW R1 — documented GPIO mapping for the worked hardware.
- ESPHome: Total Daily Energy Sensor — W-to-kWh integration, daily resets and restoration.
- ESPHome: Integration Sensor — cumulative integration and non-volatile state trade-offs.
- ESPHome: Native OTA Updates and Encryption — current secure OTA configuration and upgrade steps.
Bottom line: confirm the exact metering IC and product revision, use the device’s genuine CF/CF1/SEL map, then calibrate active power against a trusted reference. Keep the mains-connected hardware enclosed, preserve working relay and security settings, and choose one clearly understood energy-total strategy instead of trusting an unexplained kWh number.