From ba7f82d5e2ac30edfacab53a250faf76f38fd25c Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Wed, 5 Jun 2024 07:55:49 +0100 Subject: [PATCH] Add diagnostic to V2C (#118823) * add diagnostic platform * add diagnostic platform * add diagnostic platform --- homeassistant/components/v2c/diagnostics.py | 35 +++++++++++++++++++ tests/components/v2c/conftest.py | 6 ++++ .../v2c/snapshots/test_diagnostics.ambr | 25 +++++++++++++ tests/components/v2c/test_diagnostics.py | 30 ++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 homeassistant/components/v2c/diagnostics.py create mode 100644 tests/components/v2c/snapshots/test_diagnostics.ambr create mode 100644 tests/components/v2c/test_diagnostics.py diff --git a/homeassistant/components/v2c/diagnostics.py b/homeassistant/components/v2c/diagnostics.py new file mode 100644 index 00000000000..9f9df8723e0 --- /dev/null +++ b/homeassistant/components/v2c/diagnostics.py @@ -0,0 +1,35 @@ +"""Diagnostics support for V2C.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_HOST +from homeassistant.core import HomeAssistant + +from .const import DOMAIN +from .coordinator import V2CUpdateCoordinator + +TO_REDACT = {CONF_HOST, "title"} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: ConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + coordinator: V2CUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + if TYPE_CHECKING: + assert coordinator.evse + + coordinator_data = coordinator.evse.data + evse_raw_data = coordinator.evse.raw_data + + return { + "config_entry": async_redact_data(entry.as_dict(), TO_REDACT), + "data": str(coordinator_data), + "raw_data": evse_raw_data["content"].decode("utf-8"), # type: ignore[attr-defined] + "host_status": evse_raw_data["status_code"], + } diff --git a/tests/components/v2c/conftest.py b/tests/components/v2c/conftest.py index 87c11a3ceef..5dc8d96aab4 100644 --- a/tests/components/v2c/conftest.py +++ b/tests/components/v2c/conftest.py @@ -8,6 +8,7 @@ from pytrydan.models.trydan import TrydanData from homeassistant.components.v2c import DOMAIN from homeassistant.const import CONF_HOST +from homeassistant.helpers.json import json_dumps from tests.common import MockConfigEntry, load_json_object_fixture @@ -47,6 +48,11 @@ def mock_v2c_client() -> Generator[AsyncMock, None, None]: ): client = mock_client.return_value get_data_json = load_json_object_fixture("get_data.json", DOMAIN) + client.raw_data = { + "content": json_dumps(get_data_json).encode("utf-8"), + "status_code": 200, + } client.get_data.return_value = TrydanData.from_api(get_data_json) + client.data = client.get_data.return_value client.firmware_version = get_data_json["FirmwareVersion"] yield client diff --git a/tests/components/v2c/snapshots/test_diagnostics.ambr b/tests/components/v2c/snapshots/test_diagnostics.ambr new file mode 100644 index 00000000000..a4f6cad4cc8 --- /dev/null +++ b/tests/components/v2c/snapshots/test_diagnostics.ambr @@ -0,0 +1,25 @@ +# serializer version: 1 +# name: test_entry_diagnostics + dict({ + 'config_entry': dict({ + 'data': dict({ + 'host': '**REDACTED**', + }), + 'disabled_by': None, + 'domain': 'v2c', + 'entry_id': 'da58ee91f38c2406c2a36d0a1a7f8569', + 'minor_version': 1, + 'options': dict({ + }), + 'pref_disable_new_entities': False, + 'pref_disable_polling': False, + 'source': 'user', + 'title': '**REDACTED**', + 'unique_id': 'ABC123', + 'version': 1, + }), + 'data': "TrydanData(ID='ABC123', charge_state=, ready_state=, charge_power=1500.27, charge_energy=1.8, slave_error=, charge_time=4355, house_power=0.0, fv_power=0.0, battery_power=0.0, paused=, locked=, timer=, intensity=6, dynamic=, min_intensity=6, max_intensity=16, pause_dynamic=, dynamic_power_mode=, contracted_power=4600, firmware_version='2.1.7')", + 'host_status': 200, + 'raw_data': '{"ID":"ABC123","ChargeState":2,"ReadyState":0,"ChargePower":1500.27,"ChargeEnergy":1.8,"SlaveError":4,"ChargeTime":4355,"HousePower":0.0,"FVPower":0.0,"BatteryPower":0.0,"Paused":0,"Locked":0,"Timer":0,"Intensity":6,"Dynamic":0,"MinIntensity":6,"MaxIntensity":16,"PauseDynamic":0,"FirmwareVersion":"2.1.7","DynamicPowerMode":2,"ContractedPower":4600}', + }) +# --- diff --git a/tests/components/v2c/test_diagnostics.py b/tests/components/v2c/test_diagnostics.py new file mode 100644 index 00000000000..770b00e988b --- /dev/null +++ b/tests/components/v2c/test_diagnostics.py @@ -0,0 +1,30 @@ +"""Test V2C diagnostics.""" + +from unittest.mock import AsyncMock + +from syrupy import SnapshotAssertion + +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant + +from . import init_integration + +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +async def test_entry_diagnostics( + hass: HomeAssistant, + mock_config_entry: ConfigEntry, + mock_v2c_client: AsyncMock, + hass_client: ClientSessionGenerator, + snapshot: SnapshotAssertion, +) -> None: + """Test config entry diagnostics.""" + + await init_integration(hass, mock_config_entry) + + assert ( + await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry) + == snapshot() + )