mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Add config flow to Mold indicator (#122600)
* Add config flow to Mold indicator * strings * Add tests * Is a helper * Add back platform yaml * Fixes * Remove wait
This commit is contained in:
parent
af62e8267f
commit
65b48aa903
@ -1 +1,26 @@
|
|||||||
"""Calculates mold growth indication from temperature and humidity."""
|
"""Calculates mold growth indication from temperature and humidity."""
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Set up Mold indicator from a config entry."""
|
||||||
|
|
||||||
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
entry.async_on_unload(entry.add_update_listener(update_listener))
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Unload Mold indicator config entry."""
|
||||||
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||||
|
"""Handle options update."""
|
||||||
|
await hass.config_entries.async_reload(entry.entry_id)
|
||||||
|
96
homeassistant/components/mold_indicator/config_flow.py
Normal file
96
homeassistant/components/mold_indicator/config_flow.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
"""Config flow for Mold indicator."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Mapping
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import SensorDeviceClass
|
||||||
|
from homeassistant.const import CONF_NAME, Platform
|
||||||
|
from homeassistant.helpers.schema_config_entry_flow import (
|
||||||
|
SchemaCommonFlowHandler,
|
||||||
|
SchemaConfigFlowHandler,
|
||||||
|
SchemaFlowFormStep,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.selector import (
|
||||||
|
EntitySelector,
|
||||||
|
EntitySelectorConfig,
|
||||||
|
NumberSelector,
|
||||||
|
NumberSelectorConfig,
|
||||||
|
NumberSelectorMode,
|
||||||
|
TextSelector,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
CONF_CALIBRATION_FACTOR,
|
||||||
|
CONF_INDOOR_HUMIDITY,
|
||||||
|
CONF_INDOOR_TEMP,
|
||||||
|
CONF_OUTDOOR_TEMP,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def validate_duplicate(
|
||||||
|
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Validate already existing entry."""
|
||||||
|
handler.parent_handler._async_abort_entries_match({**handler.options, **user_input}) # noqa: SLF001
|
||||||
|
return user_input
|
||||||
|
|
||||||
|
|
||||||
|
DATA_SCHEMA_OPTIONS = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_CALIBRATION_FACTOR): NumberSelector(
|
||||||
|
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
DATA_SCHEMA_CONFIG = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_NAME, default=DEFAULT_NAME): TextSelector(),
|
||||||
|
vol.Required(CONF_INDOOR_TEMP): EntitySelector(
|
||||||
|
EntitySelectorConfig(
|
||||||
|
domain=Platform.SENSOR, device_class=SensorDeviceClass.TEMPERATURE
|
||||||
|
)
|
||||||
|
),
|
||||||
|
vol.Required(CONF_INDOOR_HUMIDITY): EntitySelector(
|
||||||
|
EntitySelectorConfig(
|
||||||
|
domain=Platform.SENSOR, device_class=SensorDeviceClass.HUMIDITY
|
||||||
|
)
|
||||||
|
),
|
||||||
|
vol.Required(CONF_OUTDOOR_TEMP): EntitySelector(
|
||||||
|
EntitySelectorConfig(
|
||||||
|
domain=Platform.SENSOR, device_class=SensorDeviceClass.TEMPERATURE
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
).extend(DATA_SCHEMA_OPTIONS.schema)
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_FLOW = {
|
||||||
|
"user": SchemaFlowFormStep(
|
||||||
|
schema=DATA_SCHEMA_CONFIG,
|
||||||
|
validate_user_input=validate_duplicate,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
OPTIONS_FLOW = {
|
||||||
|
"init": SchemaFlowFormStep(
|
||||||
|
DATA_SCHEMA_OPTIONS,
|
||||||
|
validate_user_input=validate_duplicate,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MoldIndicatorConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
|
||||||
|
"""Handle a config flow for Mold indicator."""
|
||||||
|
|
||||||
|
config_flow = CONFIG_FLOW
|
||||||
|
options_flow = OPTIONS_FLOW
|
||||||
|
|
||||||
|
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
|
||||||
|
"""Return config entry title."""
|
||||||
|
return cast(str, options[CONF_NAME])
|
12
homeassistant/components/mold_indicator/const.py
Normal file
12
homeassistant/components/mold_indicator/const.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"""Constants for Mold indicator component."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
DOMAIN = "mold_indicator"
|
||||||
|
|
||||||
|
CONF_CALIBRATION_FACTOR = "calibration_factor"
|
||||||
|
CONF_INDOOR_HUMIDITY = "indoor_humidity_sensor"
|
||||||
|
CONF_INDOOR_TEMP = "indoor_temp_sensor"
|
||||||
|
CONF_OUTDOOR_TEMP = "outdoor_temp_sensor"
|
||||||
|
|
||||||
|
DEFAULT_NAME = "Mold Indicator"
|
@ -2,7 +2,9 @@
|
|||||||
"domain": "mold_indicator",
|
"domain": "mold_indicator",
|
||||||
"name": "Mold Indicator",
|
"name": "Mold Indicator",
|
||||||
"codeowners": [],
|
"codeowners": [],
|
||||||
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/mold_indicator",
|
"documentation": "https://www.home-assistant.io/integrations/mold_indicator",
|
||||||
"iot_class": "local_polling",
|
"integration_type": "helper",
|
||||||
|
"iot_class": "calculated",
|
||||||
"quality_scale": "internal"
|
"quality_scale": "internal"
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ from homeassistant.components.sensor import (
|
|||||||
SensorEntity,
|
SensorEntity,
|
||||||
SensorStateClass,
|
SensorStateClass,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
@ -37,17 +38,19 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateTyp
|
|||||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||||
from homeassistant.util.unit_system import METRIC_SYSTEM
|
from homeassistant.util.unit_system import METRIC_SYSTEM
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
CONF_CALIBRATION_FACTOR,
|
||||||
|
CONF_INDOOR_HUMIDITY,
|
||||||
|
CONF_INDOOR_TEMP,
|
||||||
|
CONF_OUTDOOR_TEMP,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ATTR_CRITICAL_TEMP = "estimated_critical_temp"
|
ATTR_CRITICAL_TEMP = "estimated_critical_temp"
|
||||||
ATTR_DEWPOINT = "dewpoint"
|
ATTR_DEWPOINT = "dewpoint"
|
||||||
|
|
||||||
CONF_CALIBRATION_FACTOR = "calibration_factor"
|
|
||||||
CONF_INDOOR_HUMIDITY = "indoor_humidity_sensor"
|
|
||||||
CONF_INDOOR_TEMP = "indoor_temp_sensor"
|
|
||||||
CONF_OUTDOOR_TEMP = "outdoor_temp_sensor"
|
|
||||||
|
|
||||||
DEFAULT_NAME = "Mold Indicator"
|
|
||||||
|
|
||||||
MAGNUS_K2 = 17.62
|
MAGNUS_K2 = 17.62
|
||||||
MAGNUS_K3 = 243.12
|
MAGNUS_K3 = 243.12
|
||||||
@ -70,7 +73,7 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up MoldIndicator sensor."""
|
"""Set up MoldIndicator sensor."""
|
||||||
name: str = config[CONF_NAME]
|
name: str = config.get(CONF_NAME, DEFAULT_NAME)
|
||||||
indoor_temp_sensor: str = config[CONF_INDOOR_TEMP]
|
indoor_temp_sensor: str = config[CONF_INDOOR_TEMP]
|
||||||
outdoor_temp_sensor: str = config[CONF_OUTDOOR_TEMP]
|
outdoor_temp_sensor: str = config[CONF_OUTDOOR_TEMP]
|
||||||
indoor_humidity_sensor: str = config[CONF_INDOOR_HUMIDITY]
|
indoor_humidity_sensor: str = config[CONF_INDOOR_HUMIDITY]
|
||||||
@ -91,6 +94,33 @@ async def async_setup_platform(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up the Mold indicator sensor entry."""
|
||||||
|
name: str = entry.options[CONF_NAME]
|
||||||
|
indoor_temp_sensor: str = entry.options[CONF_INDOOR_TEMP]
|
||||||
|
outdoor_temp_sensor: str = entry.options[CONF_OUTDOOR_TEMP]
|
||||||
|
indoor_humidity_sensor: str = entry.options[CONF_INDOOR_HUMIDITY]
|
||||||
|
calib_factor: float = entry.options[CONF_CALIBRATION_FACTOR]
|
||||||
|
|
||||||
|
async_add_entities(
|
||||||
|
[
|
||||||
|
MoldIndicator(
|
||||||
|
name,
|
||||||
|
hass.config.units is METRIC_SYSTEM,
|
||||||
|
indoor_temp_sensor,
|
||||||
|
outdoor_temp_sensor,
|
||||||
|
indoor_humidity_sensor,
|
||||||
|
calib_factor,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MoldIndicator(SensorEntity):
|
class MoldIndicator(SensorEntity):
|
||||||
"""Represents a MoldIndication sensor."""
|
"""Represents a MoldIndication sensor."""
|
||||||
|
|
||||||
|
42
homeassistant/components/mold_indicator/strings.json
Normal file
42
homeassistant/components/mold_indicator/strings.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"description": "Add Mold indicator helper",
|
||||||
|
"data": {
|
||||||
|
"name": "[%key:common::config_flow::data::name%]",
|
||||||
|
"indoor_humidity_sensor": "Indoor humidity sensor",
|
||||||
|
"indoor_temp_sensor": "Indoor temperature sensor",
|
||||||
|
"outdoor_temp_sensor": "Outdoor temperature sensor",
|
||||||
|
"calibration_factor": "Calibration factor"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"name": "Name for the created entity.",
|
||||||
|
"indoor_humidity_sensor": "The entity ID of the indoor humidity sensor.",
|
||||||
|
"indoor_temp_sensor": "The entity ID of the indoor temperature sensor.",
|
||||||
|
"outdoor_temp_sensor": "The entity ID of the outdoor temperature sensor.",
|
||||||
|
"calibration_factor": "Needs to be calibrated to the critical point in the room."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"description": "Adjust the calibration factor as required",
|
||||||
|
"data": {
|
||||||
|
"calibration_factor": "[%key:component::mold_indicator::config::step::user::data::calibration_factor%]"
|
||||||
|
},
|
||||||
|
"data_description": {
|
||||||
|
"calibration_factor": "[%key:component::mold_indicator::config::step::user::data_description::calibration_factor%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ FLOWS = {
|
|||||||
"history_stats",
|
"history_stats",
|
||||||
"integration",
|
"integration",
|
||||||
"min_max",
|
"min_max",
|
||||||
|
"mold_indicator",
|
||||||
"random",
|
"random",
|
||||||
"statistics",
|
"statistics",
|
||||||
"switch_as_x",
|
"switch_as_x",
|
||||||
|
@ -3790,12 +3790,6 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"iot_class": "local_push"
|
"iot_class": "local_push"
|
||||||
},
|
},
|
||||||
"mold_indicator": {
|
|
||||||
"name": "Mold Indicator",
|
|
||||||
"integration_type": "hub",
|
|
||||||
"config_flow": false,
|
|
||||||
"iot_class": "local_polling"
|
|
||||||
},
|
|
||||||
"monessen": {
|
"monessen": {
|
||||||
"name": "Monessen",
|
"name": "Monessen",
|
||||||
"integration_type": "virtual",
|
"integration_type": "virtual",
|
||||||
@ -7307,6 +7301,12 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"iot_class": "calculated"
|
"iot_class": "calculated"
|
||||||
},
|
},
|
||||||
|
"mold_indicator": {
|
||||||
|
"name": "Mold Indicator",
|
||||||
|
"integration_type": "helper",
|
||||||
|
"config_flow": true,
|
||||||
|
"iot_class": "calculated"
|
||||||
|
},
|
||||||
"random": {
|
"random": {
|
||||||
"name": "Random",
|
"name": "Random",
|
||||||
"integration_type": "helper",
|
"integration_type": "helper",
|
||||||
|
90
tests/components/mold_indicator/conftest.py
Normal file
90
tests/components/mold_indicator/conftest.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
"""Fixtures for the Mold indicator integration."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
|
from typing import Any
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.mold_indicator.const import (
|
||||||
|
CONF_CALIBRATION_FACTOR,
|
||||||
|
CONF_INDOOR_HUMIDITY,
|
||||||
|
CONF_INDOOR_TEMP,
|
||||||
|
CONF_OUTDOOR_TEMP,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import SOURCE_USER
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
CONF_NAME,
|
||||||
|
PERCENTAGE,
|
||||||
|
UnitOfTemperature,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||||
|
"""Automatically path mold indicator."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.mold_indicator.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
yield mock_setup_entry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="get_config")
|
||||||
|
async def get_config_to_integration_load() -> dict[str, Any]:
|
||||||
|
"""Return configuration.
|
||||||
|
|
||||||
|
To override the config, tests can be marked with:
|
||||||
|
@pytest.mark.parametrize("get_config", [{...}])
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_INDOOR_TEMP: "sensor.indoor_temp",
|
||||||
|
CONF_INDOOR_HUMIDITY: "sensor.indoor_humidity",
|
||||||
|
CONF_OUTDOOR_TEMP: "sensor.outdoor_temp",
|
||||||
|
CONF_CALIBRATION_FACTOR: 2.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="loaded_entry")
|
||||||
|
async def load_integration(
|
||||||
|
hass: HomeAssistant, get_config: dict[str, Any]
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Set up the Mold indicator integration in Home Assistant."""
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
source=SOURCE_USER,
|
||||||
|
options=get_config,
|
||||||
|
entry_id="1",
|
||||||
|
title=DEFAULT_NAME,
|
||||||
|
)
|
||||||
|
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
hass.states.async_set(
|
||||||
|
"sensor.indoor_temp",
|
||||||
|
"10",
|
||||||
|
{ATTR_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS},
|
||||||
|
)
|
||||||
|
hass.states.async_set(
|
||||||
|
"sensor.outdoor_temp",
|
||||||
|
"10",
|
||||||
|
{ATTR_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS},
|
||||||
|
)
|
||||||
|
hass.states.async_set(
|
||||||
|
"sensor.indoor_humidity", "0", {ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return config_entry
|
115
tests/components/mold_indicator/test_config_flow.py
Normal file
115
tests/components/mold_indicator/test_config_flow.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
"""Test the Mold indicator config flow."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
from homeassistant.components.mold_indicator.const import (
|
||||||
|
CONF_CALIBRATION_FACTOR,
|
||||||
|
CONF_INDOOR_HUMIDITY,
|
||||||
|
CONF_INDOOR_TEMP,
|
||||||
|
CONF_OUTDOOR_TEMP,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import SOURCE_USER
|
||||||
|
from homeassistant.const import CONF_NAME
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_form_sensor(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||||
|
"""Test we get the form for sensor."""
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_INDOOR_TEMP: "sensor.indoor_temp",
|
||||||
|
CONF_INDOOR_HUMIDITY: "sensor.indoor_humidity",
|
||||||
|
CONF_OUTDOOR_TEMP: "sensor.outdoor_temp",
|
||||||
|
CONF_CALIBRATION_FACTOR: 2.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == DEFAULT_NAME
|
||||||
|
assert result["version"] == 1
|
||||||
|
assert result["options"] == {
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_INDOOR_TEMP: "sensor.indoor_temp",
|
||||||
|
CONF_INDOOR_HUMIDITY: "sensor.indoor_humidity",
|
||||||
|
CONF_OUTDOOR_TEMP: "sensor.outdoor_temp",
|
||||||
|
CONF_CALIBRATION_FACTOR: 2.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_options_flow(hass: HomeAssistant, loaded_entry: MockConfigEntry) -> None:
|
||||||
|
"""Test options flow."""
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_init(loaded_entry.entry_id)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
|
CONF_CALIBRATION_FACTOR: 3.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["data"] == {
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_INDOOR_TEMP: "sensor.indoor_temp",
|
||||||
|
CONF_INDOOR_HUMIDITY: "sensor.indoor_humidity",
|
||||||
|
CONF_OUTDOOR_TEMP: "sensor.outdoor_temp",
|
||||||
|
CONF_CALIBRATION_FACTOR: 3.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
# Check the entity was updated, no new entity was created
|
||||||
|
# 3 input entities + resulting mold indicator sensor
|
||||||
|
assert len(hass.states.async_all()) == 4
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.mold_indicator")
|
||||||
|
assert state is not None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entry_already_exist(
|
||||||
|
hass: HomeAssistant, loaded_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
|
"""Test abort when entry already exist."""
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_INDOOR_TEMP: "sensor.indoor_temp",
|
||||||
|
CONF_INDOOR_HUMIDITY: "sensor.indoor_humidity",
|
||||||
|
CONF_OUTDOOR_TEMP: "sensor.outdoor_temp",
|
||||||
|
CONF_CALIBRATION_FACTOR: 2.0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
17
tests/components/mold_indicator/test_init.py
Normal file
17
tests/components/mold_indicator/test_init.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
"""Test Mold indicator component setup process."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unload_entry(hass: HomeAssistant, loaded_entry: MockConfigEntry) -> None:
|
||||||
|
"""Test unload an entry."""
|
||||||
|
|
||||||
|
assert loaded_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert await hass.config_entries.async_unload(loaded_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert loaded_entry.state is ConfigEntryState.NOT_LOADED
|
@ -16,6 +16,8 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def init_sensors_fixture(hass: HomeAssistant) -> None:
|
def init_sensors_fixture(hass: HomeAssistant) -> None:
|
||||||
@ -52,6 +54,16 @@ async def test_setup(hass: HomeAssistant) -> None:
|
|||||||
assert moldind.attributes.get("unit_of_measurement") == PERCENTAGE
|
assert moldind.attributes.get("unit_of_measurement") == PERCENTAGE
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_from_config_entry(
|
||||||
|
hass: HomeAssistant, loaded_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
|
"""Test the mold indicator sensor setup from a config entry."""
|
||||||
|
|
||||||
|
moldind = hass.states.get("sensor.mold_indicator")
|
||||||
|
assert moldind
|
||||||
|
assert moldind.attributes.get("unit_of_measurement") == PERCENTAGE
|
||||||
|
|
||||||
|
|
||||||
async def test_invalidcalib(hass: HomeAssistant) -> None:
|
async def test_invalidcalib(hass: HomeAssistant) -> None:
|
||||||
"""Test invalid sensor values."""
|
"""Test invalid sensor values."""
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user