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.11.0.tar.gz (60.6 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.11.0-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for enovapower-0.11.0.tar.gz
Algorithm Hash digest
SHA256 e68827ce47d9059fa3c14dc1f48b269097ebde948a089f237ff639c2e7dac5b2
MD5 460be6cabec7853b32ec2759c15ecb7f
BLAKE2b-256 564aedec1c981f8a01ca4621da23ec01c4461a82592ca5a5a6ff65a3e56bba84

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: enovapower-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 34.1 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.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a612c1778edab0c69819f08cc722cbafc1cfd76028d9c57ae9f36f398003671
MD5 0bef5b9ec6a0c5f581b236a87a1f87cd
BLAKE2b-256 b3fc329ede6f2b10f3791a30ba3dbab6cdf2bfe89aaf856e902326b519bfb01d

See more details on using hashes here.

Provenance

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