Remove SolarEdge Local integration (#183446)

This commit is contained in:
Franck Nijhof
2026-09-28 15:04:56 +02:00
committed by GitHub
parent d5be0ddb51
commit 3b2a141d6b
8 changed files with 1 additions and 414 deletions
Generated
-1
View File
@@ -1764,7 +1764,6 @@ CLAUDE.md @home-assistant/core
/tests/components/sofar/ @darkrain-nl
/homeassistant/components/solaredge/ @frenck @bdraco @tronikos
/tests/components/solaredge/ @frenck @bdraco @tronikos
/homeassistant/components/solaredge_local/ @drobtravels @scheric
/homeassistant/components/solaredge_modbus/ @frenck
/tests/components/solaredge_modbus/ @frenck
/homeassistant/components/solarlog/ @Ernst79 @dontinelli
+1 -1
View File
@@ -1,5 +1,5 @@
{
"domain": "solaredge",
"name": "SolarEdge",
"integrations": ["solaredge", "solaredge_local", "solaredge_modbus"]
"integrations": ["solaredge", "solaredge_modbus"]
}
@@ -1 +0,0 @@
"""The SolarEdge Local Integration."""
@@ -1,10 +0,0 @@
{
"domain": "solaredge_local",
"name": "SolarEdge Local",
"codeowners": ["@drobtravels", "@scheric"],
"documentation": "https://www.home-assistant.io/integrations/solaredge_local",
"iot_class": "local_polling",
"loggers": ["solaredge_local"],
"quality_scale": "legacy",
"requirements": ["solaredge-local==0.2.3"]
}
@@ -1,390 +0,0 @@
"""Support for SolarEdge-local Monitoring API."""
from contextlib import suppress
import dataclasses
from datetime import timedelta
import logging
import statistics
from typing import Any, override
import probatio
from requests.exceptions import ConnectTimeout, HTTPError
from solaredge_local import SolarEdge
from homeassistant.components.sensor import (
PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.const import (
CONF_IP_ADDRESS,
CONF_NAME,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfFrequency,
UnitOfPower,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import Throttle
DOMAIN = "solaredge_local"
UPDATE_DELAY = timedelta(seconds=10)
INVERTER_MODES = (
"SHUTTING_DOWN",
"ERROR",
"STANDBY",
"PAIRING",
"POWER_PRODUCTION",
"AC_CHARGING",
"NOT_PAIRED",
"NIGHT_MODE",
"GRID_MONITORING",
"IDLE",
)
@dataclasses.dataclass(frozen=True)
class SolarEdgeLocalSensorEntityDescription(SensorEntityDescription):
"""Describes SolarEdge-local sensor entity."""
extra_attribute: str | None = None
SENSOR_TYPES: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
SolarEdgeLocalSensorEntityDescription(
key="gridvoltage",
name="Grid Voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
icon="mdi:current-ac",
),
SolarEdgeLocalSensorEntityDescription(
key="dcvoltage",
name="DC Voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
icon="mdi:current-dc",
),
SolarEdgeLocalSensorEntityDescription(
key="gridfrequency",
name="Grid Frequency",
native_unit_of_measurement=UnitOfFrequency.HERTZ,
device_class=SensorDeviceClass.FREQUENCY,
),
SolarEdgeLocalSensorEntityDescription(
key="currentPower",
name="Current Power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
icon="mdi:solar-power",
),
SolarEdgeLocalSensorEntityDescription(
key="energyThisMonth",
name="Energy This Month",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:solar-power",
),
SolarEdgeLocalSensorEntityDescription(
key="energyThisYear",
name="Energy This Year",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:solar-power",
),
SolarEdgeLocalSensorEntityDescription(
key="energyToday",
name="Energy Today",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:solar-power",
),
SolarEdgeLocalSensorEntityDescription(
key="energyTotal",
name="Lifetime Energy",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:solar-power",
),
SolarEdgeLocalSensorEntityDescription(
key="optimizers",
name="Optimizers Online",
native_unit_of_measurement="optimizers",
icon="mdi:solar-panel",
extra_attribute="optimizers_connected",
),
SolarEdgeLocalSensorEntityDescription(
key="optimizercurrent",
name="Average Optimizer Current",
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
device_class=SensorDeviceClass.CURRENT,
icon="mdi:solar-panel",
),
SolarEdgeLocalSensorEntityDescription(
key="optimizerpower",
name="Average Optimizer Power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
icon="mdi:solar-panel",
),
SolarEdgeLocalSensorEntityDescription(
key="optimizertemperature",
name="Average Optimizer Temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
icon="mdi:solar-panel",
device_class=SensorDeviceClass.TEMPERATURE,
),
SolarEdgeLocalSensorEntityDescription(
key="optimizervoltage",
name="Average Optimizer Voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
icon="mdi:solar-panel",
),
)
SENSOR_TYPE_INVERTER_TEMPERATURE = SolarEdgeLocalSensorEntityDescription(
key="invertertemperature",
name="Inverter Temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
extra_attribute="operating_mode",
device_class=SensorDeviceClass.TEMPERATURE,
)
SENSOR_TYPES_ENERGY_IMPORT: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
SolarEdgeLocalSensorEntityDescription(
key="currentPowerimport",
name="current import Power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
icon="mdi:arrow-collapse-down",
),
SolarEdgeLocalSensorEntityDescription(
key="totalEnergyimport",
name="total import Energy",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:counter",
),
)
SENSOR_TYPES_ENERGY_EXPORT: tuple[SolarEdgeLocalSensorEntityDescription, ...] = (
SolarEdgeLocalSensorEntityDescription(
key="currentPowerexport",
name="current export Power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
icon="mdi:arrow-expand-up",
),
SolarEdgeLocalSensorEntityDescription(
key="totalEnergyexport",
name="total export Energy",
native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
device_class=SensorDeviceClass.ENERGY,
icon="mdi:counter",
),
)
PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
{
probatio.Required(CONF_IP_ADDRESS): cv.string,
probatio.Optional(CONF_NAME, default="SolarEdge"): cv.string,
}
)
_LOGGER = logging.getLogger(__name__)
def setup_platform(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Create the SolarEdge Monitoring API sensor."""
ip_address = config[CONF_IP_ADDRESS]
platform_name = config[CONF_NAME]
# Create new SolarEdge object to retrieve data.
api = SolarEdge(f"http://{ip_address}/")
# Check if api can be reached and site is active.
try:
status = api.get_status()
_LOGGER.debug("Credentials correct and site is active")
except AttributeError:
_LOGGER.error("Missing details data in solaredge status")
return
except ConnectTimeout, HTTPError:
_LOGGER.error("Could not retrieve details from SolarEdge API")
return
# Create solaredge data service which will retrieve and update the data.
data = SolarEdgeData(hass, api)
# Changing inverter temperature unit.
inverter_temp_description = SENSOR_TYPE_INVERTER_TEMPERATURE
if (
status.inverters.primary.temperature.units.farenheit # codespell:ignore farenheit
):
inverter_temp_description = dataclasses.replace(
inverter_temp_description,
native_unit_of_measurement=UnitOfTemperature.FAHRENHEIT,
)
# Create entities
entities = [
SolarEdgeSensor(platform_name, data, description)
for description in (*SENSOR_TYPES, inverter_temp_description)
]
try:
if status.metersList[0]:
entities.extend(
[
SolarEdgeSensor(platform_name, data, description)
for description in SENSOR_TYPES_ENERGY_IMPORT
]
)
except IndexError:
_LOGGER.debug("Import meter sensors are not created")
try:
if status.metersList[1]:
entities.extend(
[
SolarEdgeSensor(platform_name, data, description)
for description in SENSOR_TYPES_ENERGY_EXPORT
]
)
except IndexError:
_LOGGER.debug("Export meter sensors are not created")
add_entities(entities, True)
class SolarEdgeSensor(SensorEntity):
"""Representation of an SolarEdge Monitoring API sensor."""
entity_description: SolarEdgeLocalSensorEntityDescription
def __init__(
self,
platform_name,
data,
description: SolarEdgeLocalSensorEntityDescription,
) -> None:
"""Initialize the sensor."""
self.entity_description = description
self._platform_name = platform_name
self._data = data
self._attr_name = f"{platform_name} ({description.name})"
@property
@override
def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the state attributes."""
if extra_attr := self.entity_description.extra_attribute:
try:
return {extra_attr: self._data.info.get(self.entity_description.key)}
except KeyError:
pass
return None
def update(self) -> None:
"""Get the latest data from the sensor and update the state."""
self._data.update()
self._attr_native_value = self._data.data.get(self.entity_description.key)
class SolarEdgeData:
"""Get and update the latest data."""
def __init__(self, hass, api):
"""Initialize the data object."""
self.hass = hass
self.api = api
self.data = {}
self.info = {}
@Throttle(UPDATE_DELAY)
def update(self):
"""Update the data from the SolarEdge Monitoring API."""
try:
status = self.api.get_status()
_LOGGER.debug("Status from SolarEdge: %s", status)
except ConnectTimeout:
_LOGGER.error("Connection timeout, skipping update")
return
except HTTPError:
_LOGGER.error("Could not retrieve status, skipping update")
return
try:
maintenance = self.api.get_maintenance()
_LOGGER.debug("Maintenance from SolarEdge: %s", maintenance)
except ConnectTimeout:
_LOGGER.error("Connection timeout, skipping update")
return
except HTTPError:
_LOGGER.error("Could not retrieve maintenance, skipping update")
return
temperature = []
voltage = []
current = []
power = 0
for optimizer in maintenance.diagnostics.inverters.primary.optimizer:
if not optimizer.online:
continue
temperature.append(optimizer.temperature.value)
voltage.append(optimizer.inputV)
current.append(optimizer.inputC)
if not voltage:
temperature.append(0)
voltage.append(0)
current.append(0)
else:
power = statistics.mean(voltage) * statistics.mean(current)
if status.sn:
self.data["energyTotal"] = round(status.energy.total, 2)
self.data["energyThisYear"] = round(status.energy.thisYear, 2)
self.data["energyThisMonth"] = round(status.energy.thisMonth, 2)
self.data["energyToday"] = round(status.energy.today, 2)
self.data["currentPower"] = round(status.powerWatt, 2)
self.data["invertertemperature"] = round(
status.inverters.primary.temperature.value, 2
)
self.data["dcvoltage"] = round(status.inverters.primary.voltage, 2)
self.data["gridfrequency"] = round(status.frequencyHz, 2)
self.data["gridvoltage"] = round(status.voltage, 2)
self.data["optimizers"] = status.optimizersStatus.online
self.info["optimizers"] = status.optimizersStatus.total
self.info["invertertemperature"] = INVERTER_MODES[status.status]
with suppress(IndexError):
if status.metersList[1]:
self.data["currentPowerimport"] = status.metersList[1].currentPower
self.data["totalEnergyimport"] = status.metersList[1].totalEnergy
with suppress(IndexError):
if status.metersList[0]:
self.data["currentPowerexport"] = status.metersList[0].currentPower
self.data["totalEnergyexport"] = status.metersList[0].totalEnergy
if maintenance.system.name:
self.data["optimizertemperature"] = round(statistics.mean(temperature), 2)
self.data["optimizervoltage"] = round(statistics.mean(voltage), 2)
self.data["optimizercurrent"] = round(statistics.mean(current), 2)
self.data["optimizerpower"] = round(power, 2)
@@ -6887,12 +6887,6 @@
"iot_class": "cloud_polling",
"name": "SolarEdge"
},
"solaredge_local": {
"integration_type": "hub",
"config_flow": false,
"iot_class": "local_polling",
"name": "SolarEdge Local"
},
"solaredge_modbus": {
"integration_type": "device",
"config_flow": true,
-3
View File
@@ -3131,9 +3131,6 @@ soco==0.31.2
# homeassistant.components.sofar
sofar-modbus==0.17.0
# homeassistant.components.solaredge_local
solaredge-local==0.2.3
# homeassistant.components.solaredge
solaredge-web==0.4.0
-2
View File
@@ -827,7 +827,6 @@ INTEGRATIONS_WITHOUT_QUALITY_SCALE_FILE = [
"snmp",
"snooz",
"solaredge",
"solaredge_local",
"solax",
"soma",
"somfy_mylink",
@@ -1773,7 +1772,6 @@ INTEGRATIONS_WITHOUT_SCALE = [
"snmp",
"snooz",
"solaredge",
"solaredge_local",
"solax",
"soma",
"somfy_mylink",