mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Add diagnostics to Husqvarna Automower (#111857)
This commit is contained in:
parent
59c4c85089
commit
80c8b94021
46
homeassistant/components/husqvarna_automower/diagnostics.py
Normal file
46
homeassistant/components/husqvarna_automower/diagnostics.py
Normal file
@ -0,0 +1,46 @@
|
||||
"""Diagnostics support for Husqvarna Automower."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import AutomowerDataUpdateCoordinator
|
||||
|
||||
CONF_REFRESH_TOKEN = "refresh_token"
|
||||
POSITIONS = "positions"
|
||||
|
||||
TO_REDACT = {
|
||||
CONF_ACCESS_TOKEN,
|
||||
CONF_REFRESH_TOKEN,
|
||||
POSITIONS,
|
||||
}
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
return async_redact_data(entry.as_dict(), TO_REDACT)
|
||||
|
||||
|
||||
async def async_get_device_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry, device: DeviceEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a device entry."""
|
||||
coordinator: AutomowerDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
for identifier in device.identifiers:
|
||||
if identifier[0] == DOMAIN:
|
||||
if (
|
||||
coordinator.data[identifier[1]].system.serial_number
|
||||
== device.serial_number
|
||||
):
|
||||
mower_id = identifier[1]
|
||||
return async_redact_data(coordinator.data[mower_id].to_dict(), TO_REDACT)
|
@ -0,0 +1,129 @@
|
||||
# serializer version: 1
|
||||
# name: test_device_diagnostics
|
||||
dict({
|
||||
'battery': dict({
|
||||
'battery_percent': 100,
|
||||
}),
|
||||
'calendar': dict({
|
||||
'tasks': list([
|
||||
dict({
|
||||
'duration': 300,
|
||||
'friday': True,
|
||||
'monday': True,
|
||||
'saturday': False,
|
||||
'start': 1140,
|
||||
'sunday': False,
|
||||
'thursday': False,
|
||||
'tuesday': False,
|
||||
'wednesday': True,
|
||||
'work_area_id': None,
|
||||
}),
|
||||
dict({
|
||||
'duration': 480,
|
||||
'friday': False,
|
||||
'monday': False,
|
||||
'saturday': True,
|
||||
'start': 0,
|
||||
'sunday': False,
|
||||
'thursday': True,
|
||||
'tuesday': True,
|
||||
'wednesday': False,
|
||||
'work_area_id': None,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
'capabilities': dict({
|
||||
'headlights': True,
|
||||
'position': True,
|
||||
'stay_out_zones': False,
|
||||
'work_areas': False,
|
||||
}),
|
||||
'cutting_height': 4,
|
||||
'headlight': dict({
|
||||
'mode': 'EVENING_ONLY',
|
||||
}),
|
||||
'metadata': dict({
|
||||
'connected': True,
|
||||
'status_dateteime': '2023-10-18T22:58:52.683000+00:00',
|
||||
}),
|
||||
'mower': dict({
|
||||
'activity': 'PARKED_IN_CS',
|
||||
'error_code': 0,
|
||||
'error_dateteime': None,
|
||||
'error_key': None,
|
||||
'mode': 'MAIN_AREA',
|
||||
'state': 'RESTRICTED',
|
||||
}),
|
||||
'planner': dict({
|
||||
'next_start_dateteime': '2023-06-05T19:00:00+00:00',
|
||||
'override': dict({
|
||||
'action': 'NOT_ACTIVE',
|
||||
}),
|
||||
'restricted_reason': 'WEEK_SCHEDULE',
|
||||
}),
|
||||
'positions': '**REDACTED**',
|
||||
'statistics': dict({
|
||||
'cutting_blade_usage_time': 123,
|
||||
'number_of_charging_cycles': 1380,
|
||||
'number_of_collisions': 11396,
|
||||
'total_charging_time': 4334400,
|
||||
'total_cutting_time': 4194000,
|
||||
'total_drive_distance': 1780272,
|
||||
'total_running_time': 4564800,
|
||||
'total_searching_time': 370800,
|
||||
}),
|
||||
'stay_out_zones': dict({
|
||||
'dirty': False,
|
||||
'zones': dict({
|
||||
'81C6EEA2-D139-4FEA-B134-F22A6B3EA403': dict({
|
||||
'enabled': True,
|
||||
'name': 'Springflowers',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'system': dict({
|
||||
'model': '450XH-TEST',
|
||||
'name': 'Test Mower 1',
|
||||
'serial_number': 123,
|
||||
}),
|
||||
'work_areas': dict({
|
||||
'0': dict({
|
||||
'cutting_height': 50,
|
||||
'name': None,
|
||||
}),
|
||||
'123456': dict({
|
||||
'cutting_height': 50,
|
||||
'name': 'Front lawn',
|
||||
}),
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_entry_diagnostics
|
||||
dict({
|
||||
'data': dict({
|
||||
'auth_implementation': 'husqvarna_automower',
|
||||
'token': dict({
|
||||
'access_token': '**REDACTED**',
|
||||
'expires_at': 1709208000.0,
|
||||
'expires_in': 86399,
|
||||
'provider': 'husqvarna',
|
||||
'refresh_token': '**REDACTED**',
|
||||
'scope': 'iam:read amc:api',
|
||||
'token_type': 'Bearer',
|
||||
'user_id': '123',
|
||||
}),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'domain': 'husqvarna_automower',
|
||||
'entry_id': 'automower_test',
|
||||
'minor_version': 1,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Husqvarna Automower of Erika Mustermann',
|
||||
'unique_id': '123',
|
||||
'version': 1,
|
||||
})
|
||||
# ---
|
61
tests/components/husqvarna_automower/test_diagnostics.py
Normal file
61
tests/components/husqvarna_automower/test_diagnostics.py
Normal file
@ -0,0 +1,61 @@
|
||||
"""Test the Husqvarna Automower Diagnostics."""
|
||||
import datetime
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.husqvarna_automower.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from .const import TEST_MOWER_ID
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import (
|
||||
get_diagnostics_for_config_entry,
|
||||
get_diagnostics_for_device,
|
||||
)
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
@pytest.mark.freeze_time(datetime.datetime(2024, 2, 29, 11, tzinfo=datetime.UTC))
|
||||
async def test_entry_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_automower_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test config entry diagnostics."""
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
result = await get_diagnostics_for_config_entry(
|
||||
hass, hass_client, mock_config_entry
|
||||
)
|
||||
assert result == snapshot
|
||||
|
||||
|
||||
async def test_device_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_automower_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> 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 is not None
|
||||
result = await get_diagnostics_for_device(
|
||||
hass, hass_client, mock_config_entry, reg_device
|
||||
)
|
||||
assert result == snapshot
|
Loading…
x
Reference in New Issue
Block a user