mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
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:
parent
c26d620ab1
commit
54d570a9cf
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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"]
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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": [
|
||||||
|
@ -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,
|
||||||
):
|
):
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user