Add mealie version to device info (#121443)

pull/120824/head
Joost Lekkerkerker 2024-07-07 17:13:15 +02:00 committed by GitHub
parent 67facdf3a5
commit 1fefd396b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 46 additions and 25 deletions

View File

@ -2,22 +2,45 @@
from __future__ import annotations from __future__ import annotations
from homeassistant.config_entries import ConfigEntry from aiomealie import MealieAuthenticationError, MealieClient, MealieConnectionError
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from .coordinator import MealieCoordinator from homeassistant.const import CONF_API_TOKEN, CONF_HOST, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.device_registry import DeviceEntryType
from .const import DOMAIN
from .coordinator import MealieConfigEntry, MealieCoordinator
PLATFORMS: list[Platform] = [Platform.CALENDAR] PLATFORMS: list[Platform] = [Platform.CALENDAR]
type MealieConfigEntry = ConfigEntry[MealieCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: MealieConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: MealieConfigEntry) -> bool:
"""Set up Mealie from a config entry.""" """Set up Mealie from a config entry."""
client = MealieClient(
entry.data[CONF_HOST],
token=entry.data[CONF_API_TOKEN],
session=async_get_clientsession(hass),
)
try:
about = await client.get_about()
except MealieAuthenticationError as error:
raise ConfigEntryError("Authentication failed") from error
except MealieConnectionError as error:
raise ConfigEntryNotReady(error) from error
coordinator = MealieCoordinator(hass) assert entry.unique_id
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, entry.unique_id)},
entry_type=DeviceEntryType.SERVICE,
sw_version=about.version,
)
coordinator = MealieCoordinator(hass, client)
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()

View File

@ -3,7 +3,6 @@
from __future__ import annotations from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from typing import TYPE_CHECKING
from aiomealie import ( from aiomealie import (
MealieAuthenticationError, MealieAuthenticationError,
@ -13,36 +12,30 @@ from aiomealie import (
MealplanEntryType, MealplanEntryType,
) )
from homeassistant.const import CONF_API_TOKEN, CONF_HOST from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError from homeassistant.exceptions import ConfigEntryError
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from .const import LOGGER from .const import LOGGER
if TYPE_CHECKING:
from . import MealieConfigEntry
WEEK = timedelta(days=7) WEEK = timedelta(days=7)
type MealieConfigEntry = ConfigEntry[MealieCoordinator]
class MealieCoordinator(DataUpdateCoordinator[dict[MealplanEntryType, list[Mealplan]]]): class MealieCoordinator(DataUpdateCoordinator[dict[MealplanEntryType, list[Mealplan]]]):
"""Class to manage fetching Mealie data.""" """Class to manage fetching Mealie data."""
config_entry: MealieConfigEntry config_entry: MealieConfigEntry
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant, client: MealieClient) -> None:
"""Initialize coordinator.""" """Initialize coordinator."""
super().__init__( super().__init__(
hass, logger=LOGGER, name="Mealie", update_interval=timedelta(hours=1) hass, logger=LOGGER, name="Mealie", update_interval=timedelta(hours=1)
) )
self.client = MealieClient( self.client = client
self.config_entry.data[CONF_HOST],
token=self.config_entry.data[CONF_API_TOKEN],
session=async_get_clientsession(hass),
)
async def _async_update_data(self) -> dict[MealplanEntryType, list[Mealplan]]: async def _async_update_data(self) -> dict[MealplanEntryType, list[Mealplan]]:
next_week = dt_util.now() + WEEK next_week = dt_util.now() + WEEK

View File

@ -1,6 +1,6 @@
"""Base class for Mealie entities.""" """Base class for Mealie entities."""
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import DOMAIN
@ -20,5 +20,4 @@ class MealieEntity(CoordinatorEntity[MealieCoordinator]):
self._attr_unique_id = f"{unique_id}_{key}" self._attr_unique_id = f"{unique_id}_{key}"
self._attr_device_info = DeviceInfo( self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, unique_id)}, identifiers={(DOMAIN, unique_id)},
entry_type=DeviceEntryType.SERVICE,
) )

View File

@ -3,7 +3,7 @@
from collections.abc import Generator from collections.abc import Generator
from unittest.mock import patch from unittest.mock import patch
from aiomealie import Mealplan, MealplanResponse, UserInfo from aiomealie import About, Mealplan, MealplanResponse, UserInfo
from mashumaro.codecs.orjson import ORJSONDecoder from mashumaro.codecs.orjson import ORJSONDecoder
import pytest import pytest
@ -29,7 +29,7 @@ def mock_mealie_client() -> Generator[AsyncMock]:
"""Mock a Mealie client.""" """Mock a Mealie client."""
with ( with (
patch( patch(
"homeassistant.components.mealie.coordinator.MealieClient", "homeassistant.components.mealie.MealieClient",
autospec=True, autospec=True,
) as mock_client, ) as mock_client,
patch( patch(
@ -47,6 +47,9 @@ def mock_mealie_client() -> Generator[AsyncMock]:
client.get_user_info.return_value = UserInfo.from_json( client.get_user_info.return_value = UserInfo.from_json(
load_fixture("users_self.json", DOMAIN) load_fixture("users_self.json", DOMAIN)
) )
client.get_about.return_value = About.from_json(
load_fixture("about.json", DOMAIN)
)
yield client yield client

View File

@ -0,0 +1,3 @@
{
"version": "v1.10.2"
}

View File

@ -26,7 +26,7 @@
'primary_config_entry': <ANY>, 'primary_config_entry': <ANY>,
'serial_number': None, 'serial_number': None,
'suggested_area': None, 'suggested_area': None,
'sw_version': None, 'sw_version': 'v1.10.2',
'via_device_id': None, 'via_device_id': None,
}) })
# --- # ---