From 9ad71711da016caceeb7ef6bd6dce04240cd2bb6 Mon Sep 17 00:00:00 2001 From: "A. Gideonse" Date: Sun, 8 Mar 2026 08:32:18 +0100 Subject: [PATCH] Add diagnostics to Indevolt integration (#165096) --- .../components/indevolt/diagnostics.py | 46 ++++++ .../components/indevolt/quality_scale.yaml | 3 +- .../indevolt/snapshots/test_diagnostics.ambr | 134 ++++++++++++++++++ tests/components/indevolt/test_diagnostics.py | 32 +++++ 4 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 homeassistant/components/indevolt/diagnostics.py create mode 100644 tests/components/indevolt/snapshots/test_diagnostics.ambr create mode 100644 tests/components/indevolt/test_diagnostics.py diff --git a/homeassistant/components/indevolt/diagnostics.py b/homeassistant/components/indevolt/diagnostics.py new file mode 100644 index 000000000000..fadc6e63403e --- /dev/null +++ b/homeassistant/components/indevolt/diagnostics.py @@ -0,0 +1,46 @@ +"""Diagnostics support for Indevolt integration.""" + +from __future__ import annotations + +from typing import Any + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.const import CONF_HOST +from homeassistant.core import HomeAssistant + +from .const import CONF_SERIAL_NUMBER +from .coordinator import IndevoltConfigEntry + +# Redact sensitive information from diagnostics (host and serial numbers) +TO_REDACT = { + CONF_HOST, + CONF_SERIAL_NUMBER, + "0", + "9008", + "9032", + "9051", + "9070", + "9218", + "9165", +} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: IndevoltConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + coordinator = entry.runtime_data + + device_info = { + "model": coordinator.device_model, + "generation": coordinator.generation, + "serial_number": coordinator.serial_number, + "firmware_version": coordinator.firmware_version, + } + + return { + "entry_data": async_redact_data(entry.data, TO_REDACT), + "device": async_redact_data(device_info, TO_REDACT), + "coordinator_data": async_redact_data(coordinator.data, TO_REDACT), + "last_update_success": coordinator.last_update_success, + } diff --git a/homeassistant/components/indevolt/quality_scale.yaml b/homeassistant/components/indevolt/quality_scale.yaml index c436beb43fe6..e1a9932efa82 100644 --- a/homeassistant/components/indevolt/quality_scale.yaml +++ b/homeassistant/components/indevolt/quality_scale.yaml @@ -45,8 +45,7 @@ rules: # Gold devices: done - diagnostics: - status: todo + diagnostics: done discovery-update-info: status: exempt comment: Integration does not support network discovery diff --git a/tests/components/indevolt/snapshots/test_diagnostics.ambr b/tests/components/indevolt/snapshots/test_diagnostics.ambr new file mode 100644 index 000000000000..8bd050520ce4 --- /dev/null +++ b/tests/components/indevolt/snapshots/test_diagnostics.ambr @@ -0,0 +1,134 @@ +# serializer version: 1 +# name: test_diagnostics[1] + dict({ + 'coordinator_data': dict({ + '0': '**REDACTED**', + '1501': 0, + '1502': 0, + '1505': 553673, + '1664': 0, + '1665': 0, + '2101': 0, + '21028': 0, + '2107': 58.1, + '2108': 0, + '6000': 0, + '6001': 1000, + '6002': 92, + '6004': 0, + '6005': 0, + '6006': 277.16, + '6007': 256.39, + '606': '1000', + '6105': 5, + '7101': 5, + '7120': 1001, + }), + 'device': dict({ + 'firmware_version': '1.2.3', + 'generation': 1, + 'model': 'BK1600', + 'serial_number': '**REDACTED**', + }), + 'entry_data': dict({ + 'generation': 1, + 'host': '**REDACTED**', + 'model': 'BK1600', + 'serial_number': '**REDACTED**', + }), + 'last_update_success': True, + }) +# --- +# name: test_diagnostics[2] + dict({ + 'coordinator_data': dict({ + '0': '**REDACTED**', + '11009': 50.2, + '11010': 52.3, + '11011': 85, + '11016': 0, + '11034': 100, + '142': 1.79, + '1501': 0, + '1502': 0, + '1532': 150, + '1600': 48.5, + '1601': 48.3, + '1602': 48.7, + '1603': 48.6, + '1632': 10.2, + '1633': 10.1, + '1634': 9.8, + '1635': 9.9, + '1664': 0, + '1665': 0, + '1666': 0, + '1667': 0, + '19173': 14.8, + '19174': 15.0, + '19175': 15.1, + '19176': 15.3, + '19177': 14.9, + '2101': 0, + '2104': 1500, + '2105': 2000, + '2107': 289.97, + '2108': 0, + '2600': 1200, + '2612': 50.0, + '2618': 1001, + '6000': 0, + '6001': 1000, + '6002': 92, + '6004': 0.07, + '6005': 0, + '6006': 380.58, + '6007': 338.07, + '606': '1001', + '6105': 5, + '667': 0, + '680': 0, + '7101': 1, + '7120': 1001, + '7171': 1, + '9000': 92, + '9004': 51.2, + '9008': '**REDACTED**', + '9012': 25.5, + '9013': 15.2, + '9016': 91, + '9020': 51.0, + '9030': 24.8, + '9032': '**REDACTED**', + '9035': 93, + '9039': 51.3, + '9049': 25.2, + '9051': '**REDACTED**', + '9054': 92, + '9058': 51.1, + '9068': 25.0, + '9070': '**REDACTED**', + '9149': 94, + '9153': 51.4, + '9163': 25.7, + '9165': '**REDACTED**', + '9202': 90, + '9206': 50.9, + '9216': 24.9, + '9218': '**REDACTED**', + }), + 'device': dict({ + 'firmware_version': '1.2.3', + 'generation': 2, + 'model': 'CMS-SF2000', + 'serial_number': '**REDACTED**', + }), + 'entry_data': dict({ + 'generation': 2, + 'host': '**REDACTED**', + 'model': 'CMS-SF2000', + 'serial_number': '**REDACTED**', + }), + 'last_update_success': True, + }) +# --- diff --git a/tests/components/indevolt/test_diagnostics.py b/tests/components/indevolt/test_diagnostics.py new file mode 100644 index 000000000000..256d11846f02 --- /dev/null +++ b/tests/components/indevolt/test_diagnostics.py @@ -0,0 +1,32 @@ +"""Tests for Indevolt diagnostics.""" + +from unittest.mock import AsyncMock + +import pytest +from syrupy.assertion import SnapshotAssertion + +from homeassistant.core import HomeAssistant + +from . import setup_integration + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +@pytest.mark.parametrize("generation", [1, 2], indirect=True) +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + mock_indevolt: AsyncMock, + mock_config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, +) -> None: + """Test diagnostics for all device generations.""" + await setup_integration(hass, mock_config_entry) + + # Verify the diagnostics for config entry can be retrieved and matches snapshot + assert ( + await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry) + == snapshot + )