Skip to content

Latest commit

 

History

History
29 lines (15 loc) · 12.8 KB

File metadata and controls

29 lines (15 loc) · 12.8 KB

SolarEdge Optimizers Integration

Brings your SolarEdge optimizer data from the SolarEdge monitoring portal into Home Assistant. You see current production, voltage, power, temperature (SolarEdge One only), lifetime energy, status (blank = active, displayed as "blank"; dynamic icons: check-circle for Active/blank, alert-circle for Inactive, help-circle for unknown), azimuth (with compass icon), and tilt (with angle-acute icon) for each optimizer (plus optimizer voltage and last measurement), combined totals for each string, inverter, and the whole site, at site level Installation date and Peak power (SolarEdge One only; from portal layout/information/site), and at inverter level Max active power in kW (SolarEdge One only; from portal layout logical v2).

You need: Site ID, username, and password (from the SolarEdge portal). Optionally: an Entity ID prefix (e.g. se_); Include Site ID in Entity ID (default off); Use SolarEdge One (default on). When upgrading from an older version without re-adding the integration, these options default to blank, off, and on respectively if not present. Dual API: when Use SolarEdge One is Yes (default), the integration tries the SolarEdge One API first; if One has no valid measurements or login fails, it automatically falls back to the legacy SolarEdge API. When data is from legacy, it re-tries One every 30 minutes so it can switch back when One is available. When Use SolarEdge One is No, the integration always uses the legacy portal only. A site-level Obtained from sensor shows whether current data came from "One API" or "Legacy API". When data is from One, optimizer and inverter devices show model (e.g. P405-4RM4MRM-NA25, SE5000H-RW000BNN4) and serial; when the API provides a panel type (description), it is included in the optimizer device model and exposed as a panel_type attribute on optimizer sensors. One config entry per site: each Site ID can only be added once; adding the same site again is aborted. Re-authentication: if credentials become invalid (e.g. after a password change or expiry), the integration triggers a re-auth flow; you enter your current username and password in a translated form, then the integration reloads with the new credentials. Only credentials are updated; options are preserved. Reconfigure: you can change Entity ID prefix, Include Site ID in Entity ID, or Use SolarEdge One from the integration’s Configure (options flow) without removing the entry. The dialog shows Entity ID prefix (description shows current prefix; leave empty to remove it), Include Site ID in Entity ID, and Use SolarEdge One. Saving reloads the integration. Changing prefix or Include Site ID can change entity IDs and unique_ids, so history and statistics for existing entities may be lost; the options form warns users and recommends backing up or exporting first.

In Home Assistant your system appears as a hierarchy: Site [site]Inverter [site].[i]String [site].[i].[s]Optimizer [site].[i].[s].[o] (e.g. Site 9999999, Inverter 9999999.1, String 9999999.1.1, Optimizer 9999999.1.1.1). At string and optimizer level, device names and entity IDs are based on the API display name when it parses (e.g. "1.0", "1.0.1"); if the display name does not parse, position-based indices are used. Site and inverter stay position-based. Deduplication by path ensures unique entities when multiple optimizers share the same display name. Entity IDs are path-based (e.g. sensor.xyz_power_9999999_1_1 or, with “Include Site ID” off, sensor.xyz_power_1_1 for a string; site level always includes the site ID). The integration ensures site, inverter, and string devices are registered before adding optimizer entities, avoiding "references a non existing via_device". Optimizers are grouped under their string device; each device shows what it's connected via in Settings → Devices & services. The config entry title shows the site (e.g. "SolarEdge Site 9999999"), using the translated title with the site ID substituted. Hardware replacement: Devices and sensors are identified by logical position; at string/optimizer level names and entity IDs follow the API display name when it parses. Data is keyed by position so replacement hardware at the same position updates the same entity. When you replace an optimizer or inverter, the same sensor continues to show the new unit’s data after the next refresh; no duplicate entities. String and inverter sensors use the same position-based devices as the coordinator, so the hierarchy stays correct. If you already have duplicates or “two inverters” (one with sensors, one with strings), remove the integration and add it again to clean up.

Updates: The integration checks for new data every few minutes and refreshes when the portal has new readings. The coordinator runs every 5 minutes. A lightweight check uses one optimizer (when using legacy API) or up to LIGHT_CHECK_BATCH_SIZE (5) chosen at random (when using SolarEdge One); when data is fresh the desired light-check interval is about 5 minutes, when stale or missing about 30 minutes. A full refresh is not triggered again within 5 minutes of the last one (LIGHT_CHECK_MIN_INTERVAL). The integration tries SolarEdge One first and falls back to legacy when One has no valid measurements or fails. When any has newer data, a full refresh runs. When data is from legacy, a full refresh is forced every 30 minutes to re-try One so the integration can switch back when One is available. Lifetime energy is updated from the portal about once per hour (unscaledEnergy, Wh). When the integration does not do a full refresh (e.g. reuses data after a light check), it still refreshes optimizer temperatures when the temperature cache expires (30 min, SolarEdge One only), so temperature sensors stay updated even when power/voltage are not. The portal may report temperature in °C or °F (temperatureUnit); the integration normalizes to °C and Home Assistant displays in the user’s preferred unit. String totals are derived by summing that string's optimizer entries (not from API string-level keys that can be site totals). Site lifetime uses the portal's dashboard production (Wh) when > aggregated; inverter and string use the portal's layout/energy by-inverter (Wh) when > aggregated; start date for portal calls is the site installation date from layout/information/site. On first load, the coordinator fetches all optimizer data once; the sensor platform reuses that data when creating entities (only calling the API for optimizers missing from the coordinator), so setup avoids duplicate fetches and is faster.

Inactive devices: When an optimizer, string, or inverter is marked as Inactive in the SolarEdge portal, certain sensors are not created because they are not meaningful for inactive/disconnected devices. Inactive optimizers do not get Azimuth, Current, Optimizer voltage, Power, Temperature, Tilt, or Voltage sensors (only Lifetime energy, Last measurement, and Status). Inactive strings/inverters do not get Current (average), Power, or Voltage (average) sensors (only Lifetime energy, Last measurement, Child count, and Status). Aggregation (power, current, voltage, lifetime energy) includes data from all devices (any status) with recent measurements. Child counts (Optimizer count, String count, Inverter count) count only active devices (status blank or "Active").

When an optimizer is offline: Live values (voltage, current, optimizer voltage, power) show 0 if the last measurement is older than the stale threshold (1 hour when data is from One API, 2 hours when from Legacy API). The Obtained from sensor on the site device shows "One API" or "Legacy API". Temperature (when from SolarEdge One) is not zeroed; it shows the last known value or unknown if missing. Lifetime energy, last measurement, status, azimuth, and tilt always show the last known values. For inactive optimizers the API often omits last measurement; the integration preserves the previous value across refreshes so Last measurement shows when the optimizer was actually last updated (not the current time).

Duplicate name handling: When the API returns multiple inverters, strings, or optimizers with the same name (e.g. after hardware replacement), the integration resolves duplicates automatically: active (including blank status) items come first (sorted by serial number for inverters/optimizers, by position for strings), then other statuses. The first active item keeps the original name; subsequent duplicates get alphabetical suffixes (e.g. "Inverter 1a", "String 1.0a", "Optimizer 1.0.1a").

Reliability: Temporary SolarEdge or network issues (e.g. HTTP 5xx, DNS) are handled with cached data where possible. If the inverter information API returns 403 Forbidden, the integration still works (devices use position-based identity; model names may be missing). When the lifetime-energy cache is cold, it is fetched in parallel (thread pool, up to MAX_PARALLEL_WORKERS = 10 concurrent requests) so large sites complete faster; full refresh allows up to 30 minutes before timing out (COORDINATOR_REFRESH_TIMEOUT_SEC). API requests use configurable timeouts (API_TIMEOUT_SHORT = 30s, API_TIMEOUT_LONG = 60s). API sessions and connections are closed properly when the integration is removed or reloaded (no file descriptor leaks). When you delete the integration from Settings → Devices & services → Integrations (not only from HACS), a shared cleanup routine removes all associated entities and devices from the registries so no leftovers remain.

Child counts: Optimizer count (per string), String count (per inverter), and Inverter count (per site) count only active devices (status blank or "Active") and are always reported as integers.

Debug logging: To troubleshoot setup or updates, set the logger for solaredgeoptimizers to debug in your configuration.yaml (see README). Debug logging covers the full lifecycle: config flow (user form, validation, entry creation, reauth, options/reconfigure including use_solaredge_one), setup and unload (dual API use_solaredge_one, unload pop coordinator and close API even when platform unload fails), coordinator (inverter models, device creation with suffix, adaptive polling with configurable batch size, full refresh, refresh strategy determination, revert-to-One retry when data from legacy, lifetime energy, site info and dashboard/by-inverter portal data, portal lifetime overrides for site/inverter/string when portal > aggregated, inactive device skipping with status, duplicate position resolution, aggregated data creation with status and child counts including inverter max_active_power), sensor setup (entities, options, per-optimizer serial/model/panel_type/status, duplicate position resolution with suffixes, inactive device sensor skipping, aggregated sensors with status, device status summary when inactive devices exist, status value updates), and API (SolarEdge One and legacy: login, layout, system data with configurable timeouts, inverter/optimizer information including panel type (description), site info and dashboard/by-inverter caches, optimizer temperatures with unit and F→°C conversion when portal sends Fahrenheit; dual API: use_solaredge_one/legacy-only, fallback, close both clients; config flow: API close on entry removal). All debug calls are guarded so output is only generated when the log level is debug; messages use consistent prefixes (SolarEdge Optimizers, SolarEdge Optimizers coordinator, SolarEdge Optimizers sensor, SolarEdge One, SolarEdge Optimizers (legacy), SolarEdge Dual API) for log filtering.

Installation

Install via HACS as a custom repository: add https://github.com/AndrewTapp/solaredgeoptimizers (Integration), then install SolarEdge Optimizers (or SolarEdge Optimizers Data in HACS), restart Home Assistant, and add the integration with your Site ID, username, password, optional Entity ID prefix, optional Include Site ID in Entity ID (default off), and Use SolarEdge One (default on). When Use SolarEdge One is on, the integration uses a dual API (SolarEdge One first, legacy fallback); when off, it uses the legacy portal only. The Obtained from sensor on the site device shows "One API" or "Legacy API". The coordinator fetches all optimizer data on first load; the sensor platform reuses that data when available, so setup is faster than with per-optimizer duplicate calls. With many optimizers, initial fetch and device creation may still take a short while.

Translations

The integration is localized for multiple languages (config flow, options/reconfigure dialog, sensor and device names, API locale). Translation files use the same structure as en.json: config, options, entity, and device sections. Supported codes: cs, da, de, el, en, es, fi, fr, hu, it, ja, nb, nl, pl, pt, ru, sv, tr, zh. See Internationalization (i18n) for details.