mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 08:17: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