mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Move SolarEdge API init and add unload (#50823)
* SolarEdge: Move API init, add unload * Slim down try-except block
This commit is contained in:
parent
3ed416ed4c
commit
ebe1059c34
@ -1,18 +1,50 @@
|
|||||||
"""The solaredge integration."""
|
"""The SolarEdge integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from requests.exceptions import ConnectTimeout, HTTPError
|
||||||
|
from solaredge import Solaredge
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_API_KEY
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import CONF_SITE_ID, DATA_API_CLIENT, DOMAIN, LOGGER
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
|
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
|
||||||
|
|
||||||
|
PLATFORMS = ["sensor"]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Load the saved entities."""
|
"""Set up SolarEdge from a config entry."""
|
||||||
hass.async_create_task(
|
api = Solaredge(entry.data[CONF_API_KEY])
|
||||||
hass.config_entries.async_forward_entry_setup(entry, "sensor")
|
|
||||||
)
|
try:
|
||||||
|
response = await hass.async_add_executor_job(
|
||||||
|
api.get_details, entry.data[CONF_SITE_ID]
|
||||||
|
)
|
||||||
|
except KeyError as ex:
|
||||||
|
LOGGER.error("Missing details data in SolarEdge response")
|
||||||
|
raise ConfigEntryNotReady from ex
|
||||||
|
except (ConnectTimeout, HTTPError) as ex:
|
||||||
|
LOGGER.error("Could not retrieve details from SolarEdge API")
|
||||||
|
raise ConfigEntryNotReady from ex
|
||||||
|
|
||||||
|
if response["details"]["status"].lower() != "active":
|
||||||
|
LOGGER.error("SolarEdge site is not active")
|
||||||
|
return False
|
||||||
|
LOGGER.debug("Credentials correct and site is active")
|
||||||
|
|
||||||
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {DATA_API_CLIENT: api}
|
||||||
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Unload SolarEdge config entry."""
|
||||||
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
if unload_ok:
|
||||||
|
del hass.data[DOMAIN][entry.entry_id]
|
||||||
|
return unload_ok
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
"""Constants for the SolarEdge Monitoring API."""
|
"""Constants for the SolarEdge Monitoring API."""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
from homeassistant.const import ENERGY_WATT_HOUR, PERCENTAGE, POWER_WATT
|
from homeassistant.const import ENERGY_WATT_HOUR, PERCENTAGE, POWER_WATT
|
||||||
|
|
||||||
DOMAIN = "solaredge"
|
DOMAIN = "solaredge"
|
||||||
|
|
||||||
|
LOGGER = logging.getLogger(__package__)
|
||||||
|
|
||||||
|
DATA_API_CLIENT = "api_client"
|
||||||
|
|
||||||
# Config for solaredge monitoring api requests.
|
# Config for solaredge monitoring api requests.
|
||||||
CONF_SITE_ID = "site_id"
|
CONF_SITE_ID = "site_id"
|
||||||
|
|
||||||
DEFAULT_NAME = "SolarEdge"
|
DEFAULT_NAME = "SolarEdge"
|
||||||
|
|
||||||
OVERVIEW_UPDATE_DELAY = timedelta(minutes=15)
|
OVERVIEW_UPDATE_DELAY = timedelta(minutes=15)
|
||||||
@ -18,6 +22,7 @@ ENERGY_DETAILS_DELAY = timedelta(minutes=15)
|
|||||||
|
|
||||||
SCAN_INTERVAL = timedelta(minutes=15)
|
SCAN_INTERVAL = timedelta(minutes=15)
|
||||||
|
|
||||||
|
|
||||||
# Supported overview sensor types:
|
# Supported overview sensor types:
|
||||||
# Key: ['json_key', 'name', unit, icon, default]
|
# Key: ['json_key', 'name', unit, icon, default]
|
||||||
SENSOR_TYPES = {
|
SENSOR_TYPES = {
|
||||||
|
@ -3,18 +3,15 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from requests.exceptions import ConnectTimeout, HTTPError
|
|
||||||
from solaredge import Solaredge
|
from solaredge import Solaredge
|
||||||
from stringcase import snakecase
|
from stringcase import snakecase
|
||||||
|
|
||||||
from homeassistant.components.sensor import SensorEntity
|
from homeassistant.components.sensor import SensorEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_API_KEY, DEVICE_CLASS_BATTERY, DEVICE_CLASS_POWER
|
from homeassistant.const import DEVICE_CLASS_BATTERY, DEVICE_CLASS_POWER
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
CoordinatorEntity,
|
CoordinatorEntity,
|
||||||
@ -24,16 +21,17 @@ from homeassistant.helpers.update_coordinator import (
|
|||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_SITE_ID,
|
CONF_SITE_ID,
|
||||||
|
DATA_API_CLIENT,
|
||||||
DETAILS_UPDATE_DELAY,
|
DETAILS_UPDATE_DELAY,
|
||||||
|
DOMAIN,
|
||||||
ENERGY_DETAILS_DELAY,
|
ENERGY_DETAILS_DELAY,
|
||||||
INVENTORY_UPDATE_DELAY,
|
INVENTORY_UPDATE_DELAY,
|
||||||
|
LOGGER,
|
||||||
OVERVIEW_UPDATE_DELAY,
|
OVERVIEW_UPDATE_DELAY,
|
||||||
POWER_FLOW_UPDATE_DELAY,
|
POWER_FLOW_UPDATE_DELAY,
|
||||||
SENSOR_TYPES,
|
SENSOR_TYPES,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -42,23 +40,7 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Add an solarEdge entry."""
|
"""Add an solarEdge entry."""
|
||||||
# Add the needed sensors to hass
|
# Add the needed sensors to hass
|
||||||
api = Solaredge(entry.data[CONF_API_KEY])
|
api: Solaredge = hass.data[DOMAIN][entry.entry_id][DATA_API_CLIENT]
|
||||||
|
|
||||||
# Check if api can be reached and site is active
|
|
||||||
try:
|
|
||||||
response = await hass.async_add_executor_job(
|
|
||||||
api.get_details, entry.data[CONF_SITE_ID]
|
|
||||||
)
|
|
||||||
if response["details"]["status"].lower() != "active":
|
|
||||||
_LOGGER.error("SolarEdge site is not active")
|
|
||||||
return
|
|
||||||
_LOGGER.debug("Credentials correct and site is active")
|
|
||||||
except KeyError as ex:
|
|
||||||
_LOGGER.error("Missing details data in SolarEdge response")
|
|
||||||
raise ConfigEntryNotReady from ex
|
|
||||||
except (ConnectTimeout, HTTPError) as ex:
|
|
||||||
_LOGGER.error("Could not retrieve details from SolarEdge API")
|
|
||||||
raise ConfigEntryNotReady from ex
|
|
||||||
|
|
||||||
sensor_factory = SolarEdgeSensorFactory(
|
sensor_factory = SolarEdgeSensorFactory(
|
||||||
hass, entry.title, entry.data[CONF_SITE_ID], api
|
hass, entry.title, entry.data[CONF_SITE_ID], api
|
||||||
@ -313,7 +295,7 @@ class SolarEdgeDataService:
|
|||||||
"""Coordinator creation."""
|
"""Coordinator creation."""
|
||||||
self.coordinator = DataUpdateCoordinator(
|
self.coordinator = DataUpdateCoordinator(
|
||||||
self.hass,
|
self.hass,
|
||||||
_LOGGER,
|
LOGGER,
|
||||||
name=str(self),
|
name=str(self),
|
||||||
update_method=self.async_update_data,
|
update_method=self.async_update_data,
|
||||||
update_interval=self.update_interval,
|
update_interval=self.update_interval,
|
||||||
@ -360,7 +342,7 @@ class SolarEdgeOverviewDataService(SolarEdgeDataService):
|
|||||||
data = value
|
data = value
|
||||||
self.data[key] = data
|
self.data[key] = data
|
||||||
|
|
||||||
_LOGGER.debug("Updated SolarEdge overview: %s", self.data)
|
LOGGER.debug("Updated SolarEdge overview: %s", self.data)
|
||||||
|
|
||||||
|
|
||||||
class SolarEdgeDetailsDataService(SolarEdgeDataService):
|
class SolarEdgeDetailsDataService(SolarEdgeDataService):
|
||||||
@ -406,7 +388,7 @@ class SolarEdgeDetailsDataService(SolarEdgeDataService):
|
|||||||
elif key == "status":
|
elif key == "status":
|
||||||
self.data = value
|
self.data = value
|
||||||
|
|
||||||
_LOGGER.debug("Updated SolarEdge details: %s, %s", self.data, self.attributes)
|
LOGGER.debug("Updated SolarEdge details: %s, %s", self.data, self.attributes)
|
||||||
|
|
||||||
|
|
||||||
class SolarEdgeInventoryDataService(SolarEdgeDataService):
|
class SolarEdgeInventoryDataService(SolarEdgeDataService):
|
||||||
@ -432,7 +414,7 @@ class SolarEdgeInventoryDataService(SolarEdgeDataService):
|
|||||||
self.data[key] = len(value)
|
self.data[key] = len(value)
|
||||||
self.attributes[key] = {key: value}
|
self.attributes[key] = {key: value}
|
||||||
|
|
||||||
_LOGGER.debug("Updated SolarEdge inventory: %s, %s", self.data, self.attributes)
|
LOGGER.debug("Updated SolarEdge inventory: %s, %s", self.data, self.attributes)
|
||||||
|
|
||||||
|
|
||||||
class SolarEdgeEnergyDetailsService(SolarEdgeDataService):
|
class SolarEdgeEnergyDetailsService(SolarEdgeDataService):
|
||||||
@ -467,7 +449,7 @@ class SolarEdgeEnergyDetailsService(SolarEdgeDataService):
|
|||||||
raise UpdateFailed("Missing power flow data, skipping update") from ex
|
raise UpdateFailed("Missing power flow data, skipping update") from ex
|
||||||
|
|
||||||
if "meters" not in energy_details:
|
if "meters" not in energy_details:
|
||||||
_LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Missing meters in energy details data. Assuming site does not have any"
|
"Missing meters in energy details data. Assuming site does not have any"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@ -491,7 +473,7 @@ class SolarEdgeEnergyDetailsService(SolarEdgeDataService):
|
|||||||
self.data[meter["type"]] = meter["values"][0]["value"]
|
self.data[meter["type"]] = meter["values"][0]["value"]
|
||||||
self.attributes[meter["type"]] = {"date": meter["values"][0]["date"]}
|
self.attributes[meter["type"]] = {"date": meter["values"][0]["date"]}
|
||||||
|
|
||||||
_LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Updated SolarEdge energy details: %s, %s", self.data, self.attributes
|
"Updated SolarEdge energy details: %s, %s", self.data, self.attributes
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -522,7 +504,7 @@ class SolarEdgePowerFlowDataService(SolarEdgeDataService):
|
|||||||
power_to = []
|
power_to = []
|
||||||
|
|
||||||
if "connections" not in power_flow:
|
if "connections" not in power_flow:
|
||||||
_LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Missing connections in power flow data. Assuming site does not have any"
|
"Missing connections in power flow data. Assuming site does not have any"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@ -551,6 +533,4 @@ class SolarEdgePowerFlowDataService(SolarEdgeDataService):
|
|||||||
self.attributes[key]["flow"] = "charge" if charge else "discharge"
|
self.attributes[key]["flow"] = "charge" if charge else "discharge"
|
||||||
self.attributes[key]["soc"] = value["chargeLevel"]
|
self.attributes[key]["soc"] = value["chargeLevel"]
|
||||||
|
|
||||||
_LOGGER.debug(
|
LOGGER.debug("Updated SolarEdge power flow: %s, %s", self.data, self.attributes)
|
||||||
"Updated SolarEdge power flow: %s, %s", self.data, self.attributes
|
|
||||||
)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user