Prepare Analytics insights for more sensors (#108976)

This commit is contained in:
Joost Lekkerkerker 2024-01-29 19:34:53 +01:00 committed by GitHub
parent a6b426ca3e
commit aefae5bdae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 70 additions and 26 deletions

View file

@ -17,7 +17,7 @@ PLATFORMS: list[Platform] = [Platform.SENSOR]
@dataclass(frozen=True)
class AnalyticsData:
class AnalyticsInsightsData:
"""Analytics data class."""
coordinator: HomeassistantAnalyticsDataUpdateCoordinator
@ -41,7 +41,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = AnalyticsData(
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = AnalyticsInsightsData(
coordinator=coordinator, names=names
)

View file

@ -1,6 +1,7 @@
"""DataUpdateCoordinator for the Homeassistant Analytics integration."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
from python_homeassistant_analytics import (
@ -16,9 +17,14 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
from .const import CONF_TRACKED_INTEGRATIONS, DOMAIN, LOGGER
class HomeassistantAnalyticsDataUpdateCoordinator(
DataUpdateCoordinator[dict[str, int]]
):
@dataclass(frozen=True, kw_only=True)
class AnalyticsData:
"""Analytics data class."""
core_integrations: dict[str, int]
class HomeassistantAnalyticsDataUpdateCoordinator(DataUpdateCoordinator[AnalyticsData]):
"""A Homeassistant Analytics Data Update Coordinator."""
config_entry: ConfigEntry
@ -38,7 +44,7 @@ class HomeassistantAnalyticsDataUpdateCoordinator(
CONF_TRACKED_INTEGRATIONS
]
async def _async_update_data(self) -> dict[str, int]:
async def _async_update_data(self) -> AnalyticsData:
try:
data = await self._client.get_current_analytics()
except HomeassistantAnalyticsConnectionError as err:
@ -47,7 +53,8 @@ class HomeassistantAnalyticsDataUpdateCoordinator(
) from err
except HomeassistantAnalyticsNotModifiedError:
return self.data
return {
core_integrations = {
integration: data.integrations.get(integration, 0)
for integration in self._tracked_integrations
}
return AnalyticsData(core_integrations=core_integrations)

View file

@ -0,0 +1,9 @@
{
"entity": {
"sensor": {
"core_integrations": {
"default": "mdi:puzzle"
}
}
}
}

View file

@ -1,16 +1,45 @@
"""Sensor for Home Assistant analytics."""
from __future__ import annotations
from homeassistant.components.sensor import SensorEntity, SensorStateClass
from collections.abc import Callable
from dataclasses import dataclass
from homeassistant.components.sensor import (
SensorEntity,
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import AnalyticsData
from . import AnalyticsInsightsData
from .const import DOMAIN
from .coordinator import HomeassistantAnalyticsDataUpdateCoordinator
from .coordinator import AnalyticsData, HomeassistantAnalyticsDataUpdateCoordinator
@dataclass(frozen=True, kw_only=True)
class AnalyticsSensorEntityDescription(SensorEntityDescription):
"""Analytics sensor entity description."""
value_fn: Callable[[AnalyticsData], StateType]
def get_core_integration_entity_description(
domain: str, name: str
) -> AnalyticsSensorEntityDescription:
"""Get core integration entity description."""
return AnalyticsSensorEntityDescription(
key=f"core_{domain}_active_installations",
translation_key="core_integrations",
name=name,
state_class=SensorStateClass.TOTAL,
native_unit_of_measurement="active installations",
value_fn=lambda data: data.core_integrations.get(domain),
)
async def async_setup_entry(
@ -20,14 +49,15 @@ async def async_setup_entry(
) -> None:
"""Initialize the entries."""
analytics_data: AnalyticsData = hass.data[DOMAIN][entry.entry_id]
analytics_data: AnalyticsInsightsData = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
HomeassistantAnalyticsSensor(
analytics_data.coordinator,
integration_domain,
analytics_data.names[integration_domain],
get_core_integration_entity_description(
integration_domain, analytics_data.names[integration_domain]
),
)
for integration_domain in analytics_data.coordinator.data
for integration_domain in analytics_data.coordinator.data.core_integrations
)
@ -37,26 +67,24 @@ class HomeassistantAnalyticsSensor(
"""Home Assistant Analytics Sensor."""
_attr_has_entity_name = True
_attr_state_class = SensorStateClass.TOTAL
_attr_native_unit_of_measurement = "active installations"
entity_description: AnalyticsSensorEntityDescription
def __init__(
self,
coordinator: HomeassistantAnalyticsDataUpdateCoordinator,
integration_domain: str,
name: str,
entity_description: AnalyticsSensorEntityDescription,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self._attr_name = name
self._attr_unique_id = f"core_{integration_domain}_active_installations"
self.entity_description = entity_description
self._attr_unique_id = entity_description.key
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, DOMAIN)},
entry_type=DeviceEntryType.SERVICE,
)
self._integration_domain = integration_domain
@property
def native_value(self) -> int | None:
def native_value(self) -> StateType:
"""Return the state of the sensor."""
return self.coordinator.data.get(self._integration_domain)
return self.entity_description.value_fn(self.coordinator.data)

View file

@ -27,7 +27,7 @@
'platform': 'analytics_insights',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'translation_key': 'core_integrations',
'unique_id': 'core_myq_active_installations',
'unit_of_measurement': 'active installations',
})
@ -74,7 +74,7 @@
'platform': 'analytics_insights',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'translation_key': 'core_integrations',
'unique_id': 'core_spotify_active_installations',
'unit_of_measurement': 'active installations',
})
@ -121,7 +121,7 @@
'platform': 'analytics_insights',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'translation_key': 'core_integrations',
'unique_id': 'core_youtube_active_installations',
'unit_of_measurement': 'active installations',
})