Bump pykoplenti to 1.0.0 (#83251)

* Update Kostal integration to use maintained lib

* Update Kostal integration to use pykoplenti

* Update kostal_plenticore tests for new lib

* Fix tests config_flow & diagnostics after changes
This commit is contained in:
Jussi Rosenberg 2023-01-16 13:54:29 +02:00 committed by GitHub
parent c26d620ab1
commit 54d570a9cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 43 additions and 49 deletions

View File

@ -1,7 +1,7 @@
"""The Kostal Plenticore Solar Inverter integration.""" """The Kostal Plenticore Solar Inverter integration."""
import logging import logging
from kostal.plenticore import PlenticoreApiException from pykoplenti import ApiException
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform from homeassistant.const import Platform
@ -39,7 +39,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
plenticore = hass.data[DOMAIN].pop(entry.entry_id) plenticore = hass.data[DOMAIN].pop(entry.entry_id)
try: try:
await plenticore.async_unload() await plenticore.async_unload()
except PlenticoreApiException as err: except ApiException as err:
_LOGGER.error("Error logging out from inverter: %s", err) _LOGGER.error("Error logging out from inverter: %s", err)
return unload_ok return unload_ok

View File

@ -3,7 +3,7 @@ import asyncio
import logging import logging
from aiohttp.client_exceptions import ClientError from aiohttp.client_exceptions import ClientError
from kostal.plenticore import PlenticoreApiClient, PlenticoreAuthenticationException from pykoplenti import ApiClient, AuthenticationException
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
@ -30,7 +30,7 @@ async def test_connection(hass: HomeAssistant, data) -> str:
""" """
session = async_get_clientsession(hass) session = async_get_clientsession(hass)
async with PlenticoreApiClient(session, data["host"]) as client: async with ApiClient(session, data["host"]) as client:
await client.login(data["password"]) await client.login(data["password"])
values = await client.get_setting_values("scb:network", "Hostname") values = await client.get_setting_values("scb:network", "Hostname")
@ -52,7 +52,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
try: try:
hostname = await test_connection(self.hass, user_input) hostname = await test_connection(self.hass, user_input)
except PlenticoreAuthenticationException as ex: except AuthenticationException as ex:
errors[CONF_PASSWORD] = "invalid_auth" errors[CONF_PASSWORD] = "invalid_auth"
_LOGGER.error("Error response: %s", ex) _LOGGER.error("Error response: %s", ex)
except (ClientError, asyncio.TimeoutError): except (ClientError, asyncio.TimeoutError):

View File

@ -9,11 +9,7 @@ import logging
from typing import Any, TypeVar, cast from typing import Any, TypeVar, cast
from aiohttp.client_exceptions import ClientError from aiohttp.client_exceptions import ClientError
from kostal.plenticore import ( from pykoplenti import ApiClient, ApiException, AuthenticationException
PlenticoreApiClient,
PlenticoreApiException,
PlenticoreAuthenticationException,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP from homeassistant.const import CONF_HOST, CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -48,18 +44,16 @@ class Plenticore:
return self.config_entry.data[CONF_HOST] return self.config_entry.data[CONF_HOST]
@property @property
def client(self) -> PlenticoreApiClient: def client(self) -> ApiClient:
"""Return the Plenticore API client.""" """Return the Plenticore API client."""
return self._client return self._client
async def async_setup(self) -> bool: async def async_setup(self) -> bool:
"""Set up Plenticore API client.""" """Set up Plenticore API client."""
self._client = PlenticoreApiClient( self._client = ApiClient(async_get_clientsession(self.hass), host=self.host)
async_get_clientsession(self.hass), host=self.host
)
try: try:
await self._client.login(self.config_entry.data[CONF_PASSWORD]) await self._client.login(self.config_entry.data[CONF_PASSWORD])
except PlenticoreAuthenticationException as err: except AuthenticationException as err:
_LOGGER.error( _LOGGER.error(
"Authentication exception connecting to %s: %s", self.host, err "Authentication exception connecting to %s: %s", self.host, err
) )
@ -135,7 +129,7 @@ class DataUpdateCoordinatorMixin:
try: try:
return await client.get_setting_values(module_id, data_id) return await client.get_setting_values(module_id, data_id)
except PlenticoreApiException: except ApiException:
return None return None
async def async_write_data(self, module_id: str, value: dict[str, str]) -> bool: async def async_write_data(self, module_id: str, value: dict[str, str]) -> bool:
@ -149,7 +143,7 @@ class DataUpdateCoordinatorMixin:
try: try:
await client.set_setting_values(module_id, value) await client.set_setting_values(module_id, value)
except PlenticoreApiException: except ApiException:
return False return False
else: else:
return True return True

View File

@ -3,7 +3,7 @@
"name": "Kostal Plenticore Solar Inverter", "name": "Kostal Plenticore Solar Inverter",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/kostal_plenticore", "documentation": "https://www.home-assistant.io/integrations/kostal_plenticore",
"requirements": ["kostal_plenticore==0.2.0"], "requirements": ["pykoplenti==1.0.0"],
"codeowners": ["@stegm"], "codeowners": ["@stegm"],
"iot_class": "local_polling", "iot_class": "local_polling",
"loggers": ["kostal"] "loggers": ["kostal"]

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
import logging import logging
from kostal.plenticore import SettingsData from pykoplenti import SettingsData
from homeassistant.components.number import ( from homeassistant.components.number import (
NumberDeviceClass, NumberDeviceClass,

View File

@ -1017,9 +1017,6 @@ kiwiki-client==0.1.1
# homeassistant.components.konnected # homeassistant.components.konnected
konnected==1.2.0 konnected==1.2.0
# homeassistant.components.kostal_plenticore
kostal_plenticore==0.2.0
# homeassistant.components.kraken # homeassistant.components.kraken
krakenex==2.1.0 krakenex==2.1.0
@ -1713,6 +1710,9 @@ pykmtronic==0.3.0
# homeassistant.components.kodi # homeassistant.components.kodi
pykodi==0.2.7 pykodi==0.2.7
# homeassistant.components.kostal_plenticore
pykoplenti==1.0.0
# homeassistant.components.kraken # homeassistant.components.kraken
pykrakenapi==0.1.8 pykrakenapi==0.1.8

View File

@ -764,9 +764,6 @@ kegtron-ble==0.4.0
# homeassistant.components.konnected # homeassistant.components.konnected
konnected==1.2.0 konnected==1.2.0
# homeassistant.components.kostal_plenticore
kostal_plenticore==0.2.0
# homeassistant.components.kraken # homeassistant.components.kraken
krakenex==2.1.0 krakenex==2.1.0
@ -1229,6 +1226,9 @@ pykmtronic==0.3.0
# homeassistant.components.kodi # homeassistant.components.kodi
pykodi==0.2.7 pykodi==0.2.7
# homeassistant.components.kostal_plenticore
pykoplenti==1.0.0
# homeassistant.components.kraken # homeassistant.components.kraken
pykrakenapi==0.1.8 pykrakenapi==0.1.8

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from collections.abc import Generator from collections.abc import Generator
from unittest.mock import AsyncMock, MagicMock, patch from unittest.mock import AsyncMock, MagicMock, patch
from kostal.plenticore import MeData, VersionData from pykoplenti import MeData, VersionData
import pytest import pytest
from homeassistant.components.kostal_plenticore.helper import Plenticore from homeassistant.components.kostal_plenticore.helper import Plenticore

View File

@ -2,7 +2,7 @@
import asyncio import asyncio
from unittest.mock import ANY, AsyncMock, MagicMock, patch from unittest.mock import ANY, AsyncMock, MagicMock, patch
from kostal.plenticore import PlenticoreAuthenticationException from pykoplenti import AuthenticationException
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.kostal_plenticore.const import DOMAIN from homeassistant.components.kostal_plenticore.const import DOMAIN
@ -20,7 +20,7 @@ async def test_formx(hass):
assert result["errors"] == {} assert result["errors"] == {}
with patch( with patch(
"homeassistant.components.kostal_plenticore.config_flow.PlenticoreApiClient" "homeassistant.components.kostal_plenticore.config_flow.ApiClient"
) as mock_api_class, patch( ) as mock_api_class, patch(
"homeassistant.components.kostal_plenticore.async_setup_entry", "homeassistant.components.kostal_plenticore.async_setup_entry",
return_value=True, return_value=True,
@ -32,7 +32,7 @@ async def test_formx(hass):
return_value={"scb:network": {"Hostname": "scb"}} return_value={"scb:network": {"Hostname": "scb"}}
) )
# mock of the return instance of PlenticoreApiClient # mock of the return instance of ApiClient
mock_api = MagicMock() mock_api = MagicMock()
mock_api.__aenter__.return_value = mock_api_ctx mock_api.__aenter__.return_value = mock_api_ctx
mock_api.__aexit__ = AsyncMock() mock_api.__aexit__ = AsyncMock()
@ -70,15 +70,15 @@ async def test_form_invalid_auth(hass):
) )
with patch( with patch(
"homeassistant.components.kostal_plenticore.config_flow.PlenticoreApiClient" "homeassistant.components.kostal_plenticore.config_flow.ApiClient"
) as mock_api_class: ) as mock_api_class:
# mock of the context manager instance # mock of the context manager instance
mock_api_ctx = MagicMock() mock_api_ctx = MagicMock()
mock_api_ctx.login = AsyncMock( mock_api_ctx.login = AsyncMock(
side_effect=PlenticoreAuthenticationException(404, "invalid user"), side_effect=AuthenticationException(404, "invalid user"),
) )
# mock of the return instance of PlenticoreApiClient # mock of the return instance of ApiClient
mock_api = MagicMock() mock_api = MagicMock()
mock_api.__aenter__.return_value = mock_api_ctx mock_api.__aenter__.return_value = mock_api_ctx
mock_api.__aexit__.return_value = None mock_api.__aexit__.return_value = None
@ -104,7 +104,7 @@ async def test_form_cannot_connect(hass):
) )
with patch( with patch(
"homeassistant.components.kostal_plenticore.config_flow.PlenticoreApiClient" "homeassistant.components.kostal_plenticore.config_flow.ApiClient"
) as mock_api_class: ) as mock_api_class:
# mock of the context manager instance # mock of the context manager instance
mock_api_ctx = MagicMock() mock_api_ctx = MagicMock()
@ -112,7 +112,7 @@ async def test_form_cannot_connect(hass):
side_effect=asyncio.TimeoutError(), side_effect=asyncio.TimeoutError(),
) )
# mock of the return instance of PlenticoreApiClient # mock of the return instance of ApiClient
mock_api = MagicMock() mock_api = MagicMock()
mock_api.__aenter__.return_value = mock_api_ctx mock_api.__aenter__.return_value = mock_api_ctx
mock_api.__aexit__.return_value = None mock_api.__aexit__.return_value = None
@ -138,7 +138,7 @@ async def test_form_unexpected_error(hass):
) )
with patch( with patch(
"homeassistant.components.kostal_plenticore.config_flow.PlenticoreApiClient" "homeassistant.components.kostal_plenticore.config_flow.ApiClient"
) as mock_api_class: ) as mock_api_class:
# mock of the context manager instance # mock of the context manager instance
mock_api_ctx = MagicMock() mock_api_ctx = MagicMock()
@ -146,7 +146,7 @@ async def test_form_unexpected_error(hass):
side_effect=Exception(), side_effect=Exception(),
) )
# mock of the return instance of PlenticoreApiClient # mock of the return instance of ApiClient
mock_api = MagicMock() mock_api = MagicMock()
mock_api.__aenter__.return_value = mock_api_ctx mock_api.__aenter__.return_value = mock_api_ctx
mock_api.__aexit__.return_value = None mock_api.__aexit__.return_value = None

View File

@ -1,6 +1,6 @@
"""Test Kostal Plenticore diagnostics.""" """Test Kostal Plenticore diagnostics."""
from aiohttp import ClientSession from aiohttp import ClientSession
from kostal.plenticore import SettingsData from pykoplenti import SettingsData
from homeassistant.components.diagnostics import REDACTED from homeassistant.components.diagnostics import REDACTED
from homeassistant.components.kostal_plenticore.helper import Plenticore from homeassistant.components.kostal_plenticore.helper import Plenticore
@ -57,7 +57,7 @@ async def test_entry_diagnostics(
}, },
"client": { "client": {
"version": "Version(api_version=0.2.0, hostname=scb, name=PUCK RESTful API, sw_version=01.16.05025)", "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)", "me": "Me(locked=False, active=True, authenticated=True, permissions=[], anonymous=False, role=USER)",
"available_process_data": {"devices:local": ["HomeGrid_P", "HomePv_P"]}, "available_process_data": {"devices:local": ["HomeGrid_P", "HomePv_P"]},
"available_settings_data": { "available_settings_data": {
"devices:local": [ "devices:local": [

View File

@ -4,7 +4,7 @@ from collections.abc import Generator
from datetime import timedelta from datetime import timedelta
from unittest.mock import patch from unittest.mock import patch
from kostal.plenticore import PlenticoreApiClient, SettingsData from pykoplenti import ApiClient, SettingsData
import pytest import pytest
from homeassistant.components.number import ( from homeassistant.components.number import (
@ -23,17 +23,17 @@ from tests.common import MockConfigEntry, async_fire_time_changed
@pytest.fixture @pytest.fixture
def mock_plenticore_client() -> Generator[PlenticoreApiClient, None, None]: def mock_plenticore_client() -> Generator[ApiClient, None, None]:
"""Return a patched PlenticoreApiClient.""" """Return a patched ApiClient."""
with patch( with patch(
"homeassistant.components.kostal_plenticore.helper.PlenticoreApiClient", "homeassistant.components.kostal_plenticore.helper.ApiClient",
autospec=True, autospec=True,
) as plenticore_client_class: ) as plenticore_client_class:
yield plenticore_client_class.return_value yield plenticore_client_class.return_value
@pytest.fixture @pytest.fixture
def mock_get_setting_values(mock_plenticore_client: PlenticoreApiClient) -> list: def mock_get_setting_values(mock_plenticore_client: ApiClient) -> list:
"""Add a setting value to the given Plenticore client. """Add a setting value to the given Plenticore client.
Returns a list with setting values which can be extended by test cases. Returns a list with setting values which can be extended by test cases.
@ -88,7 +88,7 @@ def mock_get_setting_values(mock_plenticore_client: PlenticoreApiClient) -> list
async def test_setup_all_entries( async def test_setup_all_entries(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
mock_plenticore_client: PlenticoreApiClient, mock_plenticore_client: ApiClient,
mock_get_setting_values: list, mock_get_setting_values: list,
entity_registry_enabled_by_default, entity_registry_enabled_by_default,
): ):
@ -107,7 +107,7 @@ async def test_setup_all_entries(
async def test_setup_no_entries( async def test_setup_no_entries(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
mock_plenticore_client: PlenticoreApiClient, mock_plenticore_client: ApiClient,
mock_get_setting_values: list, mock_get_setting_values: list,
entity_registry_enabled_by_default, entity_registry_enabled_by_default,
): ):
@ -128,7 +128,7 @@ async def test_setup_no_entries(
async def test_number_has_value( async def test_number_has_value(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
mock_plenticore_client: PlenticoreApiClient, mock_plenticore_client: ApiClient,
mock_get_setting_values: list, mock_get_setting_values: list,
entity_registry_enabled_by_default, entity_registry_enabled_by_default,
): ):
@ -153,7 +153,7 @@ async def test_number_has_value(
async def test_number_is_unavailable( async def test_number_is_unavailable(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
mock_plenticore_client: PlenticoreApiClient, mock_plenticore_client: ApiClient,
mock_get_setting_values: list, mock_get_setting_values: list,
entity_registry_enabled_by_default, entity_registry_enabled_by_default,
): ):
@ -174,7 +174,7 @@ async def test_number_is_unavailable(
async def test_set_value( async def test_set_value(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
mock_plenticore_client: PlenticoreApiClient, mock_plenticore_client: ApiClient,
mock_get_setting_values: list, mock_get_setting_values: list,
entity_registry_enabled_by_default, entity_registry_enabled_by_default,
): ):

View File

@ -1,5 +1,5 @@
"""Test the Kostal Plenticore Solar Inverter select platform.""" """Test the Kostal Plenticore Solar Inverter select platform."""
from kostal.plenticore import SettingsData from pykoplenti import SettingsData
from homeassistant.components.kostal_plenticore.helper import Plenticore from homeassistant.components.kostal_plenticore.helper import Plenticore
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant