[ 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 ]