Add missing device info to Husqvarna Automower (#113090)

* Add missing DeviceInfo to Husqvarna Automower

* add a test

* Adress review

* Update homeassistant/components/husqvarna_automower/entity.py

* fix url

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Thomas55555 2024-03-12 08:25:35 +01:00 committed by GitHub
parent 6f19744469
commit 4f4391bd09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 2 deletions

View File

@ -2,6 +2,5 @@
DOMAIN = "husqvarna_automower" DOMAIN = "husqvarna_automower"
NAME = "Husqvarna Automower" NAME = "Husqvarna Automower"
HUSQVARNA_URL = "https://developer.husqvarnagroup.cloud/login"
OAUTH2_AUTHORIZE = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/authorize" OAUTH2_AUTHORIZE = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/authorize"
OAUTH2_TOKEN = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/token" OAUTH2_TOKEN = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/token"

View File

@ -21,6 +21,8 @@ MAX_WS_RECONNECT_TIME = 600
class AutomowerDataUpdateCoordinator(DataUpdateCoordinator[dict[str, MowerAttributes]]): class AutomowerDataUpdateCoordinator(DataUpdateCoordinator[dict[str, MowerAttributes]]):
"""Class to manage fetching Husqvarna data.""" """Class to manage fetching Husqvarna data."""
config_entry: ConfigEntry
def __init__( def __init__(
self, hass: HomeAssistant, api: AutomowerSession, entry: ConfigEntry self, hass: HomeAssistant, api: AutomowerSession, entry: ConfigEntry
) -> None: ) -> None:

View File

@ -3,6 +3,7 @@
import logging import logging
from aioautomower.model import MowerAttributes from aioautomower.model import MowerAttributes
from aioautomower.utils import structure_token
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -12,6 +13,8 @@ from .const import DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
HUSQVARNA_URL = "https://developer.husqvarnagroup.cloud"
class AutomowerBaseEntity(CoordinatorEntity[AutomowerDataUpdateCoordinator]): class AutomowerBaseEntity(CoordinatorEntity[AutomowerDataUpdateCoordinator]):
"""Defining the Automower base Entity.""" """Defining the Automower base Entity."""
@ -26,11 +29,15 @@ class AutomowerBaseEntity(CoordinatorEntity[AutomowerDataUpdateCoordinator]):
"""Initialize AutomowerEntity.""" """Initialize AutomowerEntity."""
super().__init__(coordinator) super().__init__(coordinator)
self.mower_id = mower_id self.mower_id = mower_id
entry = coordinator.config_entry
structured_token = structure_token(entry.data["token"]["access_token"])
self._attr_device_info = DeviceInfo( self._attr_device_info = DeviceInfo(
configuration_url=f"{HUSQVARNA_URL}/applications/{structured_token.client_id}",
identifiers={(DOMAIN, mower_id)}, identifiers={(DOMAIN, mower_id)},
name=self.mower_attributes.system.name,
manufacturer="Husqvarna", manufacturer="Husqvarna",
model=self.mower_attributes.system.model, model=self.mower_attributes.system.model,
name=self.mower_attributes.system.name,
serial_number=self.mower_attributes.system.serial_number,
suggested_area="Garden", suggested_area="Garden",
) )

View File

@ -0,0 +1,31 @@
# serializer version: 1
# name: test_device_info
DeviceRegistryEntrySnapshot({
'area_id': 'garden',
'config_entries': <ANY>,
'configuration_url': 'https://developer.husqvarnagroup.cloud/applications/433e5fdf-5129-452c-xxxx-fadce3213042',
'connections': set({
}),
'disabled_by': None,
'entry_type': None,
'hw_version': None,
'id': <ANY>,
'identifiers': set({
tuple(
'husqvarna_automower',
'c7233734-b219-4287-a173-08e3643f89f0',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Husqvarna',
'model': '450XH-TEST',
'name': 'Test Mower 1',
'name_by_user': None,
'serial_number': 123,
'suggested_area': 'Garden',
'sw_version': None,
'via_device_id': None,
})
# ---

View File

@ -8,12 +8,15 @@ from unittest.mock import AsyncMock
from aioautomower.exceptions import ApiException, HusqvarnaWSServerHandshakeError from aioautomower.exceptions import ApiException, HusqvarnaWSServerHandshakeError
from freezegun.api import FrozenDateTimeFactory from freezegun.api import FrozenDateTimeFactory
import pytest import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.husqvarna_automower.const import DOMAIN, OAUTH2_TOKEN from homeassistant.components.husqvarna_automower.const import DOMAIN, OAUTH2_TOKEN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from . import setup_integration from . import setup_integration
from .const import TEST_MOWER_ID
from tests.common import MockConfigEntry, async_fire_time_changed from tests.common import MockConfigEntry, async_fire_time_changed
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
@ -109,3 +112,21 @@ async def test_websocket_not_available(
assert mock_automower_client.auth.websocket_connect.call_count == 2 assert mock_automower_client.auth.websocket_connect.call_count == 2
assert mock_automower_client.start_listening.call_count == 2 assert mock_automower_client.start_listening.call_count == 2
assert mock_config_entry.state == ConfigEntryState.LOADED assert mock_config_entry.state == ConfigEntryState.LOADED
async def test_device_info(
hass: HomeAssistant,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
device_registry: dr.DeviceRegistry,
snapshot: SnapshotAssertion,
) -> None:
"""Test select platform."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
reg_device = device_registry.async_get_device(
identifiers={(DOMAIN, TEST_MOWER_ID)},
)
assert reg_device == snapshot