Metadata-Version: 2.3
Name: solaredge
Version: 3.0.0
Summary: Sync and async Python client for the SolarEdge Monitoring API (V2)
Keywords: solaredge,solar,monitoring,inverter,api,httpx
Author: evworth
Author-email: evworth <elliotworth@protonmail.com>
License: MIT
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Requires-Dist: httpx>=0.28.1
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/EVWorth/solaredge
Project-URL: Issues, https://github.com/EVWorth/solaredge/issues
Project-URL: Changelog, https://github.com/EVWorth/solaredge/blob/main/CHANGELOG.md
Project-URL: SolarEdge API docs, https://api-docs.solaredge.com/
Description-Content-Type: text/markdown

# SolarEdge Client (Monitoring API)

<p align="center">
  <a href="https://docs.astral.sh/uv/">
    <img src="https://img.shields.io/badge/packaging-UV-299bd7?style=flat-square&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDEiIGhlaWdodD0iNDEiIHZpZXdCb3g9IjAgMCA0MSA0MSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTS01LjI4NjE5ZS0wNiAwLjE2ODYyOUwwLjA4NDMwOTggMjAuMTY4NUwwLjE1MTc2MiAzNi4xNjgzQzAuMTYxMDc1IDM4LjM3NzQgMS45NTk0NyA0MC4xNjA3IDQuMTY4NTkgNDAuMTUxNEwyMC4xNjg0IDQwLjA4NEwzMC4xNjg0IDQwLjA0MThMMzEuMTg1MiA0MC4wMzc1QzMzLjM4NzcgNDAuMDI4MiAzNS4xNjgzIDM4LjIwMjYgMzUuMTY4MyAzNlYzNkwzNy4wMDAzIDM2TDM3LjAwMDMgMzkuOTk5Mkw0MC4xNjgzIDM5Ljk5OTZMMzkuOTk5NiAtOS45NDY1M2UtMDdMMjEuNTk5OCAwLjA3NzU2ODlMMjEuNjc3NCAxNi4wMTg1TDIxLjY3NzQgMjUuOTk5OEwyMC4wNzc0IDI1Ljk5OThMMTguMzk5OCAyNS45OTk4TDE4LjQ3NzQgMTYuMDMyTDE4LjM5OTggMC4wOTEwNTkzTC01LjI4NjE5ZS0wNiAwLjE2ODYyOVoiIGZpbGw9IiNERTVGRTkiLz4KPC9zdmc+Cg==" alt="UV">
  </a>
  <a href="https://docs.astral.sh/ruff/">
    <img src="https://img.shields.io/badge/code%20style-Ruff-8400ff?style=flat-square" alt="Ruff">
  </a>
  <a href="https://github.com/j178/prek">
    <img src="https://img.shields.io/badge/hooks-prek-f6d55c?style=flat-square" alt="prek">
  </a>
</p>
<p align="center">
  <a href="https://pypi.org/project/solaredge/">
    <img src="https://img.shields.io/pypi/v/solaredge?logo=python&logoColor=fff&style=flat-square" alt="PyPI Version">
  </a>
  <img src="https://img.shields.io/pypi/pyversions/solaredge?style=flat-square&logo=python&logoColor=fff" alt="Supported Python versions">
  <img src="https://img.shields.io/pypi/l/solaredge?style=flat-square" alt="License">
</p>



A Python client for the SolarEdge Monitoring API (V2), with synchronous and asynchronous interfaces and a method for every documented operation.

> **Upgrading from 2.x?** SolarEdge retired Monitoring API V1 on November 3,
> 2026, and every request from 2.x now fails with HTTP 410. 3.0 talks to V2,
> which needs a new API key and has different endpoints and response shapes.
> See [Migrating from 2.x](#migrating-from-2x).

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Credentials](#credentials)
- [Quick Start](#quick-start)
  - [Synchronous Usage](#synchronous-usage)
  - [Asynchronous Usage](#asynchronous-usage)
  - [Methods](#methods)
  - [Error Handling](#error-handling)
- [Rate Limits](#rate-limits)
- [Migrating from 2.x](#migrating-from-2x)
- [Development](#development)
- [API Documentation](#api-documentation)

## Features

- **Complete V2 coverage**: all 56 operations in SolarEdge's Basic Monitoring
  (2.1.0) and Advanced Monitoring (2.0.1) APIs, plus `get()` for anything added later
- **Sync & Async Support**: `MonitoringClient` and `AsyncMonitoringClient` share
  one definition of every method, so they cannot drift apart
- **Typed**: full annotations, `py.typed`, and `Literal` types for every enumerated parameter
- **Safe by default**: arguments are validated before anything is sent, and the
  API key never appears in URLs or error messages

## Installation

```bash
pip install solaredge
poetry add solaredge
uv add solaredge
```

## Credentials

V1 API keys do not work with V2. Create an account on the
[SolarEdge Developer Platform](https://developer.solaredge.com/) and generate
an **API key** there. This client sends it in the `X-API-Key` header, which
every V2 operation accepts.

V2 also supports **OAuth 2.0** (Site Access), which lets an app act on behalf
of a system owner. That isn't supported here yet. If you need it, please
comment on [#122](https://github.com/EVWorth/solaredge/issues/122).

## Quick Start

All time windows take **timezone-aware** `datetime`s, which are sent as UTC. V2
rejects timestamps without an offset, so a naive `datetime` raises
`SolarEdgeValidationError` before any request is sent. Where `start`/`end` are
optional, leaving them out means "midnight today until now" in the site's
time zone.

### Synchronous Usage

```python
from datetime import datetime, timedelta, timezone

from solaredge import MonitoringClient

SITE_ID = 1234567
now = datetime.now(timezone.utc)

with MonitoringClient("YOUR_API_KEY") as client:
    details = client.get_site_details(SITE_ID)
    today = client.get_overview(SITE_ID)
    daily = client.get_energy(
        SITE_ID,
        start=now - timedelta(days=30),
        end=now,
        resolution="DAY",
        unit="KWH",
    )
    batteries = client.get_storage_telemetry(SITE_ID)
```

### Asynchronous Usage

```python
import asyncio
from datetime import datetime, timedelta, timezone

from solaredge import AsyncMonitoringClient


async def main():
    now = datetime.now(timezone.utc)
    async with AsyncMonitoringClient("YOUR_API_KEY") as client:
        details, power = await asyncio.gather(
            client.get_site_details(1234567),
            client.get_power(1234567, start=now - timedelta(hours=2), end=now),
        )


asyncio.run(main())
```

### Methods

Every method returns the parsed JSON unchanged. Optional arguments left as
`None` are not sent, so the API's own defaults apply. The
[API reference](docs/SE_monitoring_API.md) lists the paths, parameters and
per-resolution window limits.

| Area | Methods |
| --- | --- |
| Sites | `get_sites`, `get_site_details`, `get_overview`, `get_performance`, `get_power`, `get_energy`, `get_environmental_benefits`, `get_lifetime_energy`, `get_external_production_energy` |
| Alerts | `get_alerts` (all sites), `get_site_alerts` |
| Inventory | `get_devices`, `get_device` |
| Telemetry | `get_inverters_telemetry`, `get_meters_telemetry`, `get_storage_telemetry` |
| Status | `get_inverters_status`, `get_storage_status` |
| Lifetime counters | `get_inverters_lifetime_energy`, `get_meters_lifetime_energy`, `get_storage_lifetime_energy` |
| Inverter | `get_inverter_power`, `_energy`, `_consumed_ac_power`, `_consumed_ac_energy`, `_voltage`, `_current`, `_frequency` |
| Meter | `get_meter_production_power` / `_energy`, `get_meter_consumption_*`, `get_meter_import_*`, `get_meter_export_*` |
| Battery | `get_battery_charge_power`, `_discharge_power`, `_charge_energy`, `_discharge_energy`, `_state_of_energy`, `_remaining_energy` |
| Advanced Monitoring* | `get_power_per_destination`, `get_energy_per_destination`, `get_current_power_flow`, `start_live_power_flow`, `get_weather_guard`, `get_backup_reserve` |
| Anything else | `get(path, params=None)` |

\* Business Pro and Enterprise plans only. Other plans get HTTP 403, raised as
`SolarEdgeAuthError`.

Telemetry, status and lifetime methods cover every device of that kind on the
site. Pass `serial_numbers=[...]` to limit them to specific devices. V2 reports
units in upper case (`"WH"`, `"KWH"`, `"W"`), so compare them
case-insensitively.

### Error Handling

Every failure raises a `SolarEdgeError` subclass, so you never need to import
`httpx` to handle one. The originating `httpx` exception is preserved as
`__cause__` if you want the transport-level detail.

```python
from solaredge import (
    MonitoringClient,
    SolarEdgeAuthError,
    SolarEdgeRateLimitError,
    SolarEdgeError,
)

with MonitoringClient("YOUR_API_KEY") as client:
    try:
        flow = client.get_current_power_flow(1234567)
    except SolarEdgeAuthError:
        ...  # bad key, or an operation your plan does not include
    except SolarEdgeRateLimitError as exc:
        ...  # exc.retry_after, exc.limits
    except SolarEdgeError:
        ...  # anything else this library raises
```

The hierarchy:

| Exception | Raised when |
| --- | --- |
| `SolarEdgeError` | Base class for everything below |
| `SolarEdgeValidationError` | Arguments rejected locally, before any request. Also a `ValueError` |
| `SolarEdgeAPIError` | The API returned an error status, e.g. 400 for a window that is too long |
| `SolarEdgeAuthError` | 401 / 403: key missing or invalid, or the operation is not in your plan |
| `SolarEdgeNotFoundError` | 404: no such site, device or operation |
| `SolarEdgeRateLimitError` | 429: per-minute or monthly quota exceeded. Carries `retry_after` and `limits` (the `x-ratelimit-*` headers) |
| `SolarEdgeServerError` | 5xx: the API failed to handle a valid request |
| `SolarEdgeResponseError` | Success status, but the body could not be parsed |

`SolarEdgeAPIError` and its subclasses carry `status_code`, `response_body` and
`url`.

## Rate Limits

Every call costs one credit. Plans set a monthly credit quota and a
calls-per-minute limit; the Free tier allows 2,000 credits a month and 10 calls
a minute.

This client caps itself at 3 concurrent requests but does not retry or throttle
for you. A client that polled several endpoints every 15 minutes under V1 will
run through the Free tier's monthly quota. To stay within it:

- Prefer the bulk telemetry methods over per-device ones.
- Use coarser resolutions where you can.
- Poll less often.

## Migrating from 2.x

| 2.x method | 3.0 replacement |
| --- | --- |
| `get_site_list(...)` | `get_sites(page=..., sites_in_page=..., name=...)` |
| `get_site_details(site_id)` | `get_site_details(site_id)` |
| `get_overview(site_ids)` | `get_overview(site_id)`, one site per call |
| `get_energy(site_ids, start_date, end_date, time_unit)` | `get_energy(site_id, start, end, resolution, unit)` |
| `get_time_frame_energy(...)` | `get_energy(..., resolution="TOTAL")` |
| `get_power(site_id, start_time, end_time)` | `get_power(site_id, start, end, resolution, unit)` |
| `get_power_details(...)`, `get_energy_details(...)` | `get_meters_telemetry(...)`, or `get_power_per_destination` / `get_energy_per_destination` (Advanced) |
| `get_current_power_flow(site_id)` | `get_current_power_flow(site_id)` (Advanced) |
| `get_storage_data(...)` | `get_storage_telemetry(...)`, `get_storage_status(...)` |
| `get_environmental_benefits(site_id, system_units)` | `get_environmental_benefits(site_id, unit="METRIC" or "IMPERIAL")` |
| `get_inventory(site_id)`, `get_components_list(site_id)` | `get_devices(site_id, types=[...])` |
| `get_inverter_technical_data(site_id, serial, ...)` | `get_inverters_telemetry(...)` and `get_inverters_status(...)` with `serial_numbers=[serial]` |
| `get_meters(...)` | `get_meters_lifetime_energy(...)`, `get_meters_telemetry(...)` |
| `get_site_data(site_ids)` | No V2 equivalent |

Other changes:

- **Credentials:** pass a V2 API key; V1 keys are rejected.
- **One site per call:** V2 has no comma-separated bulk form for sites.
- **Datetimes must be timezone-aware**, and are sent as UTC `from`/`to`.
- **Parameters renamed:** `time_unit` is now `resolution`, and
  `QUARTER_OF_AN_HOUR` is now `QUARTER_HOUR`. Enum values are upper case,
  e.g. `METRIC`, `PRODUCTION`.
- **Response bodies differ**, so code that reads fields needs updating.
- **Data no longer available:** optimizer-level telemetry (optimizers appear
  only in `get_devices`), and per-phase inverter values (V2 averages across
  phases).

## Development

```bash
# Install development dependencies
uv sync
uv run prek install -t commit-msg
```

```bash
# Commiting changes
uv run cz c
```

## API Documentation

- [V2 API reference for this library](docs/SE_monitoring_API.md)
- [SolarEdge Developer Platform documentation](https://api-docs.solaredge.com/)
- [SolarEdge: Migrating from V1 to V2](https://api-docs.solaredge.com/docs/developer-platform/mxj41549n0nxk-migrating-from-v1-to-v2)
