Add coordinator.py to RESTful component (#178114)

Co-authored-by: G Johansson <goran.johansson@shiftit.se>
This commit is contained in:
iluvdata
2026-09-17 18:13:48 +02:00
committed by GitHub
co-authored by G Johansson
parent 2e7816c793
commit 5a081e154f
6 changed files with 72 additions and 54 deletions
+11 -44
View File
@@ -38,7 +38,6 @@ from homeassistant.helpers.reload import (
async_reload_integration_platforms,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.util.async_ import create_eager_task
from .const import (
@@ -49,10 +48,9 @@ from .const import (
DEFAULT_SSL_CIPHER_LIST,
DOMAIN,
PLATFORM_IDX,
REST,
REST_DATA,
REST_IDX,
)
from .coordinator import RestCoordinator
from .data import RestData
from .schema import CONFIG_SCHEMA, RESOURCE_SCHEMA # noqa: F401
@@ -94,7 +92,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
@callback
def _async_setup_shared_data(hass: HomeAssistant) -> None:
"""Create shared data for platform config and rest coordinators."""
hass.data[DOMAIN] = {key: [] for key in (REST_DATA, *COORDINATOR_AWARE_PLATFORMS)}
hass.data[DOMAIN] = {key: [] for key in (COORDINATOR, *COORDINATOR_AWARE_PLATFORMS)}
async def _async_process_config(hass: HomeAssistant, config: ConfigType) -> bool:
@@ -110,11 +108,11 @@ async def _async_process_config(hass: HomeAssistant, config: ConfigType) -> bool
resource_template: template.Template | None = conf.get(CONF_RESOURCE_TEMPLATE)
payload_template: template.Template | None = conf.get(CONF_PAYLOAD_TEMPLATE)
rest = create_rest_data_from_config(hass, conf)
coordinator = _rest_coordinator(
hass, rest, resource_template, payload_template, scan_interval
coordinator = RestCoordinator(
hass, rest, None, resource_template, payload_template, scan_interval
)
refresh_coroutines.append(coordinator.async_refresh())
hass.data[DOMAIN][REST_DATA].append({REST: rest, COORDINATOR: coordinator})
hass.data[DOMAIN][COORDINATOR].append(coordinator)
for platform_domain in COORDINATOR_AWARE_PLATFORMS:
if platform_domain not in conf:
@@ -144,46 +142,15 @@ async def _async_process_config(hass: HomeAssistant, config: ConfigType) -> bool
async def async_get_config_and_coordinator(
hass: HomeAssistant, platform_domain: str, discovery_info: DiscoveryInfoType
) -> tuple[ConfigType, DataUpdateCoordinator[None], RestData]:
) -> tuple[ConfigType, RestCoordinator, RestData]:
"""Get the config and coordinator for the platform from discovery."""
shared_data = hass.data[DOMAIN][REST_DATA][discovery_info[REST_IDX]]
coordinator: RestCoordinator = hass.data[DOMAIN][COORDINATOR][
discovery_info[REST_IDX]
]
conf: ConfigType = hass.data[DOMAIN][platform_domain][discovery_info[PLATFORM_IDX]]
coordinator: DataUpdateCoordinator[None] = shared_data[COORDINATOR]
rest: RestData = shared_data[REST]
if rest.data is None:
if coordinator.rest.data is None:
await coordinator.async_request_refresh()
return conf, coordinator, rest
def _rest_coordinator(
hass: HomeAssistant,
rest: RestData,
resource_template: template.Template | None,
payload_template: template.Template | None,
update_interval: timedelta,
) -> DataUpdateCoordinator[None]:
"""Wrap a DataUpdateCoordinator around the rest object."""
if resource_template or payload_template:
async def _async_refresh_with_templates() -> None:
if resource_template:
rest.set_url(resource_template.async_render(parse_result=False))
if payload_template:
rest.set_payload(payload_template.async_render(parse_result=False))
await rest.async_update()
update_method = _async_refresh_with_templates
else:
update_method = rest.async_update
return DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=None,
name="rest data",
update_method=update_method,
update_interval=update_interval,
)
return conf, coordinator, coordinator.rest
def create_rest_data_from_config(hass: HomeAssistant, config: ConfigType) -> RestData:
@@ -25,9 +25,9 @@ from homeassistant.helpers.trigger_template_entity import (
ValueTemplate,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import DEFAULT_BINARY_SENSOR_NAME
from .coordinator import RestCoordinator
from .data import RestData
from .entity import (
RestEntity,
@@ -78,7 +78,7 @@ class RestBinarySensor(ManualTriggerEntity, RestEntity, BinarySensorEntity):
def __init__(
self,
hass: HomeAssistant,
coordinator: DataUpdateCoordinator[None] | None,
coordinator: RestCoordinator | None,
rest: RestData,
config: ConfigType,
trigger_entity_config: ConfigType,
-3
View File
@@ -21,9 +21,6 @@ REST_IDX = "rest_idx"
PLATFORM_IDX = "platform_idx"
COORDINATOR = "coordinator"
REST = "rest"
REST_DATA = "rest_data"
METHODS = ["POST", "GET"]
@@ -0,0 +1,54 @@
"""RESTful Data Update Coordinator."""
from datetime import timedelta
import logging
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import template
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .data import RestData
_LOGGER = logging.getLogger(__name__)
RestConfigEntry = ConfigEntry["RestCoordinator"]
class RestCoordinator(DataUpdateCoordinator[None]):
"""Rest coordinator."""
def __init__(
self,
hass: HomeAssistant,
rest: RestData,
config_entry: RestConfigEntry | None,
resource_template: template.Template | None,
payload_template: template.Template | None,
update_interval: timedelta,
) -> None:
"""Initialize a data update coordinator."""
self.rest: RestData = rest
if resource_template or payload_template:
async def _async_refresh_with_templates() -> None:
if resource_template:
rest.set_url(resource_template.async_render(parse_result=False))
if payload_template:
rest.set_payload(payload_template.async_render(parse_result=False))
await rest.async_update()
update_method = _async_refresh_with_templates
else:
update_method = rest.async_update
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name="rest data",
update_interval=update_interval,
update_method=update_method,
)
+3 -3
View File
@@ -22,9 +22,9 @@ from homeassistant.helpers.trigger_template_entity import (
CONF_PICTURE,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import async_get_config_and_coordinator, create_rest_data_from_config
from .coordinator import RestCoordinator
from .data import RestData
TRIGGER_ENTITY_OPTIONS = (
@@ -45,7 +45,7 @@ async def async_get_config_rest_data_and_coordinator(
config: ConfigType,
entity_domain: str,
discovery_info: DiscoveryInfoType | None = None,
) -> tuple[ConfigType, RestData, DataUpdateCoordinator[None] | None]:
) -> tuple[ConfigType, RestData, RestCoordinator | None]:
"""Get the config, rest data +/- coordinator for sub entity."""
# Must update the sensor now (including fetching the rest resource) to
# ensure it's updating its state.
@@ -96,7 +96,7 @@ class RestEntity(Entity):
def __init__(
self,
coordinator: DataUpdateCoordinator[None] | None,
coordinator: RestCoordinator | None,
rest: RestData,
resource_template: Template | None,
force_update: bool,
+2 -2
View File
@@ -24,9 +24,9 @@ from homeassistant.helpers.trigger_template_entity import (
ValueTemplate,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import CONF_JSON_ATTRS, CONF_JSON_ATTRS_PATH, DEFAULT_SENSOR_NAME
from .coordinator import RestCoordinator
from .data import RestData
from .entity import (
RestEntity,
@@ -76,7 +76,7 @@ class RestSensor(ManualTriggerSensorEntity, RestEntity):
def __init__(
self,
hass: HomeAssistant,
coordinator: DataUpdateCoordinator[None] | None,
coordinator: RestCoordinator | None,
rest: RestData,
config: ConfigType,
trigger_entity_config: ConfigType,