Skip to content

Commit

Permalink
- Resolve deprecation warnings with 2024.7.x: https://developers.home…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexdelprete committed Jul 6, 2024
1 parent 9b37eb9 commit 89015c2
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 50 deletions.
98 changes: 64 additions & 34 deletions custom_components/4noks_elios4you/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,39 @@
https://github.com/alexdelprete/ha-4noks-elios4you
"""

import asyncio
import logging
from collections.abc import Callable
from dataclasses import dataclass

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from .const import (
CONF_NAME,
DATA,
DOMAIN,
PLATFORMS,
STARTUP_MESSAGE,
UPDATE_LISTENER,
)
from .coordinator import Elios4YouCoordinator

_LOGGER = logging.getLogger(__name__)

PLATFORMS: list[Platform] = [Platform.SENSOR]

# The type alias needs to be suffixed with 'ConfigEntry'
type Elios4YouConfigEntry = ConfigEntry[RuntimeData]


@dataclass
class RuntimeData:
"""Class to hold your data."""

coordinator: DataUpdateCoordinator
update_listener: Callable


def get_instance_count(hass: HomeAssistant) -> int:
"""Return number of instances."""
Expand All @@ -34,47 +47,55 @@ def get_instance_count(hass: HomeAssistant) -> int:
return len(entries)


async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
"""Set up this integration using UI."""
async def async_setup_entry(hass: HomeAssistant, config_entry: Elios4YouConfigEntry):
"""Set up integration from a config entry."""

if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})
_LOGGER.info(STARTUP_MESSAGE)

_LOGGER.debug(f"Setup config_entry for {DOMAIN}")

# Initialise the coordinator that manages data updates from your api.
# This is defined in coordinator.py
coordinator = Elios4YouCoordinator(hass, config_entry)

# If the refresh fails, async_config_entry_first_refresh() will
# raise ConfigEntryNotReady and setup will try again later
# ref.: https://developers.home-assistant.io/docs/integration_setup_failures
await coordinator.async_config_entry_first_refresh()

# Test to see if api initialised correctly, else raise ConfigNotReady to make HA retry setup
# Change this to match how your api will know if connected or successful update
if not coordinator.api.data["sn"]:
raise ConfigEntryNotReady(
f"Timeout connecting to {config_entry.data.get(CONF_NAME)}"
)

# Update listener for config option changes
# Initialise a listener for config flow options changes.
# See config_flow for defining an options setting that shows up as configure on the integration.
update_listener = config_entry.add_update_listener(_async_update_listener)

# Add coordinator and update_listener to config_entry
hass.data[DOMAIN][config_entry.entry_id] = {
DATA: coordinator,
UPDATE_LISTENER: update_listener,
}
# Add the coordinator and update listener to hass data to make
# accessible throughout your integration
# Note: this will change on HA2024.6 to save on the config entry.
config_entry.runtime_data = RuntimeData(coordinator, update_listener)

# Setup platforms
for platform in PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(config_entry, platform)
)
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)

# Regiser device
await async_update_device_registry(hass, config_entry)

# Return true to denote a successful setup.
return True


async def async_update_device_registry(hass: HomeAssistant, config_entry):
async def async_update_device_registry(
hass: HomeAssistant, config_entry: Elios4YouConfigEntry
):
"""Manual device registration."""
coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA]
# This gets the data update coordinator from hass.data
coordinator: Elios4YouCoordinator = config_entry.runtime_data.coordinator
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
Expand All @@ -91,14 +112,18 @@ async def async_update_device_registry(hass: HomeAssistant, config_entry):


async def _async_update_listener(hass: HomeAssistant, config_entry):
"""Handle options update."""
"""Handle config options update."""
# Reload the integration when the options change.
await hass.config_entries.async_reload(config_entry.entry_id)


async def async_remove_config_entry_device(
hass: HomeAssistant, config_entry, device_entry
) -> bool:
"""Delete device if not entities."""
"""Delete device if selected from UI."""
# Adding this function shows the delete device option in the UI.
# Remove this function if you do not want that option.
# You may need to do some checks here before allowing devices to be removed.
if DOMAIN in device_entry.identifiers:
_LOGGER.error(
"You cannot delete the device using device delete. Remove the integration instead."
Expand All @@ -108,27 +133,32 @@ async def async_remove_config_entry_device(


async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Handle removal of config_entry."""
"""Unload a config entry."""
# This is called when you remove your integration or shutdown HA.
# If you have created any custom services, they need to be removed here too.

_LOGGER.debug("Unload config_entry")

# This is called when you remove your integration or shutdown HA.
# If you have created any custom services, they need to be removed here too.

# Remove the config options update listener
_LOGGER.debug("Detach config update listener")
hass.data[DOMAIN][config_entry.entry_id].update_listener()

# Check if there are other instances
if get_instance_count(hass) == 0:
_LOGGER.debug("Unload config_entry: no more entries found")

_LOGGER.debug("Unload integration platforms")
# Unload a config entry
unloaded = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(config_entry, platform)
for platform in PLATFORMS
]
)
)

_LOGGER.debug("Detach config update listener")
hass.data[DOMAIN][config_entry.entry_id][UPDATE_LISTENER]()
# Unload platforms
unload_ok = await hass.config_entries.async_unload_platforms(
config_entry, PLATFORMS
)

if unloaded:
# Remove the config entry from the hass data object.
if unload_ok:
_LOGGER.debug("Unload integration")
hass.data[DOMAIN].pop(config_entry.entry_id)
return True # unloaded
Expand Down
8 changes: 0 additions & 8 deletions custom_components/4noks_elios4you/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@
ATTRIBUTION = "by @alexdelprete"
ISSUE_URL = "https://github.com/alexdelprete/ha-4noks-elios4you/issues"

# Platforms
PLATFORMS = [
"sensor",
"switch",
]
UPDATE_LISTENER = "update_listener"
DATA = "data"

# Configuration and options
CONF_NAME = "name"
CONF_HOST = "host"
Expand Down
13 changes: 9 additions & 4 deletions custom_components/4noks_elios4you/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from . import Elios4YouConfigEntry
from .const import (
CONF_NAME,
DATA,
DOMAIN,
SENSOR_ENTITIES,
)
from .coordinator import Elios4YouCoordinator

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities):
async def async_setup_entry(
hass: HomeAssistant, config_entry: Elios4YouConfigEntry, async_add_entities
):
"""Sensor Platform setup."""

# Get handler to coordinator from config
coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA]
# This gets the data update coordinator from hass.data as specified in your __init__.py
coordinator: Elios4YouCoordinator = config_entry.runtime_data.coordinator

_LOGGER.debug("(sensor) Name: %s", config_entry.data.get(CONF_NAME))
_LOGGER.debug("(sensor) Manufacturer: %s", coordinator.api.data["manufact"])
Expand Down Expand Up @@ -129,6 +132,8 @@ def native_value(self):
"""Return the state of the sensor."""
if self._key in self._coordinator.api.data:
return self._coordinator.api.data[self._key]
else:
return None

@property
def state_attributes(self) -> dict[str, Any] | None:
Expand Down
12 changes: 8 additions & 4 deletions custom_components/4noks_elios4you/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DATA, DOMAIN, SWITCH_ENTITIES
from . import Elios4YouConfigEntry
from .const import DOMAIN, SWITCH_ENTITIES
from .coordinator import Elios4YouCoordinator

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass: HomeAssistant, config_entry, async_add_entities):
async def async_setup_entry(
hass: HomeAssistant, config_entry: Elios4YouConfigEntry, async_add_entities
):
"""Switch Platform setup."""

# Get handler to coordinator from config
coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA]
# This gets the data update coordinator from hass.data as specified in your __init__.py
coordinator: Elios4YouCoordinator = config_entry.runtime_data.coordinator

# Add defined switches
switches = []
Expand Down

0 comments on commit 89015c2

Please sign in to comment.