From 208622e8a7cd0d65e1b0537afb5ee787d3744e1e Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 30 Nov 2023 18:45:04 +0100 Subject: [PATCH] Revert "Add Komfovent (#95722)" (#104819) --- .coveragerc | 2 - CODEOWNERS | 2 - .../components/komfovent/__init__.py | 34 ---- homeassistant/components/komfovent/climate.py | 91 --------- .../components/komfovent/config_flow.py | 74 ------- homeassistant/components/komfovent/const.py | 3 - .../components/komfovent/manifest.json | 9 - .../components/komfovent/strings.json | 22 -- homeassistant/generated/config_flows.py | 1 - homeassistant/generated/integrations.json | 6 - requirements_all.txt | 3 - requirements_test_all.txt | 3 - tests/components/komfovent/__init__.py | 1 - tests/components/komfovent/conftest.py | 14 -- .../components/komfovent/test_config_flow.py | 189 ------------------ 15 files changed, 454 deletions(-) delete mode 100644 homeassistant/components/komfovent/__init__.py delete mode 100644 homeassistant/components/komfovent/climate.py delete mode 100644 homeassistant/components/komfovent/config_flow.py delete mode 100644 homeassistant/components/komfovent/const.py delete mode 100644 homeassistant/components/komfovent/manifest.json delete mode 100644 homeassistant/components/komfovent/strings.json delete mode 100644 tests/components/komfovent/__init__.py delete mode 100644 tests/components/komfovent/conftest.py delete mode 100644 tests/components/komfovent/test_config_flow.py diff --git a/.coveragerc b/.coveragerc index f15d36918ec..27aed1e1009 100644 --- a/.coveragerc +++ b/.coveragerc @@ -633,8 +633,6 @@ omit = homeassistant/components/kodi/browse_media.py homeassistant/components/kodi/media_player.py homeassistant/components/kodi/notify.py - homeassistant/components/komfovent/__init__.py - homeassistant/components/komfovent/climate.py homeassistant/components/konnected/__init__.py homeassistant/components/konnected/panel.py homeassistant/components/konnected/switch.py diff --git a/CODEOWNERS b/CODEOWNERS index ec32f941d56..5ecb7d75cc8 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -663,8 +663,6 @@ build.json @home-assistant/supervisor /tests/components/knx/ @Julius2342 @farmio @marvin-w /homeassistant/components/kodi/ @OnFreund /tests/components/kodi/ @OnFreund -/homeassistant/components/komfovent/ @ProstoSanja -/tests/components/komfovent/ @ProstoSanja /homeassistant/components/konnected/ @heythisisnate /tests/components/konnected/ @heythisisnate /homeassistant/components/kostal_plenticore/ @stegm diff --git a/homeassistant/components/komfovent/__init__.py b/homeassistant/components/komfovent/__init__.py deleted file mode 100644 index 0366a429b21..00000000000 --- a/homeassistant/components/komfovent/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -"""The Komfovent integration.""" -from __future__ import annotations - -import komfovent_api - -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform -from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryNotReady - -from .const import DOMAIN - -PLATFORMS: list[Platform] = [Platform.CLIMATE] - - -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Set up Komfovent from a config entry.""" - host = entry.data[CONF_HOST] - username = entry.data[CONF_USERNAME] - password = entry.data[CONF_PASSWORD] - _, credentials = komfovent_api.get_credentials(host, username, password) - result, settings = await komfovent_api.get_settings(credentials) - if result != komfovent_api.KomfoventConnectionResult.SUCCESS: - raise ConfigEntryNotReady(f"Unable to connect to {host}: {result}") - - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = (credentials, settings) - - await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) - return True - - -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Unload a config entry.""" - return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/komfovent/climate.py b/homeassistant/components/komfovent/climate.py deleted file mode 100644 index 2e51fddf4f2..00000000000 --- a/homeassistant/components/komfovent/climate.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Ventilation Units from Komfovent integration.""" -from __future__ import annotations - -import komfovent_api - -from homeassistant.components.climate import ( - ClimateEntity, - ClimateEntityFeature, - HVACMode, -) -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import UnitOfTemperature -from homeassistant.core import HomeAssistant -from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.entity_platform import AddEntitiesCallback - -from .const import DOMAIN - -HASS_TO_KOMFOVENT_MODES = { - HVACMode.COOL: komfovent_api.KomfoventModes.COOL, - HVACMode.HEAT_COOL: komfovent_api.KomfoventModes.HEAT_COOL, - HVACMode.OFF: komfovent_api.KomfoventModes.OFF, - HVACMode.AUTO: komfovent_api.KomfoventModes.AUTO, -} -KOMFOVENT_TO_HASS_MODES = {v: k for k, v in HASS_TO_KOMFOVENT_MODES.items()} - - -async def async_setup_entry( - hass: HomeAssistant, - entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, -) -> None: - """Set up the Komfovent unit control.""" - credentials, settings = hass.data[DOMAIN][entry.entry_id] - async_add_entities([KomfoventDevice(credentials, settings)], True) - - -class KomfoventDevice(ClimateEntity): - """Representation of a ventilation unit.""" - - _attr_hvac_modes = list(HASS_TO_KOMFOVENT_MODES.keys()) - _attr_preset_modes = [mode.name for mode in komfovent_api.KomfoventPresets] - _attr_supported_features = ClimateEntityFeature.PRESET_MODE - _attr_temperature_unit = UnitOfTemperature.CELSIUS - _attr_has_entity_name = True - _attr_name = None - - def __init__( - self, - credentials: komfovent_api.KomfoventCredentials, - settings: komfovent_api.KomfoventSettings, - ) -> None: - """Initialize the ventilation unit.""" - self._komfovent_credentials = credentials - self._komfovent_settings = settings - - self._attr_unique_id = settings.serial_number - self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, settings.serial_number)}, - model=settings.model, - name=settings.name, - serial_number=settings.serial_number, - sw_version=settings.version, - manufacturer="Komfovent", - ) - - async def async_set_preset_mode(self, preset_mode: str) -> None: - """Set new target preset mode.""" - await komfovent_api.set_preset( - self._komfovent_credentials, - komfovent_api.KomfoventPresets[preset_mode], - ) - - async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: - """Set new target hvac mode.""" - await komfovent_api.set_mode( - self._komfovent_credentials, HASS_TO_KOMFOVENT_MODES[hvac_mode] - ) - - async def async_update(self) -> None: - """Get the latest data.""" - result, status = await komfovent_api.get_unit_status( - self._komfovent_credentials - ) - if result != komfovent_api.KomfoventConnectionResult.SUCCESS or not status: - self._attr_available = False - return - self._attr_available = True - self._attr_preset_mode = status.preset - self._attr_current_temperature = status.temp_extract - self._attr_hvac_mode = KOMFOVENT_TO_HASS_MODES[status.mode] diff --git a/homeassistant/components/komfovent/config_flow.py b/homeassistant/components/komfovent/config_flow.py deleted file mode 100644 index fb5390a30c6..00000000000 --- a/homeassistant/components/komfovent/config_flow.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Config flow for Komfovent integration.""" -from __future__ import annotations - -import logging -from typing import Any - -import komfovent_api -import voluptuous as vol - -from homeassistant import config_entries -from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME -from homeassistant.data_entry_flow import FlowResult - -from .const import DOMAIN - -_LOGGER = logging.getLogger(__name__) - -STEP_USER = "user" -STEP_USER_DATA_SCHEMA = vol.Schema( - { - vol.Required(CONF_HOST): str, - vol.Optional(CONF_USERNAME, default="user"): str, - vol.Required(CONF_PASSWORD): str, - } -) - -ERRORS_MAP = { - komfovent_api.KomfoventConnectionResult.NOT_FOUND: "cannot_connect", - komfovent_api.KomfoventConnectionResult.UNAUTHORISED: "invalid_auth", - komfovent_api.KomfoventConnectionResult.INVALID_INPUT: "invalid_input", -} - - -class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): - """Handle a config flow for Komfovent.""" - - VERSION = 1 - - def __return_error( - self, result: komfovent_api.KomfoventConnectionResult - ) -> FlowResult: - return self.async_show_form( - step_id=STEP_USER, - data_schema=STEP_USER_DATA_SCHEMA, - errors={"base": ERRORS_MAP.get(result, "unknown")}, - ) - - async def async_step_user( - self, user_input: dict[str, Any] | None = None - ) -> FlowResult: - """Handle the initial step.""" - if user_input is None: - return self.async_show_form( - step_id=STEP_USER, data_schema=STEP_USER_DATA_SCHEMA - ) - - conf_host = user_input[CONF_HOST] - conf_username = user_input[CONF_USERNAME] - conf_password = user_input[CONF_PASSWORD] - - result, credentials = komfovent_api.get_credentials( - conf_host, conf_username, conf_password - ) - if result != komfovent_api.KomfoventConnectionResult.SUCCESS: - return self.__return_error(result) - - result, settings = await komfovent_api.get_settings(credentials) - if result != komfovent_api.KomfoventConnectionResult.SUCCESS: - return self.__return_error(result) - - await self.async_set_unique_id(settings.serial_number) - self._abort_if_unique_id_configured() - - return self.async_create_entry(title=settings.name, data=user_input) diff --git a/homeassistant/components/komfovent/const.py b/homeassistant/components/komfovent/const.py deleted file mode 100644 index a7881a58c41..00000000000 --- a/homeassistant/components/komfovent/const.py +++ /dev/null @@ -1,3 +0,0 @@ -"""Constants for the Komfovent integration.""" - -DOMAIN = "komfovent" diff --git a/homeassistant/components/komfovent/manifest.json b/homeassistant/components/komfovent/manifest.json deleted file mode 100644 index cbe00ef8dc5..00000000000 --- a/homeassistant/components/komfovent/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "domain": "komfovent", - "name": "Komfovent", - "codeowners": ["@ProstoSanja"], - "config_flow": true, - "documentation": "https://www.home-assistant.io/integrations/komfovent", - "iot_class": "local_polling", - "requirements": ["komfovent-api==0.0.3"] -} diff --git a/homeassistant/components/komfovent/strings.json b/homeassistant/components/komfovent/strings.json deleted file mode 100644 index 074754c1fe0..00000000000 --- a/homeassistant/components/komfovent/strings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "config": { - "step": { - "user": { - "data": { - "host": "[%key:common::config_flow::data::host%]", - "username": "[%key:common::config_flow::data::username%]", - "password": "[%key:common::config_flow::data::password%]" - } - } - }, - "error": { - "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", - "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", - "invalid_input": "Failed to parse provided hostname", - "unknown": "[%key:common::config_flow::error::unknown%]" - }, - "abort": { - "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" - } - } -} diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 57503f0ef32..eeee6532792 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -246,7 +246,6 @@ FLOWS = { "kmtronic", "knx", "kodi", - "komfovent", "konnected", "kostal_plenticore", "kraken", diff --git a/homeassistant/generated/integrations.json b/homeassistant/generated/integrations.json index f0af72624f6..2c6d8277309 100644 --- a/homeassistant/generated/integrations.json +++ b/homeassistant/generated/integrations.json @@ -2881,12 +2881,6 @@ "config_flow": true, "iot_class": "local_push" }, - "komfovent": { - "name": "Komfovent", - "integration_type": "hub", - "config_flow": true, - "iot_class": "local_polling" - }, "konnected": { "name": "Konnected.io", "integration_type": "hub", diff --git a/requirements_all.txt b/requirements_all.txt index 54a598ad9b1..8e9ad9fb404 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1128,9 +1128,6 @@ kiwiki-client==0.1.1 # homeassistant.components.knx knx-frontend==2023.6.23.191712 -# homeassistant.components.komfovent -komfovent-api==0.0.3 - # homeassistant.components.konnected konnected==1.2.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 82a65044067..bc70a0d4124 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -885,9 +885,6 @@ kegtron-ble==0.4.0 # homeassistant.components.knx knx-frontend==2023.6.23.191712 -# homeassistant.components.komfovent -komfovent-api==0.0.3 - # homeassistant.components.konnected konnected==1.2.0 diff --git a/tests/components/komfovent/__init__.py b/tests/components/komfovent/__init__.py deleted file mode 100644 index e5492a52327..00000000000 --- a/tests/components/komfovent/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Tests for the Komfovent integration.""" diff --git a/tests/components/komfovent/conftest.py b/tests/components/komfovent/conftest.py deleted file mode 100644 index d9cb0950c74..00000000000 --- a/tests/components/komfovent/conftest.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Common fixtures for the Komfovent tests.""" -from collections.abc import Generator -from unittest.mock import AsyncMock, patch - -import pytest - - -@pytest.fixture -def mock_setup_entry() -> Generator[AsyncMock, None, None]: - """Override async_setup_entry.""" - with patch( - "homeassistant.components.komfovent.async_setup_entry", return_value=True - ) as mock_setup_entry: - yield mock_setup_entry diff --git a/tests/components/komfovent/test_config_flow.py b/tests/components/komfovent/test_config_flow.py deleted file mode 100644 index 008d92e36a3..00000000000 --- a/tests/components/komfovent/test_config_flow.py +++ /dev/null @@ -1,189 +0,0 @@ -"""Test the Komfovent config flow.""" -from unittest.mock import AsyncMock, patch - -import komfovent_api -import pytest - -from homeassistant import config_entries -from homeassistant.components.komfovent.const import DOMAIN -from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME -from homeassistant.core import HomeAssistant -from homeassistant.data_entry_flow import FlowResult, FlowResultType - -from tests.common import MockConfigEntry - - -async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None: - """Test flow completes as expected.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - assert result["type"] == FlowResultType.FORM - assert result["errors"] is None - - final_result = await __test_normal_flow(hass, result["flow_id"]) - assert final_result["type"] == FlowResultType.CREATE_ENTRY - assert final_result["title"] == "test-name" - assert final_result["data"] == { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - } - assert len(mock_setup_entry.mock_calls) == 1 - - -@pytest.mark.parametrize( - ("error", "expected_response"), - [ - (komfovent_api.KomfoventConnectionResult.NOT_FOUND, "cannot_connect"), - (komfovent_api.KomfoventConnectionResult.UNAUTHORISED, "invalid_auth"), - (komfovent_api.KomfoventConnectionResult.INVALID_INPUT, "invalid_input"), - ], -) -async def test_flow_error_authenticating( - hass: HomeAssistant, - mock_setup_entry: AsyncMock, - error: komfovent_api.KomfoventConnectionResult, - expected_response: str, -) -> None: - """Test errors during flow authentication step are handled and dont affect final result.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - with patch( - "homeassistant.components.komfovent.config_flow.komfovent_api.get_credentials", - return_value=( - error, - None, - ), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - - assert result2["type"] == FlowResultType.FORM - assert result2["errors"] == {"base": expected_response} - - final_result = await __test_normal_flow(hass, result2["flow_id"]) - assert final_result["type"] == FlowResultType.CREATE_ENTRY - assert final_result["title"] == "test-name" - assert final_result["data"] == { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - } - assert len(mock_setup_entry.mock_calls) == 1 - - -@pytest.mark.parametrize( - ("error", "expected_response"), - [ - (komfovent_api.KomfoventConnectionResult.NOT_FOUND, "cannot_connect"), - (komfovent_api.KomfoventConnectionResult.UNAUTHORISED, "invalid_auth"), - (komfovent_api.KomfoventConnectionResult.INVALID_INPUT, "invalid_input"), - ], -) -async def test_flow_error_device_info( - hass: HomeAssistant, - mock_setup_entry: AsyncMock, - error: komfovent_api.KomfoventConnectionResult, - expected_response: str, -) -> None: - """Test errors during flow device info download step are handled and dont affect final result.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - with patch( - "homeassistant.components.komfovent.config_flow.komfovent_api.get_credentials", - return_value=( - komfovent_api.KomfoventConnectionResult.SUCCESS, - komfovent_api.KomfoventCredentials("1.1.1.1", "user", "pass"), - ), - ), patch( - "homeassistant.components.komfovent.config_flow.komfovent_api.get_settings", - return_value=( - error, - None, - ), - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - - assert result2["type"] == FlowResultType.FORM - assert result2["errors"] == {"base": expected_response} - - final_result = await __test_normal_flow(hass, result2["flow_id"]) - assert final_result["type"] == FlowResultType.CREATE_ENTRY - assert final_result["title"] == "test-name" - assert final_result["data"] == { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - } - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_device_already_exists( - hass: HomeAssistant, mock_setup_entry: AsyncMock -) -> None: - """Test device is not added when it already exists.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={ - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - unique_id="test-uid", - ) - entry.add_to_hass(hass) - - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - assert result["type"] == FlowResultType.FORM - assert result["errors"] is None - - final_result = await __test_normal_flow(hass, result["flow_id"]) - assert final_result["type"] == FlowResultType.ABORT - assert final_result["reason"] == "already_configured" - - -async def __test_normal_flow(hass: HomeAssistant, flow_id: str) -> FlowResult: - """Test flow completing as expected, no matter what happened before.""" - - with patch( - "homeassistant.components.komfovent.config_flow.komfovent_api.get_credentials", - return_value=( - komfovent_api.KomfoventConnectionResult.SUCCESS, - komfovent_api.KomfoventCredentials("1.1.1.1", "user", "pass"), - ), - ), patch( - "homeassistant.components.komfovent.config_flow.komfovent_api.get_settings", - return_value=( - komfovent_api.KomfoventConnectionResult.SUCCESS, - komfovent_api.KomfoventSettings("test-name", None, None, "test-uid"), - ), - ): - final_result = await hass.config_entries.flow.async_configure( - flow_id, - { - CONF_HOST: "1.1.1.1", - CONF_USERNAME: "test-username", - CONF_PASSWORD: "test-password", - }, - ) - await hass.async_block_till_done() - - return final_result