Skip to main content

Python client for downloading electricity usage data from Enova Power

Project description

enovapower

PyPI version Python versions License

⚠️ Unofficial project — not affiliated with, endorsed by, or supported by Enova Power Corp. "Enova Power" is a trademark of its respective owner. Use at your own risk under the Apache-2.0 license.

A Python library for downloading electricity usage data from the Enova Power customer portal.

Enova Power serves residential and commercial customers in the Kitchener-Waterloo region of Ontario, Canada. Their My Account portal provides smart meter data exports, but only through a web UI. This library automates that process so you can pull your usage data into scripts, notebooks, dashboards, or data pipelines.

Quick start

Install

Using uv (recommended):

uv add enovapower

Using pip:

pip install enovapower

Environment variables

Credentials can be set via environment variables instead of passing them directly:

export ENOVA_USERNAME="user@example.com"
export ENOVA_PASSWORD="your_password"

Async client (primary)

The AsyncEnovaClient is the primary interface.

from datetime import date
from enovapower import AsyncEnovaClient

async with AsyncEnovaClient() as client:
    await client.login("user@example.com", "your_password")  # Do not pass credentials if they are set via environment variables
    readings = await client.download_usage(date(2026, 2, 25), date(2026, 3, 26))
    for r in readings:
        print(f"{r.date}: {r.total:.2f} kWh")

Sync client (convenience)

The EnovaClient is a thin synchronous wrapper for scripts and non-async contexts. It runs a dedicated background event loop.

from datetime import date
from enovapower import EnovaClient

client = EnovaClient()
client.login("user@example.com", "your_password")

readings = client.download_usage(date(2026, 2, 25), date(2026, 3, 26))
for r in readings:
    print(f"{r.date}: {r.total:.2f} kWh")

Features

  • Authenticate with the Enova Power My Account portal
  • Download hourly smart meter usage data as UsageReading dataclasses
  • Convert hourly readings to timezone-aware UTC (timestamp, kWh) intervals via UsageReading.intervals()
  • Distinguish missing hours (None) from real zero-consumption hours
  • Download Green Button XML exports and parse them with parse_green_button_xml() (safe defusedxml parsing)
  • Multi-meter accounts via meter_ids / select_meter()
  • Optional re-authentication callback to avoid retaining credentials
  • Download tariff rates for all pricing plans (Time-of-Use, Ultra-Low Overnight, Tiered)
  • Automatically chunk requests for date ranges exceeding 90 days
  • Store and incrementally update usage history in a local SQLite database
  • Automatic retry with exponential backoff on transient errors
  • Session expiry detection with automatic re-login
  • Configurable base_url for custom portal endpoints
  • Built-in logging with customizable logger support

Local storage

from enovapower import EnovaClient, UsageStore

client = EnovaClient()
client.login("user@example.com", "your_password")

with UsageStore("usage.db") as store:
    store.seed(client, months=12)   # initial backfill
    store.update(client)            # incremental update
    readings = store.load("111111", from_date, to_date)

Polling interval

The Enova portal is a utility web UI, not a high-throughput API. Avoid polling more frequently than every 15 minutes. A 30-minute interval is recommended for regular updates.

Logging

The library uses Python's standard logging module. The logger name is "enovapower".

Basic usage

import logging

logging.basicConfig(level=logging.DEBUG)
# Now all enovapower logs will appear

Custom logger

You can inject a custom logger to both clients and storage:

import logging

my_logger = logging.getLogger("my_app")
my_logger.setLevel(logging.INFO)

client = AsyncEnovaClient(logger=my_logger)
store = UsageStore("usage.db", logger=my_logger)

Built-in configuration

The library provides a convenience function to set up default handlers:

from enovapower.logger import configure_logging

# Configure with default format and DEBUG level
configure_logging(level=logging.DEBUG)

# Or with custom format
configure_logging(
    level=logging.INFO,
    format_string="%(asctime)s - %(levelname)s - %(message)s"
)

Security

Credentials passed to login() are stored in memory to enable automatic re-authentication on session expiry. They are never written to disk.

The library requires HTTPS by default. Use allow_insecure_http=True only for local testing against a development endpoint.

UsageStore databases are created with owner-only permissions (0600), since hourly usage data can reveal household occupancy patterns.

Documentation

See docs/usage.md for detailed API documentation and examples.

Development

See CONTRIBUTING.md for setup instructions and development workflow.

License

Apache-2.0. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

enovapower-0.6.1.tar.gz (48.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

enovapower-0.6.1-py3-none-any.whl (28.5 kB view details)

Uploaded Python 3

File details

Details for the file enovapower-0.6.1.tar.gz.

File metadata

  • Download URL: enovapower-0.6.1.tar.gz
  • Upload date:
  • Size: 48.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enovapower-0.6.1.tar.gz
Algorithm Hash digest
SHA256 c7abf31313e74ba133574bf9bc9f13310f7354e3140100c9ee074f94ef3a122b
MD5 5b798ef948057b6552b1b1b3b236ceb9
BLAKE2b-256 2294abde8b39650140698c8651fcf330a858d6826900dbb539cfba0256d1ac0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for enovapower-0.6.1.tar.gz:

Publisher: publish.yml on mojo17/enovapower

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file enovapower-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: enovapower-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 28.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for enovapower-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 08c790503f3a744ce7de11ebefd026ed8227d2d48a43b718d2a512cfd87a1d84
MD5 0eaa7146662733740be510f420809879
BLAKE2b-256 67368bcfe6f1aaf2fb5b3bdd1e156a32a1442469f58107135908494d2781d93c

See more details on using hashes here.

Provenance

The following attestation bundles were made for enovapower-0.6.1-py3-none-any.whl:

Publisher: publish.yml on mojo17/enovapower

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page