You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ Your solar system is organised in a simple hierarchy. Device and entity names in
54
54
55
55
-**Voltage**, **Current**, **Optimizer voltage**, **Power** – Live values when the optimizer is reporting.
56
56
-**Temperature** – Optimizer temperature from the SolarEdge One API (layout/energy by-inverter with `include-max-temperature`). The portal may report in °C or °F (`temperatureUnit`); the integration normalizes to °C for storage and Home Assistant displays in your preferred unit. Only available when using the One API; shown as “unknown” when missing or when using the legacy API. When the integration is not doing a full refresh (e.g. reusing data after a light check), it still refreshes temperatures when the temperature cache expires (30 minutes, TEMPERATURE_CACHE_TTL), so temperature stays up to date even when power/voltage are not updating.
57
-
-**Lifetime energy** – Total energy produced (kWh); this only goes up over time. The integration uses the API’s raw energy value (unscaledEnergy, in Wh) so it updates correctly regardless of how the portal displays units (Wh/kWh/MWh). When optimizer-level lifetime data is reliable, site lifetime is the sum of optimizers; when it is not (e.g. mixed or missing data), the site uses the portal’s total directly.
57
+
-**Lifetime energy** – Total energy produced (kWh); this only goes up over time. The integration uses the API’s raw energy value (unscaledEnergy, in Wh) so it updates correctly regardless of how the portal displays units (Wh/kWh/MWh). Site lifetime is the sum of inverters when aggregated data is reliable, or the portal total when unreliable (e.g. below `RELIABLE_THRESHOLD_KWH`). String totals are derived by summing that string's optimizer entries, not from API string-level keys that can be site totals.
58
58
-**Last measurement** – When the portal last had a reading for this optimizer.
59
59
-**Status** – The optimizer's status from the API. Blank (empty) status is treated as active and displayed as **blank** with the active icon. Values are shown in proper case: "Active", "Inactive", or the raw value for any other status. The icon changes based on status: check-circle for Active or blank, alert-circle for Inactive, help-circle for unknown (any other) status.
60
60
-**Azimuth** – The panel's compass direction in degrees (0–360°), converted from radians. Only available when the API provides module orientation data. Icon: compass.
@@ -80,7 +80,7 @@ Names are kept short (e.g. “Current (average)”, “Power”) because the dev
80
80
- The **coordinator** runs every **5 minutes** (`UPDATE_DELAY`). It does a lightweight check (one or a few optimizers) to see if the portal has new readings. When data is **fresh**, the desired interval between light checks is about **5 minutes**; when data is **stale or missing**, about **30 minutes**. When the light check detects new data, a full refresh runs so all sensors update; a full refresh is not triggered again within **5 minutes** of the last one (`LIGHT_CHECK_MIN_INTERVAL`). When using **SolarEdge One**, up to `LIGHT_CHECK_BATCH_SIZE` (5) optimizers are chosen at random for each check so different orientations and shade don't block updates; when falling back to the legacy API, a single representative optimizer is used for the light check. When data is currently from the **legacy** API, the integration also forces a full refresh **every 30 minutes** so it re-tries the SolarEdge One API and can switch back to One when it becomes available again.
81
81
-**Lifetime energy** is only refreshed from the portal about **once per hour** (`LIFETIME_ENERGY_CACHE_TTL`), because that value changes slowly. It is derived from the API’s unscaled energy (Wh), not the display units, so values update correctly. Totals for strings, inverters, and the site are calculated from that data.
82
82
83
-
-**Layout (panels)** is cached for **2 hours** when using SolarEdge One (`PANELS_CACHE_TTL_ONE`) and **1 hour** when using the legacy API (`PANELS_CACHE_TTL_LEGACY`).
83
+
-**Layout (panels)** is cached for **2 hours** when using SolarEdge One (`PANELS_CACHE_TTL_ONE`) or the legacy API (`PANELS_CACHE_TTL_LEGACY`).
84
84
85
85
-**Temperature** (SolarEdge One only): When the integration does not perform a full refresh (e.g. it reuses existing data after a light check), it still refreshes optimizer temperatures when the temperature cache expires (**30 minutes**, `TEMPERATURE_CACHE_TTL`). So temperature sensors stay updated even when power, voltage, and current are not being refreshed.
86
86
@@ -176,6 +176,8 @@ logger:
176
176
177
177
Restart Home Assistant for the change to take effect. Debug logging covers the full lifecycle: config flow (user form, validation, unique_id check, entry creation, reauth form, options/reconfigure form when showing or saving — including entity_id_prefix, include_site_id_in_entity_id, use_solaredge_one — removal), setup and unload (dual API with use_solaredge_one, coordinator, platform forward, API session close, registry cleanup), coordinator updates (inverter models fetch, device creation with model and suffix, adaptive polling with configurable batch size (`LIGHT_CHECK_BATCH_SIZE`), full refresh vs reuse, obtained_from source, revert-to-One retry every 30 min when data from legacy, representative optimizers or random batch, lifetime energy entries, inactive device skipping with status, duplicate position resolution with suffix assignment, string/inverter/site aggregated data creation with status and child counts, refresh strategy determination, update complete), sensor setup (base_name, include_site_id, per-optimizer serial/model/panel_type/status, duplicate optimizer position resolution with suffixes, inactive device sensor skipping, aggregated sensors with status, obtained_from sensor, entity count, device status summary when inactive devices exist, status value updates), and API requests (SolarEdge One: OAuth, token, GET/POST to /services/ with configurable timeouts (`API_TIMEOUT_SHORT`/`API_TIMEOUT_LONG`), requestAllData (single batch for all optimizers; per-optimizer fallback when batch fails), optimizer/inverter information including panel type (description), cache hit/miss, optimizer temperatures with unit and F→°C conversion when portal sends Fahrenheit; legacy: login, layout, system data, lifetime energy; dual API: use_solaredge_one/legacy-only, fallback to legacy when One has no valid measurements or fails). All debug output is guarded with `isEnabledFor(logging.DEBUG)`, so there is no performance cost when the log level is `info`. Debug messages use consistent prefixes (e.g. `SolarEdge Optimizers`, `SolarEdge Optimizers coordinator`, `SolarEdge Optimizers sensor`, `SolarEdge One`, `SolarEdge Optimizers (legacy)`, `SolarEdge Dual API`) so you can filter logs easily. Turn logging back to `info` when you are done.
178
178
179
+
**Code quality:** The project uses Pylint and pycodestyle (e.g. via CodeFactor). See `pyproject.toml` for tool config and `CODEQUALITY.md` for intentional patterns and suppressions.
180
+
179
181
## Translations
180
182
181
183
The integration is localized for multiple languages: config flow (labels, errors, entry title), sensor and device names, and API locale follow the user’s Home Assistant language where supported. See [Internationalization (i18n)](https://github.com/AndrewTapp/solaredgeoptimizers/blob/main/docs/internationalization.md) for details.
Copy file name to clipboardExpand all lines: custom_components/solaredgeoptimizers/docs/SolarEdge-One-API-Summary.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ A site-level sensor **Obtained from** shows whether current data came from **"On
36
36
-**Auth**: Single OAuth flow and Bearer token instead of mixing Basic Auth and session cookies.
37
37
-**Data**: Structured JSON (e.g. `power_W`, `voltage_V`, `optimizerVoltage_V`) instead of locale-dependent labels; layout in a single v2 structure.
38
38
-**Devices**: Optimizer and inverter **model** (and serial) come from the API, so HA devices can show real model names (e.g. P405-4RM4MRM-NA25, SE5000H-RW000BNN4). When the API provides a **panel type** (description, e.g. SunPower SPR-MAX3-400), it is included in the optimizer device model and exposed as a **panel_type** attribute on optimizer sensors.
39
-
-**Polling**: Lightweight “any new data?” check can use a batch request (up to `LIGHT_CHECK_BATCH_SIZE` = 5 optimizers) instead of one panel; 1-hour stale threshold for live values (legacy used 2 hours). **Full refresh** fetches all optimizer live data in **one batch POST** (`requestSystemDataBatch` with all serials), reducing portal load; if that batch fails (e.g. 5xx), the integration falls back to per-optimizer requests.
39
+
-**Polling**: Lightweight “any new data?” check can use a batch request (up to `LIGHT_CHECK_BATCH_SIZE` = 5 optimizers) instead of one panel; 1-hour stale threshold for live values (legacy uses 2 hours). Site layout (panels) is cached for **2 hours** (`PANELS_CACHE_TTL_ONE`) when using SolarEdge One. **Full refresh** fetches all optimizer live data in **one batch POST** (`requestSystemDataBatch` with all serials), reducing portal load; if that batch fails (e.g. 5xx), the integration falls back to per-optimizer requests.
0 commit comments