Add diagnostics to Husqvarna Automower (#111857)

This commit is contained in:
Thomas55555 2024-03-21 10:06:40 +01:00 committed by GitHub
parent 59c4c85089
commit 80c8b94021
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 236 additions and 0 deletions

View 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)

View File

@ -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,
})
# ---

View 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