Skip to content

Commit

Permalink
Split out coordinator
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeeus committed Feb 11, 2023
1 parent 3652422 commit 6c0078c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 93 deletions.
97 changes: 24 additions & 73 deletions custom_components/integration_blueprint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,55 @@
Custom integration to integrate integration_blueprint with Home Assistant.
For more details about this integration, please refer to
https://github.com/custom-components/integration_blueprint
https://github.com/ludeeus/integration_blueprint
"""
import asyncio
from datetime import timedelta
import logging
from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .api import IntegrationBlueprintApiClient
from .const import CONF_PASSWORD, CONF_USERNAME, DOMAIN, PLATFORMS
from .coordinator import BlueprintDataUpdateCoordinator

from .const import (
CONF_PASSWORD,
CONF_USERNAME,
DOMAIN,
PLATFORMS,
STARTUP_MESSAGE,
)
PLATFORMS: list[Platform] = [
Platform.SENSOR,
Platform.BINARY_SENSOR,
Platform.SWITCH,
]

SCAN_INTERVAL = timedelta(seconds=30)

_LOGGER: logging.Logger = logging.getLogger(__package__)


async def async_setup(hass: HomeAssistant, config: Config):
"""Set up this integration using YAML is not supported."""
return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Set up this integration using UI."""
if hass.data.get(DOMAIN) is None:
hass.data.setdefault(DOMAIN, {})
_LOGGER.info(STARTUP_MESSAGE)

username = entry.data.get(CONF_USERNAME)
password = entry.data.get(CONF_PASSWORD)

session = async_get_clientsession(hass)
client = IntegrationBlueprintApiClient(username, password, session)

coordinator = BlueprintDataUpdateCoordinator(hass, client=client)
await coordinator.async_refresh()
coordinator = BlueprintDataUpdateCoordinator(
hass=hass,
client=IntegrationBlueprintApiClient(
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=async_get_clientsession(hass),
),
)

await coordinator.async_config_entry_first_refresh()
if not coordinator.last_update_success:
raise ConfigEntryNotReady

hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = coordinator

for platform in PLATFORMS:
if entry.options.get(platform, True):
coordinator.platforms.append(platform)
hass.async_add_job(
hass.config_entries.async_forward_entry_setup(entry, platform)
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

entry.async_on_unload(entry.add_update_listener(async_reload_entry))
return True


class BlueprintDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the API."""

def __init__(
self, hass: HomeAssistant, client: IntegrationBlueprintApiClient
) -> None:
"""Initialize."""
self.api = client
self.platforms = []

super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)

async def _async_update_data(self):
"""Update data via library."""
try:
return await self.api.async_get_data()
except Exception as exception:
raise UpdateFailed() from exception


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Handle removal of an entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
unloaded = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, platform)
for platform in PLATFORMS
if platform in coordinator.platforms
]
)
)
if unloaded:
if unloaded := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)

return unloaded


Expand Down
13 changes: 8 additions & 5 deletions custom_components/integration_blueprint/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Sample API Client."""
from __future__ import annotations

import asyncio
import socket

import aiohttp
import async_timeout

Expand All @@ -21,22 +24,22 @@ def __init__(
self._password = password
self._session = session

async def async_get_data(self) -> dict:
async def async_get_data(self) -> any:
"""Get data from the API."""
url = "https://jsonplaceholder.typicode.com/posts/1"
return await self.api_wrapper("get", url)
return await self._api_wrapper("get", url)

async def async_set_title(self, value: str) -> None:
async def async_set_title(self, value: str) -> any:
"""Get data from the API."""
url = "https://jsonplaceholder.typicode.com/posts/1"
await self.api_wrapper(
return await self._api_wrapper(
"patch",
url,
data={"title": value},
headers={"Content-type": "application/json; charset=UTF-8"},
)

async def api_wrapper(
async def _api_wrapper(
self,
method: str,
url: str,
Expand Down
7 changes: 1 addition & 6 deletions custom_components/integration_blueprint/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
"""Binary sensor platform for integration_blueprint."""
from homeassistant.components.binary_sensor import BinarySensorEntity

from .const import (
BINARY_SENSOR,
BINARY_SENSOR_DEVICE_CLASS,
DEFAULT_NAME,
DOMAIN,
)
from .const import BINARY_SENSOR, BINARY_SENSOR_DEVICE_CLASS, DEFAULT_NAME, DOMAIN
from .entity import IntegrationBlueprintEntity


Expand Down
9 changes: 2 additions & 7 deletions custom_components/integration_blueprint/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
"""Adds config flow for Blueprint."""
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_create_clientsession
import voluptuous as vol

from .api import IntegrationBlueprintApiClient
from .const import (
CONF_PASSWORD,
CONF_USERNAME,
DOMAIN,
PLATFORMS,
)
from .const import CONF_PASSWORD, CONF_USERNAME, DOMAIN, PLATFORMS


class BlueprintFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
Expand Down
2 changes: 1 addition & 1 deletion custom_components/integration_blueprint/const.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Constants for integration_blueprint."""
from logging import getLogger, Logger
from logging import Logger, getLogger

LOGGER: Logger = getLogger(__package__)

Expand Down
35 changes: 35 additions & 0 deletions custom_components/integration_blueprint/coordinator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""DataUpdateCoordinator for integration_blueprint."""
from __future__ import annotations

from datetime import timedelta

from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .api import IntegrationBlueprintApiClient
from .const import LOGGER, DOMAIN


class BlueprintDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the API."""

def __init__(
self,
hass: HomeAssistant,
client: IntegrationBlueprintApiClient,
) -> None:
"""Initialize."""
self.client = client
super().__init__(
hass=hass,
logger=LOGGER,
name=DOMAIN,
update_interval=timedelta(seconds=30),
)

async def _async_update_data(self):
"""Update data via library."""
try:
return await self.client.async_get_data()
except Exception as exception:
raise UpdateFailed() from exception
2 changes: 1 addition & 1 deletion custom_components/integration_blueprint/entity.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""BlueprintEntity class"""
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN, NAME, VERSION, ATTRIBUTION
from .const import ATTRIBUTION, DOMAIN, NAME, VERSION


class IntegrationBlueprintEntity(CoordinatorEntity):
Expand Down

0 comments on commit 6c0078c

Please sign in to comment.