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.8.0.tar.gz (51.2 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.8.0-py3-none-any.whl (29.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for enovapower-0.8.0.tar.gz
Algorithm Hash digest
SHA256 60729457e1157290a53bc0f51a7da9828f5bfac02fdcc183deef6395c2b6081d
MD5 6e0fd7a69648e28af9e5c475c298ff1f
BLAKE2b-256 851e5ce861b8fcc978cc73a6786202427022be9d54d7ef7eb05b432678189034

See more details on using hashes here.

Provenance

The following attestation bundles were made for enovapower-0.8.0.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.8.0-py3-none-any.whl.

File metadata

  • Download URL: enovapower-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 29.8 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.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f2484bda3b80ec722dc45ab15ad737c9a47acd24f4c5afda30881515ba3021b9
MD5 d5df8efb1e4c2bbe2bc7ed640e1c40a8
BLAKE2b-256 5b7203ca4d501acf8084b4c41f97f0c028b41187cd191cbeb0f5bd803a5f037d

See more details on using hashes here.

Provenance

The following attestation bundles were made for enovapower-0.8.0-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