From 3b2b2b9c69ef355e0e2fde6963a3c162fecf8187 Mon Sep 17 00:00:00 2001 From: stegm Date: Sat, 26 Feb 2022 22:32:38 +0100 Subject: [PATCH] Add diagnostics to Kostal Plenticore (#66435) --- .../kostal_plenticore/diagnostics.py | 42 ++++++++ .../components/kostal_plenticore/conftest.py | 96 +++++++++++++++++++ .../kostal_plenticore/test_diagnostics.py | 49 ++++++++++ 3 files changed, 187 insertions(+) create mode 100644 homeassistant/components/kostal_plenticore/diagnostics.py create mode 100644 tests/components/kostal_plenticore/conftest.py create mode 100644 tests/components/kostal_plenticore/test_diagnostics.py diff --git a/homeassistant/components/kostal_plenticore/diagnostics.py b/homeassistant/components/kostal_plenticore/diagnostics.py new file mode 100644 index 00000000000..2e061d35528 --- /dev/null +++ b/homeassistant/components/kostal_plenticore/diagnostics.py @@ -0,0 +1,42 @@ +"""Diagnostics support for Kostal Plenticore.""" +from __future__ import annotations + +from typing import Any + +from homeassistant.components.diagnostics import REDACTED, async_redact_data +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_PASSWORD +from homeassistant.core import HomeAssistant + +from .const import DOMAIN +from .helper import Plenticore + +TO_REDACT = {CONF_PASSWORD} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, config_entry: ConfigEntry +) -> dict[str, dict[str, Any]]: + """Return diagnostics for a config entry.""" + data = {"config_entry": async_redact_data(config_entry.as_dict(), TO_REDACT)} + + plenticore: Plenticore = hass.data[DOMAIN][config_entry.entry_id] + + # Get information from Kostal Plenticore library + available_process_data = await plenticore.client.get_process_data() + available_settings_data = await plenticore.client.get_settings() + data["client"] = { + "version": str(await plenticore.client.get_version()), + "me": str(await plenticore.client.get_me()), + "available_process_data": available_process_data, + "available_settings_data": { + module_id: [str(setting) for setting in settings] + for module_id, settings in available_settings_data.items() + }, + } + + device_info = {**plenticore.device_info} + device_info["identifiers"] = REDACTED # contains serial number + data["device"] = device_info + + return data diff --git a/tests/components/kostal_plenticore/conftest.py b/tests/components/kostal_plenticore/conftest.py new file mode 100644 index 00000000000..c3ed1b45592 --- /dev/null +++ b/tests/components/kostal_plenticore/conftest.py @@ -0,0 +1,96 @@ +"""Fixtures for Kostal Plenticore tests.""" +from __future__ import annotations + +from collections.abc import Generator +from unittest.mock import AsyncMock, MagicMock, patch + +from kostal.plenticore import MeData, SettingsData, VersionData +import pytest + +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity import DeviceInfo + +from tests.common import MockConfigEntry + + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, +) -> Generator[None, MockConfigEntry, None]: + """Set up Kostal Plenticore integration for testing.""" + with patch( + "homeassistant.components.kostal_plenticore.Plenticore", autospec=True + ) as mock_api_class: + # setup + plenticore = mock_api_class.return_value + plenticore.async_setup = AsyncMock() + plenticore.async_setup.return_value = True + + plenticore.device_info = DeviceInfo( + configuration_url="http://192.168.1.2", + identifiers={("kostal_plenticore", "12345")}, + manufacturer="Kostal", + model="PLENTICORE plus 10", + name="scb", + sw_version="IOC: 01.45 MC: 01.46", + ) + + plenticore.client = MagicMock() + + plenticore.client.get_version = AsyncMock() + plenticore.client.get_version.return_value = VersionData( + { + "api_version": "0.2.0", + "hostname": "scb", + "name": "PUCK RESTful API", + "sw_version": "01.16.05025", + } + ) + + plenticore.client.get_me = AsyncMock() + plenticore.client.get_me.return_value = MeData( + { + "locked": False, + "active": True, + "authenticated": True, + "permissions": [], + "anonymous": False, + "role": "USER", + } + ) + + plenticore.client.get_process_data = AsyncMock() + plenticore.client.get_process_data.return_value = { + "devices:local": ["HomeGrid_P", "HomePv_P"] + } + + plenticore.client.get_settings = AsyncMock() + plenticore.client.get_settings.return_value = { + "devices:local": [ + SettingsData( + { + "id": "Battery:MinSoc", + "unit": "%", + "default": "None", + "min": 5, + "max": 100, + "type": "byte", + "access": "readwrite", + } + ) + ] + } + + mock_config_entry = MockConfigEntry( + entry_id="2ab8dd92a62787ddfe213a67e09406bd", + title="scb", + domain="kostal_plenticore", + data={"host": "192.168.1.2", "password": "SecretPassword"}, + ) + + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + yield mock_config_entry diff --git a/tests/components/kostal_plenticore/test_diagnostics.py b/tests/components/kostal_plenticore/test_diagnostics.py new file mode 100644 index 00000000000..56af8bafe06 --- /dev/null +++ b/tests/components/kostal_plenticore/test_diagnostics.py @@ -0,0 +1,49 @@ +"""Test Kostal Plenticore diagnostics.""" +from aiohttp import ClientSession + +from homeassistant.components.diagnostics import REDACTED +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry + + +async def test_entry_diagnostics( + hass: HomeAssistant, hass_client: ClientSession, init_integration: MockConfigEntry +): + """Test config entry diagnostics.""" + assert await get_diagnostics_for_config_entry( + hass, hass_client, init_integration + ) == { + "config_entry": { + "entry_id": "2ab8dd92a62787ddfe213a67e09406bd", + "version": 1, + "domain": "kostal_plenticore", + "title": "scb", + "data": {"host": "192.168.1.2", "password": REDACTED}, + "options": {}, + "pref_disable_new_entities": False, + "pref_disable_polling": False, + "source": "user", + "unique_id": None, + "disabled_by": None, + }, + "client": { + "version": "Version(api_version=0.2.0, hostname=scb, name=PUCK RESTful API, sw_version=01.16.05025)", + "me": "Me(locked=False, active=True, authenticated=True, permissions=[] anonymous=False role=USER)", + "available_process_data": {"devices:local": ["HomeGrid_P", "HomePv_P"]}, + "available_settings_data": { + "devices:local": [ + "SettingsData(id=Battery:MinSoc, unit=%, default=None, min=5, max=100,type=byte, access=readwrite)" + ] + }, + }, + "device": { + "configuration_url": "http://192.168.1.2", + "identifiers": "**REDACTED**", + "manufacturer": "Kostal", + "model": "PLENTICORE plus 10", + "name": "scb", + "sw_version": "IOC: 01.45 MC: 01.46", + }, + }