v2.4.14
v2.4.14 Summary of Changes (SolarEdge Optimizers Integration)
This document summarizes the main changes made to the integration, including new features, lifetime energy logic, reliability improvements, code quality, and documentation updates.
1. New site-level sensors (SolarEdge One only)
-
Installation date
- Entity:
sensor.[prefix]installation_date_[site](orsensor.[prefix]installation_datewhen site ID is not in entity IDs). - Source: Portal
layout/information/site/{siteId}→installationDate. - Cached for 2 hours (
SITE_INFO_CACHE_TTL), same as layout.
- Entity:
-
Peak power
- Entity:
sensor.[prefix]peak_power_[site](orsensor.[prefix]peak_powerwhen site ID is not in entity IDs). - Source: Portal
layout/information/site/{siteId}→peakPower(kW). - Same cache as above.
- Entity:
Both values are fetched via get_site_info_cached() in the SolarEdge One API and stored on the site aggregated data; the sensor platform exposes them only when using the One API.
2. Lifetime energy: portal overrides and removal of threshold
Previous behaviour
- Site lifetime could use a “portal total” when aggregated data was considered unreliable (below
RELIABLE_THRESHOLD_KWH).
Current behaviour
-
Site lifetime
- Uses the portal’s dashboard production (Wh) from
dashboard/energy/sites/{siteId}?start-date={installation_date}&end-date=...
when that value is greater than the aggregated site total. - Start date for the request is the site installation date from site info.
- Uses the portal’s dashboard production (Wh) from
-
Inverter and string lifetime
- Use the portal’s layout/energy by-inverter data (Wh) from
layout/energy/site/{siteId}/by-inverter?start-date={installation_date}&...
when the portal value is greater than the aggregated inverter or string total.
- Use the portal’s layout/energy by-inverter data (Wh) from
-
Removed
- The constant
RELIABLE_THRESHOLD_KWHand all logic based on it. - Override rule is now simply: if portal value > aggregated value, use portal value (with start date = installation date).
- The constant
Implementation details
-
const.py
- Added
SITE_INFO_CACHE_TTL(2 h). - Added
SENSOR_TYPE_INSTALLATION_DATE,SENSOR_TYPE_PEAK_POWERand included them inSENSOR_TYPE_AGGREGATED_SITE. - Removed
RELIABLE_THRESHOLD_KWH.
- Added
-
solaredge_one_api.py
get_site_info_cached(): layout/information/site →installationDate,peakPower(kW).get_dashboard_site_production_cached(installation_date): dashboard/energy/sites →summary.production(Wh).get_layout_energy_by_inverter_cached(installation_date): layout/energy by-inverter → per-inverter and per-string energy (Wh).- Caches keyed/used by installation date and date range where relevant.
-
api_dual.py
- Wraps the above three methods; when not using SolarEdge One, they return empty/None.
-
coordinator.py
- Fetches site info and installation date; uses it for dashboard production and by-inverter calls.
- Passes
site_infoandportal_by_inverterinto aggregation. - Applies portal overrides for site, inverter, and string lifetime when portal value > aggregated (values from portal are in Wh; converted to kWh for entity state).
-
sensor.py
- New site-level sensor types for Installation date and Peak power (attributes, units, device classes, translation keys).
3. Reliability and resource handling
-
Unload / file descriptors
- On integration unload, the coordinator is always retrieved, its API client is closed (
my_api.close()), and the coordinator is removed fromhass.data, even ifasync_unload_platforms()fails. - Ensures sessions and connections are released and avoids file descriptor leaks (especially for the legacy API’s
requests.Sessionpool).
- On integration unload, the coordinator is always retrieved, its API client is closed (
-
SolarEdge One API
close()- Made explicitly idempotent: if already closed, returns immediately.
-
Dual API
close()- Closes both One and legacy clients; tracks and logs if any client fails to close while still attempting to close the other.
4. Debug logging
- Coordinator: site info fetch result (installation_date, peak_power), dashboard production usage (Wh→kWh), by-inverter fetch and inverter count, and when portal overrides are applied for site, inverter, and string. When creating inverter aggregated data, debug log includes
max_active_power(kW). - SolarEdge One API: cache miss logs for site info, dashboard production, and by-inverter energy; building inverter node logs
maxActivePower(kW) when present. - All debug output remains guarded with
isEnabledFor(logging.DEBUG)so there is no extra cost at info level.
5. Code quality (CodeFactor / Pylint / pycodestyle)
-
Project root
.pylintrc: design limits relaxed (e.g.max-args=10,max-module-lines=2000) so coordinator/sensor and HA callback signatures are not flagged.setup.cfg:[pycodestyle]max-line-length = 159to align with Pylint.
-
Inline disables
# pylint: disable=too-many-argumentsadded where the design requires more than five parameters (e.g._calculate_aggregated_data,_register_inverter_and_string_devices,_process_single_string, sensor builder functions,api_dual.__init__, config_flowasync_show_form).
6. Translations and i18n
- All translation files (e.g.
translations/*.json) include keys for the new site sensors:
entity.sensor.installation_date.name,entity.sensor.peak_power.name. - Documentation (including internationalization.md) updated to list Installation date and Peak power in the entity sensor names and translation structure.
7. Documentation updates
-
README.md
- New site-level Installation date and Peak power; lifetime energy described as portal override (dashboard production / by-inverter; start date = installation date); code quality section updated to reference
.pylintrcandsetup.cfg.
- New site-level Installation date and Peak power; lifetime energy described as portal override (dashboard production / by-inverter; start date = installation date); code quality section updated to reference
-
info.md
- Same site sensors and lifetime behaviour; RELIABLE_THRESHOLD removed.
-
docs/Wiki-Home.md
- Overview, device hierarchy, sensor reference, and API section updated for Installation date and Peak power; caching table includes site info (2 h) and layout (2 h for both One and legacy); lifetime energy and portal overrides described; RELIABLE_THRESHOLD removed and replaced with
SITE_INFO_CACHE_TTLin constants; file structure no longer references CODEQUALITY.md/pyproject.toml in the integration folder.
- Overview, device hierarchy, sensor reference, and API section updated for Installation date and Peak power; caching table includes site info (2 h) and layout (2 h for both One and legacy); lifetime energy and portal overrides described; RELIABLE_THRESHOLD removed and replaced with
-
docs/SolarEdge-One-API-Summary.md
- Site info, dashboard production, and by-inverter energy; site-level Installation date and Peak power sensors; portal lifetime overrides and installation date as start date.
-
docs/internationalization.md
- Installation date and Peak power added to the list of sensor entity names and translation keys.
8. New inverter-level sensor: Max active power (SolarEdge One only)
-
Max active power
- Entity:
sensor.[prefix]max_active_power_[site]_[inverter](orsensor.[prefix]max_active_power_[inverter]when site ID is not in entity IDs). - Source: Portal layout logical v2
.../layout/logical/generic/v2/site/{siteId}?include-optimizers=true→ per-inverterproperties.maxActivePower(watts). Displayed as kW (same as site Peak power). - Cached with the layout (2 h); no separate API call.
- One API only; legacy layout does not provide this field (sensor still created, value unknown until available).
- Entity:
-
Implementation
- const.py:
SENSOR_TYPE_MAX_ACTIVE_POWER, added toSENSOR_TYPE_AGGREGATED_INVERTER. - solaredge_one_api.py:
_v2_build_inverter_logical_nodereadsmaxActivePower(W) from inverter properties, converts to kW, adds to inverterdatadict. - solaredgeoptimizers.py:
SolarEdgeInverterhasmaxActivePower(fromdata.get("maxActivePower"));SolarEdgeAggregatedDatahasmax_active_power. - coordinator.py:
_create_inverter_aggregatedsetsinverter_aggregated.max_active_power = getattr(inverter, "maxActivePower", None); debug log includesmax_active_powerwhen creating inverter aggregated. - sensor.py: New sensor type in aggregated maps (attr, translation key, units kW); value handling same as Peak power (round to 2 decimals).
- Translations: All locale files updated with
entity.sensor.max_active_power.name(e.g. "Max active power", "Max. Wirkleistung").
- const.py:
-
Inactive inverters: Max active power sensor is still created for inactive inverters (fixed inverter property); value may be unknown if layout does not provide it.
9. File descriptor and documentation refresh
-
File descriptor handling
- api.py: Protocol
close()docstring now states "Release resources, close sessions, and release file descriptors". - solaredgeoptimizers.py: Module docstring notes that
close()closes all tracked sessions to avoid leaking file descriptors on unload/removal. - solaredge_one_api.py: Module docstring notes no persistent sessions (context managers), and
close()clears tokens. - init.py: Docstring states that on unload or removal the API client is closed to release file descriptors.
- config_flow.py: Cleanup section now says "Closes API (releases file descriptors), then removes entities and devices".
- api.py: Protocol
-
Top-of-file / module comments
- solaredgeoptimizers.py: Data classes (SolarEdgeInverter maxActivePower, SolarEdgeAggregatedData max_active_power), Key Features (close/file descriptors).
- sensor.py: Aggregated sensors list includes "Inverter-level: Max active power (kW, from portal layout logical v2; One API only)".
- coordinator.py: Data aggregation includes "Inverter aggregated data includes max_active_power (kW) from layout logical v2 when available (One API)".
- solaredge_one_api.py: Key Features include inverter maxActivePower (W→kW) and no persistent sessions/close() clears tokens.
-
Documentation
- README.md, info.md, docs/Wiki-Home.md, docs/SolarEdge-One-API-Summary.md, docs/internationalization.md: All updated for Max active power (inverter, entity ID, cache, One API only), and where relevant for file descriptor release on unload/removal and dual API
close().
- README.md, info.md, docs/Wiki-Home.md, docs/SolarEdge-One-API-Summary.md, docs/internationalization.md: All updated for Max active power (inverter, entity ID, cache, One API only), and where relevant for file descriptor release on unload/removal and dual API
10. Files touched (overview)
| Area | Files |
|---|---|
| Constants & types | const.py (SENSOR_TYPE_*, SITE_INFO_CACHE_TTL, SENSOR_TYPE_MAX_ACTIVE_POWER), solaredgeoptimizers.py (SolarEdgeAggregatedData, SolarEdgeInverter.maxActivePower) |
| One API | solaredge_one_api.py (get_site_info_cached, layout inverter maxActivePower→kW, close/docstring) |
| Dual API | api_dual.py |
| Protocol | api.py (close docstring) |
| Coordinator | coordinator.py (site info, portal overrides, inverter max_active_power, debug log, docstring) |
| Sensors | sensor.py (Installation date, Peak power, Max active power; docstrings) |
| Setup / unload | __init__.py (docstring, unload close) |
| Config flow | config_flow.py (docstring, async_remove_entry close) |
| Config | .pylintrc, setup.cfg (project root) |
| Translations | translations/*.json (installation_date, peak_power, max_active_power) |
| Docs | README.md, info.md, docs/Wiki-Home.md, docs/SolarEdge-One-API-Summary.md, docs/internationalization.md |
This summary reflects the state of the integration after the above changes, including the post–v2.4.14 additions (inverter Max active power sensor and file-descriptor/documentation refresh). For version-specific release notes, see the repository releases.
What's Changed
- v2.4.14 by @AndrewTapp in #36
Full Changelog: 2.4.13...2.4.14