[ Athom Smart Plug V3 — Dentra Energy Stats in ESPHome ]

[ Overview ]

The Athom Smart Plug V3 is an inexpensive
(~$10-12) ESP-based WiFi smart plug that ships with ESPHome
pre-flashed and the source available on GitHub. Out of the box you
get instantaneous power / voltage / current / power-factor sensors
and a cumulative total_energy_sensor — useful, but
not directly usable for the kind of dashboards most people actually
want ("how much did this fridge use yesterday / this week / this
month?").

The dentra/esphome-components
collection includes an energy_statistics component that
reads any cumulative energy sensor and breaks it into rolling Today /
Yesterday / Week / Month / Year buckets. Combined with the official
Athom base package via ESPHome's packages: include, the
whole thing is about 40 lines of YAML per plug and lights up the
Energy dashboard cards you actually want.

This guide is the full known-working config plus the reasoning for
each block. It's the file I drop onto every new V3 plug and flash
once — that's it.

[ What you get ]

After flashing, the device shows up in Home Assistant with the
standard Athom sensors plus five new ones:

  — Energy Today      — kWh since 00:00
                                  local time
  — Energy Yesterday  — the previous day's
                                  final total, frozen at midnight
                                  rollover
  — Energy Week       — running total since
                                  the start of the current week
  — Energy Month      — running total since
                                  the 1st of the current month
  — Energy Year       — running total since
                                  January 1st

All five reset automatically at their respective boundaries (midnight
in your configured timezone for Today / Yesterday, Monday 00:00 for
Week, etc.) and persist through reboots — the component stores
state in NVRAM so a power blip doesn't zero the running totals.

The cumulative total_energy_sensor the Athom base config
provides stays intact and continues exposing lifetime kWh, so you can
keep using it for whole-of-life consumption tracking.

[ Requirements ]

Athom Smart Plug V3athom.tech
    has them direct, also widely available on AliExpress / Amazon.
    Make sure it's the V3 — older revisions use
    different ESP chips and different base configs
  — ESPHome dashboard — Home Assistant
    add-on, standalone Docker, or just pip install esphome
    and running locally
  — Wi-Fi credentials in secrets.yamlwifi_ssid and wifi_password
  — The plug pre-adopted into your ESPHome dashboard — on a
    fresh V3 this happens automatically via the captive portal it
    spins up on first boot

No soldering, no UART tinkering, no JTAG, no replacement firmware.
The V3 ships with ESPHome already on it; everything below is an
OTA reflash of a config you author.

[ Full config ]

The complete working config for one plug. Paste this as
athom-smart-plug-1a2b3c.yaml in your ESPHome dashboard,
swap the per-device fields at the top, and click Install:
substitutions:
  name: "athom-smart-plug-1a2b3c"
  friendly_name: "Athom Plug V3 1a2b3c"
  current_limit: "16"                  # US (AU would be 10)
  timezone: "Pacific/Honolulu"         # Maui

packages:
  athom_plug:
    url: https://github.com/athom-tech/esp32-configs
    ref: main
    files: [athom-smart-plug.yaml]
    refresh: 1d

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# --- Fancy energy breakdown: Today / Yesterday / Week / Month / Year ---
external_components:
  - source: github://dentra/esphome-components
    components: [energy_statistics]

sensor:
  - platform: energy_statistics
    total: total_energy_sensor         # provided by the Athom base config
    energy_today:
      name: "Energy Today"
      accuracy_decimals: 3
      icon: mdi:hours-24
    energy_yesterday:
      name: "Energy Yesterday"
      accuracy_decimals: 3
      icon: mdi:calendar-today
    energy_week:
      name: "Energy Week"
      accuracy_decimals: 3
      icon: mdi:calendar-week
    energy_month:
      name: "Energy Month"
      accuracy_decimals: 3
      icon: mdi:calendar-month
    energy_year:
      name: "Energy Year"
      accuracy_decimals: 3
      icon: mdi:calendar
The rest of this page is a walkthrough of why each block is the way
it is and what changes per plug.

[ Step 1 — Substitutions ]

substitutions:
  name: "athom-smart-plug-1a2b3c"
  friendly_name: "Athom Plug V3 1a2b3c"
  current_limit: "16"                  # US (AU would be 10)
  timezone: "Pacific/Honolulu"         # Maui
Four values that change per device or per install:

name — the ESPHome node hostname.
Must be unique on your network. The convention I follow is
athom-smart-plug-<last-3-bytes-of-MAC> — the MAC
is printed on the plug's label and on the captive-portal page it
serves on first boot. Anything works as long as it's unique;
predictable per-MAC names make fleet management easier than
arbitrary "kitchen_plug" / "lamp_plug" names that drift as you
relocate plugs.

friendly_name — what shows up in
the Home Assistant UI as the device name. Friendly version of the
hostname — you can change this later in HA without re-flashing
if you decide on a different scheme, so don't sweat it too much at
flash time.

current_limit — safety cutoff for
the on-board current sensor. The plug will trip and disconnect the
relay if it sees sustained draw above this many amps. Set to the
maximum continuous current rating for your local outlet standard:
16A for US/EU NEMA 5-15 / Schuko outlets,
10A for AU/UK lower-current outlets. Don't crank
this up — the plug's internal relay is only rated for the
nominal current and will eventually fail (or worse) if pushed past
it.

timezone — IANA timezone string
(Pacific/Honolulu, America/New_York,
Europe/London, etc.) — this is what
energy_statistics uses to figure out when "midnight"
happens for the Today / Yesterday rollover and when Monday starts
for Week. Get this wrong and your "Energy Today" will reset at a
weird time. Full IANA list at
en.wikipedia.org/wiki/List_of_tz_database_time_zones.

[ Step 2 — The Athom base package ]

packages:
  athom_plug:
    url: https://github.com/athom-tech/esp32-configs
    ref: main
    files: [athom-smart-plug.yaml]
    refresh: 1d
This pulls in the official Athom base configuration from
athom-tech/esp32-configs
— the ESPHome packages: feature stitches a remote
YAML file into yours at build time. Everything in
athom-smart-plug.yaml upstream — the GPIO pin
assignments for the relay and button, the CSE7766 power monitor
driver setup, the WS2812 status LED, the OTA / API blocks, the
button-press behaviour, the relay-state-restore-after-reboot
config — lands in your config as if you'd typed it in.

Why use the package include instead of pasting it inline?

Two reasons:

  — Athom occasionally pushes fixes / improvements (better
    calibration constants for the CSE7766, status-LED behaviour
    tweaks). With refresh: 1d, the ESPHome dashboard
    re-downloads the package once per day, so the next time you
    re-flash a plug you get those improvements for free without
    chasing diffs.

  — Multi-plug fleets stay consistent. Every plug shares the
    same base config, with only the substitutions block changing
    per device. Bug fix upstream propagates everywhere on the next
    flash cycle.

If you'd rather pin to a specific known-good revision and never get
surprised, change ref: main to a specific commit SHA
(ref: a1b2c3d) or a tag. Then update only when you
choose.

[ Step 3 — Wi-Fi ]

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
Standard ESPHome pattern: pull credentials from
secrets.yaml rather than baking them into per-plug
configs that you might check into a public dotfiles repo or share
in a forum post. The Athom base package doesn't set Wi-Fi for you
— it expects the parent config to do that — so this block
is required.

If you don't have secrets.yaml set up yet: create
/config/esphome/secrets.yaml with two lines:

    wifi_ssid: "YourSSID"
    wifi_password: "YourPassword"

The ESPHome dashboard reads it from that fixed location across all
your projects; you only set it once.

[ Step 4 — Dentra external component ]

external_components:
  - source: github://dentra/esphome-components
    components: [energy_statistics]
external_components: tells ESPHome to fetch additional
component code from outside its built-in library at compile time.
dentra/esphome-components
is a well-maintained collection of useful add-ons; we're pulling
just one component out of it (energy_statistics) to
keep the firmware image lean.

The github://dentra/esphome-components shorthand
expands to "clone the default branch of that repo." If you want to
pin to a release tag or a specific commit (recommended once you
have it working — same reasoning as the Athom package pin),
the long form is:

    source:
      type: git
      url: https://github.com/dentra/esphome-components
      ref: v1.2.3              # or a commit SHA

The components: [energy_statistics] filter is important
— the repo contains dozens of components and without the
filter ESPHome will try to compile all of them, blowing up your
firmware image size and possibly hitting flash limits on smaller
ESPs.

[ Step 5 — Energy sensors ]

sensor:
  - platform: energy_statistics
    total: total_energy_sensor         # provided by the Athom base config
    energy_today:
      name: "Energy Today"
      accuracy_decimals: 3
      icon: mdi:hours-24
    energy_yesterday:
      name: "Energy Yesterday"
      accuracy_decimals: 3
      icon: mdi:calendar-today
    energy_week:
      name: "Energy Week"
      accuracy_decimals: 3
      icon: mdi:calendar-week
    energy_month:
      name: "Energy Month"
      accuracy_decimals: 3
      icon: mdi:calendar-month
    energy_year:
      name: "Energy Year"
      accuracy_decimals: 3
      icon: mdi:calendar
The actual work. One energy_statistics platform
declaration that reads from total: total_energy_sensor
— the cumulative-kWh sensor ID that the Athom base package
exposes — and produces five bucketed children.

total: — this is the source
sensor's ID, not its name. The Athom base config defines
the cumulative sensor with id: total_energy_sensor;
that's what we reference here. If you ever retarget this guide to
a different smart plug brand, check that brand's base config for
the equivalent cumulative-energy sensor ID and substitute it.

accuracy_decimals: 3 — three
decimal places (Wh-resolution on a kWh reading). Higher precision
than the source sensor produces is meaningless; lower throws away
information you might want. Three is the sweet spot for the CSE7766
chip the plug uses.

icon: — cosmetic. Material
Design Icons by name; HA picks them up automatically. The chosen
set distinguishes the five buckets at a glance on the device page
(mdi:hours-24 for today, mdi:calendar-week
for week, etc.). Drop the icon lines if you don't care; HA falls
back to a generic energy icon.

Each child also gets a name: field; that becomes the
HA entity friendly name (sensor.athom_plug_v3_1a2b3c_energy_today,
etc.). The entity_id auto-derives from the device's name
substitution + this name.

[ Step 6 — Flash & verify ]

  1. ESPHome dashboard → New device (or edit an
     existing one). Paste the full config from
     step 0. Adjust the substitutions
     block.

  2. Save → Install. First flash should be over
     USB if the plug isn't on Wi-Fi yet; subsequent re-flashes are
     OTA. Compile takes 60-90 seconds; OTA upload another ~30s.

  3. Verify on the ESPHome side: the dashboard
     should now show the plug as Online with five new sensors in
     its preview — Energy Today / Yesterday / Week / Month /
     Year — alongside the stock Power / Voltage / Current /
     Power Factor / Total Energy.

  4. Verify in Home Assistant: HA should auto-pick
     up the new sensors via the ESPHome API integration. Look under
     Settings → Devices & Services → ESPHome →
     (your plug) — the five new entities appear there.

  5. Plug something in with a known steady draw
     (LED bulb, phone charger). Watch
     sensor.<plug_id>_energy_today tick up over a
     few minutes. If it does, you're done.

  6. Optional: add to Energy dashboard.
     Settings → Dashboards → Energy → Add consumption,
     pick sensor.<plug_id>_energy_today. The
     Energy dashboard expects a cumulative-kWh source, NOT a
     resetting one — so for the Energy card itself, use the
     stock total_energy_sensor (also exposed). The
     bucketed sensors from this guide are for your own dashboards,
     templates, and automations.

[ Troubleshooting ]

  Compile fails: "energy_statistics not found"
    Either the external_components: block is missing,
    or the components: [energy_statistics] filter is
    typo'd. Component names are case-sensitive.

  Compile fails: "total_energy_sensor not declared"
    The Athom base package didn't load — usually because the
    packages: block is wrong (typo in url / files /
    ref) or the dashboard is offline and can't fetch. Check the
    ESPHome compile log; the package-fetch failure is loud.

  Plug compiles and flashes but sensors stay at 0
    Make sure something is actually drawing power through the plug
    (>1W or so — some plugs have a small noise floor). If you
    see Power moving but Energy Today stays at 0, give it a few
    minutes — energy_statistics updates on a
    poll cycle, not every Power reading.

  Energy Today resets at the wrong time
    Timezone in substitutions: doesn't match where you
    live, or your ESPHome host isn't synced to NTP. Verify with
    esphome logs <config.yaml> — the log
    prints the resolved timezone on boot.

  Energy Today / Yesterday reset on every reboot
    NVRAM persistence requires the
    esp32: ... preferences: block in the base config
    (Athom's includes this, so this should "just work"). If you've
    overridden the base config or you're seeing this on a non-Athom
    plug, add an explicit:

        preferences:
          flash_write_interval: 1min

    so state survives across boots.

  Sensor names look weird in HA
    Entity IDs auto-derive from name in
    substitutions:. To rename without re-flashing, do
    it in HA itself — Settings → Devices &
    Services → ESPHome → (plug) → pencil icon.
    Don't try to override entity_id in the config
    block; the Athom base package controls the prefix.

[ Multi-plug fleet ]

For more than 2-3 plugs, copy this file once per plug and only
change the substitutions: block. A naming convention
based on the MAC suffix (printed on the plug, never changes,
unique by definition) saves a lot of "which one was this again?"
later:

    athom-smart-plug-1a2b3c.yaml    (substitution name: athom-smart-plug-1a2b3c)
    athom-smart-plug-4d5e6f.yaml    (substitution name: athom-smart-plug-4d5e6f)
    athom-smart-plug-7890ab.yaml    (substitution name: athom-smart-plug-7890ab)

The ESPHome dashboard sorts alphabetically, so a consistent prefix
keeps all your Athom plugs grouped. The friendly name in HA can be
whatever — you change that per-plug after flash via
Settings → Devices & Services → ESPHome →
(plug) → rename — the underlying hostname stays
predictable and stable.

Sharing the per-plug delta via YAML anchors.
If the only thing that differs between plugs is the substitutions
block, ESPHome doesn't have a great way to share the rest across
files — you can't !include a parent file that
references substitutions from the child. The pragmatic approach
is: keep one
athom-smart-plug-template.yaml as your gold-standard
master, and create new per-plug files via copy. When you change
something (e.g. pinning ref: to a new Athom commit),
sed across the lot:

    for f in athom-smart-plug-*.yaml; do
      sed -i 's|ref: main|ref: a1b2c3d|' "$f"
    done

Then Install → All from the ESPHome dashboard.
Cycle time per plug for an OTA reflash is ~90 seconds.

[ See Also ]