mirror of
https://github.com/home-assistant/core.git
synced 2026-01-14 02:58:14 +00:00
Compare commits
7 Commits
simplify_t
...
matter_rem
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f189fcd8f | ||
|
|
068a7917fe | ||
|
|
66f60e6757 | ||
|
|
72d299f088 | ||
|
|
9c66561381 | ||
|
|
e762f839fa | ||
|
|
0c9d97c89f |
@@ -407,6 +407,7 @@ homeassistant.components.person.*
|
||||
homeassistant.components.pi_hole.*
|
||||
homeassistant.components.ping.*
|
||||
homeassistant.components.plugwise.*
|
||||
homeassistant.components.pooldose.*
|
||||
homeassistant.components.portainer.*
|
||||
homeassistant.components.powerfox.*
|
||||
homeassistant.components.powerwall.*
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["datadog"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["datadog==0.52.0"]
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
device_class=SensorDeviceClass.CO,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.co.concentration.units,
|
||||
exists_fn=lambda x: "co" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.co.concentration.value,
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
@@ -143,6 +144,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
translation_key="nitrogen_dioxide",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.no2.concentration.units,
|
||||
exists_fn=lambda x: "no2" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.no2.concentration.value,
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
@@ -150,6 +152,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
translation_key="ozone",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.o3.concentration.units,
|
||||
exists_fn=lambda x: "o3" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.o3.concentration.value,
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
@@ -157,6 +160,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
device_class=SensorDeviceClass.PM10,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.pm10.concentration.units,
|
||||
exists_fn=lambda x: "pm10" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.pm10.concentration.value,
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
@@ -164,6 +168,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
device_class=SensorDeviceClass.PM25,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.pm25.concentration.units,
|
||||
exists_fn=lambda x: "pm25" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.pm25.concentration.value,
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
@@ -171,6 +176,7 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
translation_key="sulphur_dioxide",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.so2.concentration.units,
|
||||
exists_fn=lambda x: "so2" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.so2.concentration.value,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["london_tube_status"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["london-tube-status==0.5"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
||||
@@ -528,7 +528,10 @@ DISCOVERY_SCHEMAS = [
|
||||
),
|
||||
),
|
||||
entity_class=MatterBinarySensor,
|
||||
required_attributes=(clusters.Thermostat.Attributes.RemoteSensing,),
|
||||
required_attributes=(
|
||||
clusters.Thermostat.Attributes.RemoteSensing,
|
||||
clusters.Thermostat.Attributes.OutdoorTemperature,
|
||||
),
|
||||
allow_multi=True,
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
|
||||
@@ -9,7 +9,7 @@ from aiohttp import ClientError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_DOMAIN, CONF_HOST, CONF_PASSWORD
|
||||
from homeassistant.const import CONF_DOMAIN, CONF_HOST, CONF_NAME, CONF_PASSWORD
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.selector import (
|
||||
@@ -37,6 +37,16 @@ STEP_USER_DATA_SCHEMA = vol.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
STEP_RECONFIGURE_DATA_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_PASSWORD): TextSelector(
|
||||
TextSelectorConfig(
|
||||
type=TextSelectorType.PASSWORD, autocomplete="current-password"
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class NamecheapDnsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Namecheap DynamicDNS."""
|
||||
@@ -89,3 +99,41 @@ class NamecheapDnsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
deprecate_yaml_issue(self.hass, import_success=True)
|
||||
return result
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle reconfigure flow."""
|
||||
errors: dict[str, str] = {}
|
||||
|
||||
entry = self._get_reconfigure_entry()
|
||||
|
||||
if user_input is not None:
|
||||
session = async_get_clientsession(self.hass)
|
||||
try:
|
||||
if not await update_namecheapdns(
|
||||
session,
|
||||
entry.data[CONF_HOST],
|
||||
entry.data[CONF_DOMAIN],
|
||||
user_input[CONF_PASSWORD],
|
||||
):
|
||||
errors["base"] = "update_failed"
|
||||
except ClientError:
|
||||
_LOGGER.debug("Cannot connect", exc_info=True)
|
||||
errors["base"] = "cannot_connect"
|
||||
except Exception:
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
|
||||
if not errors:
|
||||
return self.async_update_reload_and_abort(
|
||||
entry,
|
||||
data_updates=user_input,
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="reconfigure",
|
||||
data_schema=STEP_RECONFIGURE_DATA_SCHEMA,
|
||||
errors=errors,
|
||||
description_placeholders={CONF_NAME: entry.title},
|
||||
)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]"
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
@@ -9,6 +10,15 @@
|
||||
"update_failed": "Updating DNS failed"
|
||||
},
|
||||
"step": {
|
||||
"reconfigure": {
|
||||
"data": {
|
||||
"password": "[%key:component::namecheapdns::config::step::user::data::password%]"
|
||||
},
|
||||
"data_description": {
|
||||
"password": "[%key:component::namecheapdns::config::step::user::data_description::password%]"
|
||||
},
|
||||
"title": "Re-configure {name}"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"domain": "[%key:common::config_flow::data::username%]",
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/nederlandse_spoorwegen",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["nsapi==3.1.3"]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyrail"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["pyrail==0.4.1"]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
from collections.abc import Callable, Coroutine
|
||||
from typing import Any, Literal
|
||||
|
||||
from pooldose.type_definitions import DeviceInfoDict, ValueDict
|
||||
|
||||
@@ -80,7 +81,10 @@ class PooldoseEntity(CoordinatorEntity[PooldoseCoordinator]):
|
||||
return platform_data.get(self.entity_description.key)
|
||||
|
||||
async def _async_perform_write(
|
||||
self, api_call, key: str, value: bool | str | float
|
||||
self,
|
||||
api_call: Callable[[str, Any], Coroutine[Any, Any, bool]],
|
||||
key: str,
|
||||
value: bool | str | float,
|
||||
) -> None:
|
||||
"""Perform a write call to the API with unified error handling.
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/pooldose",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"quality_scale": "gold",
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["python-pooldose==0.8.2"]
|
||||
}
|
||||
|
||||
@@ -71,4 +71,4 @@ rules:
|
||||
# Platinum
|
||||
async-dependency: done
|
||||
inject-websession: done
|
||||
strict-typing: todo
|
||||
strict-typing: done
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["prowl"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["prowlpy==1.1.1"]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,5 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["wsdot"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["wsdot==0.0.1"]
|
||||
}
|
||||
|
||||
10
mypy.ini
generated
10
mypy.ini
generated
@@ -3826,6 +3826,16 @@ disallow_untyped_defs = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.pooldose.*]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_untyped_defs = true
|
||||
warn_return_any = true
|
||||
warn_unreachable = true
|
||||
|
||||
[mypy-homeassistant.components.portainer.*]
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
||||
@@ -41,7 +41,20 @@ from homeassistant.setup import async_setup_component
|
||||
from tests.common import get_fixture_path
|
||||
|
||||
VALUES = [17, 20, 15.3]
|
||||
VALUES_ERROR = [17, "string", 15.3]
|
||||
|
||||
STATES_ONE_ERROR = ["17", "string", "15.3"]
|
||||
STATES_ONE_MISSING = ["17", None, "15.3"]
|
||||
STATES_ONE_UNKNOWN = ["17", STATE_UNKNOWN, "15.3"]
|
||||
STATES_ONE_UNAVAILABLE = ["17", STATE_UNAVAILABLE, "15.3"]
|
||||
STATES_ALL_ERROR = ["string", "string", "string"]
|
||||
STATES_ALL_MISSING = [None, None, None]
|
||||
STATES_ALL_UNKNOWN = [STATE_UNKNOWN, STATE_UNKNOWN, STATE_UNKNOWN]
|
||||
STATES_ALL_UNAVAILABLE = [STATE_UNAVAILABLE, STATE_UNAVAILABLE, STATE_UNAVAILABLE]
|
||||
STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN = [None, STATE_UNAVAILABLE, STATE_UNKNOWN]
|
||||
STATES_MIX_MISSING_UNAVAILABLE = [None, STATE_UNAVAILABLE, STATE_UNAVAILABLE]
|
||||
STATES_MIX_MISSING_UNKNOWN = [None, STATE_UNKNOWN, STATE_UNKNOWN]
|
||||
STATES_MIX_UNAVAILABLE_UNKNOWN = [STATE_UNAVAILABLE, STATE_UNKNOWN, STATE_UNKNOWN]
|
||||
|
||||
COUNT = len(VALUES)
|
||||
MIN_VALUE = min(VALUES)
|
||||
MAX_VALUE = max(VALUES)
|
||||
@@ -53,6 +66,18 @@ SUM_VALUE = sum(VALUES)
|
||||
PRODUCT_VALUE = prod(VALUES)
|
||||
|
||||
|
||||
def set_or_remove_state(
|
||||
hass: HomeAssistant,
|
||||
entity_id: str,
|
||||
state: str | None,
|
||||
) -> None:
|
||||
"""Set or remove the state of an entity."""
|
||||
if state is None:
|
||||
hass.states.async_remove(entity_id)
|
||||
else:
|
||||
hass.states.async_set(entity_id, state)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("sensor_type", "result", "attributes"),
|
||||
[
|
||||
@@ -90,7 +115,7 @@ async def test_sensors2(
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
value,
|
||||
str(value),
|
||||
{
|
||||
ATTR_DEVICE_CLASS: SensorDeviceClass.VOLUME,
|
||||
ATTR_STATE_CLASS: SensorStateClass.TOTAL,
|
||||
@@ -140,7 +165,7 @@ async def test_sensors_attributes_defined(hass: HomeAssistant) -> None:
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
value,
|
||||
str(value),
|
||||
{
|
||||
ATTR_DEVICE_CLASS: SensorDeviceClass.VOLUME,
|
||||
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||
@@ -185,7 +210,7 @@ async def test_not_enough_sensor_value(hass: HomeAssistant) -> None:
|
||||
assert state.attributes.get("min_entity_id") is None
|
||||
assert state.attributes.get("max_entity_id") is None
|
||||
|
||||
hass.states.async_set(entity_ids[1], VALUES[1])
|
||||
hass.states.async_set(entity_ids[1], str(VALUES[1]))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_max")
|
||||
@@ -210,8 +235,8 @@ async def test_not_enough_sensor_value(hass: HomeAssistant) -> None:
|
||||
|
||||
async def test_reload(hass: HomeAssistant) -> None:
|
||||
"""Verify we can reload sensors."""
|
||||
hass.states.async_set("sensor.test_1", 12345)
|
||||
hass.states.async_set("sensor.test_2", 45678)
|
||||
hass.states.async_set("sensor.test_1", "12345")
|
||||
hass.states.async_set("sensor.test_2", "45678")
|
||||
|
||||
await async_setup_component(
|
||||
hass,
|
||||
@@ -249,8 +274,28 @@ async def test_reload(hass: HomeAssistant) -> None:
|
||||
assert hass.states.get("sensor.second_test")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("states_list", "expected_group_state"),
|
||||
[
|
||||
(STATES_ONE_ERROR, "17.0"),
|
||||
(STATES_ONE_MISSING, "17.0"),
|
||||
(STATES_ONE_UNKNOWN, "17.0"),
|
||||
(STATES_ONE_UNAVAILABLE, "17.0"),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
],
|
||||
)
|
||||
async def test_sensor_incorrect_state_with_ignore_non_numeric(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
states_list: list[str | None],
|
||||
expected_group_state: str,
|
||||
) -> None:
|
||||
"""Test that non numeric values are ignored in a group."""
|
||||
config = {
|
||||
@@ -271,27 +316,48 @@ async def test_sensor_incorrect_state_with_ignore_non_numeric(
|
||||
entity_ids = config["sensor"]["entities"]
|
||||
|
||||
# Check that the final sensor value ignores the non numeric input
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES_ERROR, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
for entity_id, value in dict(zip(entity_ids, states_list, strict=False)).items():
|
||||
set_or_remove_state(hass, entity_id, value)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_ignore_non_numeric")
|
||||
assert state.state == "17.0"
|
||||
assert state.state == expected_group_state
|
||||
assert (
|
||||
"Unable to use state. Only numerical states are supported," not in caplog.text
|
||||
)
|
||||
|
||||
# Check that the final sensor value with all numeric inputs
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
hass.states.async_set(entity_id, str(value))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_ignore_non_numeric")
|
||||
assert state.state == "20.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("states_list", "expected_group_state", "error_count"),
|
||||
[
|
||||
(STATES_ONE_ERROR, STATE_UNKNOWN, 1),
|
||||
(STATES_ONE_MISSING, "17.0", 0),
|
||||
(STATES_ONE_UNKNOWN, STATE_UNKNOWN, 1),
|
||||
(STATES_ONE_UNAVAILABLE, STATE_UNKNOWN, 1),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE, 3),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE, 0),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE, 3),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE, 3),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE, 2),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE, 3),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE, 2),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE, 2),
|
||||
],
|
||||
)
|
||||
async def test_sensor_incorrect_state_with_not_ignore_non_numeric(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
states_list: list[str | None],
|
||||
expected_group_state: str,
|
||||
error_count: int,
|
||||
) -> None:
|
||||
"""Test that non numeric values cause a group to be unknown."""
|
||||
config = {
|
||||
@@ -312,24 +378,46 @@ async def test_sensor_incorrect_state_with_not_ignore_non_numeric(
|
||||
entity_ids = config["sensor"]["entities"]
|
||||
|
||||
# Check that the final sensor value is unavailable if a non numeric input exists
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES_ERROR, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
for entity_id, value in dict(zip(entity_ids, states_list, strict=False)).items():
|
||||
set_or_remove_state(hass, entity_id, value)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_failure")
|
||||
assert state.state == "unknown"
|
||||
assert "Unable to use state. Only numerical states are supported" in caplog.text
|
||||
assert state.state == expected_group_state
|
||||
assert (
|
||||
caplog.text.count("Unable to use state. Only numerical states are supported")
|
||||
== error_count
|
||||
)
|
||||
|
||||
# Check that the final sensor value is correct with all numeric inputs
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
hass.states.async_set(entity_id, str(value))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_failure")
|
||||
assert state.state == "20.0"
|
||||
|
||||
|
||||
async def test_sensor_require_all_states(hass: HomeAssistant) -> None:
|
||||
@pytest.mark.parametrize(
|
||||
("states_list", "expected_group_state"),
|
||||
[
|
||||
(STATES_ONE_ERROR, STATE_UNKNOWN),
|
||||
(STATES_ONE_MISSING, "32.3"),
|
||||
(STATES_ONE_UNKNOWN, STATE_UNKNOWN),
|
||||
(STATES_ONE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
(STATES_ALL_ERROR, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_MISSING, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_ALL_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
(STATES_MIX_MISSING_UNAVAILABLE_UNKNOWN, STATE_UNAVAILABLE),
|
||||
],
|
||||
)
|
||||
async def test_sensor_require_all_states(
|
||||
hass: HomeAssistant, states_list: list[str | None], expected_group_state: str
|
||||
) -> None:
|
||||
"""Test the sum sensor with missing state require all."""
|
||||
config = {
|
||||
SENSOR_DOMAIN: {
|
||||
@@ -348,13 +436,13 @@ async def test_sensor_require_all_states(hass: HomeAssistant) -> None:
|
||||
|
||||
entity_ids = config["sensor"]["entities"]
|
||||
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES_ERROR, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
for entity_id, value in dict(zip(entity_ids, states_list, strict=False)).items():
|
||||
set_or_remove_state(hass, entity_id, value)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("sensor.test_sum")
|
||||
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.state == expected_group_state
|
||||
|
||||
|
||||
async def test_sensor_calculated_properties(hass: HomeAssistant) -> None:
|
||||
@@ -373,7 +461,7 @@ async def test_sensor_calculated_properties(hass: HomeAssistant) -> None:
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -382,7 +470,7 @@ async def test_sensor_calculated_properties(hass: HomeAssistant) -> None:
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[1],
|
||||
VALUES[1],
|
||||
str(VALUES[1]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -391,7 +479,7 @@ async def test_sensor_calculated_properties(hass: HomeAssistant) -> None:
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -413,7 +501,7 @@ async def test_sensor_calculated_properties(hass: HomeAssistant) -> None:
|
||||
# is converted correctly by the group sensor
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -446,7 +534,7 @@ async def test_sensor_with_uoms_but_no_device_class(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.POWER,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -455,7 +543,7 @@ async def test_sensor_with_uoms_but_no_device_class(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[1],
|
||||
VALUES[1],
|
||||
str(VALUES[1]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.POWER,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -464,7 +552,7 @@ async def test_sensor_with_uoms_but_no_device_class(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"unit_of_measurement": "W",
|
||||
},
|
||||
@@ -487,7 +575,7 @@ async def test_sensor_with_uoms_but_no_device_class(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.POWER,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -508,7 +596,7 @@ async def test_sensor_with_uoms_but_no_device_class(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.POWER,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -541,7 +629,7 @@ async def test_sensor_calculated_properties_not_same(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -550,7 +638,7 @@ async def test_sensor_calculated_properties_not_same(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[1],
|
||||
VALUES[1],
|
||||
str(VALUES[1]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -559,7 +647,7 @@ async def test_sensor_calculated_properties_not_same(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.CURRENT,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -604,7 +692,7 @@ async def test_sensor_calculated_result_fails_on_uom(hass: HomeAssistant) -> Non
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -613,7 +701,7 @@ async def test_sensor_calculated_result_fails_on_uom(hass: HomeAssistant) -> Non
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[1],
|
||||
VALUES[1],
|
||||
str(VALUES[1]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -622,7 +710,7 @@ async def test_sensor_calculated_result_fails_on_uom(hass: HomeAssistant) -> Non
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -642,7 +730,7 @@ async def test_sensor_calculated_result_fails_on_uom(hass: HomeAssistant) -> Non
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
12,
|
||||
"12",
|
||||
{
|
||||
"device_class": SensorDeviceClass.ENERGY,
|
||||
"state_class": SensorStateClass.TOTAL,
|
||||
@@ -677,7 +765,7 @@ async def test_sensor_calculated_properties_not_convertible_device_class(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[0],
|
||||
VALUES[0],
|
||||
str(VALUES[0]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -686,7 +774,7 @@ async def test_sensor_calculated_properties_not_convertible_device_class(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[1],
|
||||
VALUES[1],
|
||||
str(VALUES[1]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -695,7 +783,7 @@ async def test_sensor_calculated_properties_not_convertible_device_class(
|
||||
)
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -720,7 +808,7 @@ async def test_sensor_calculated_properties_not_convertible_device_class(
|
||||
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
@@ -760,7 +848,7 @@ async def test_last_sensor(hass: HomeAssistant) -> None:
|
||||
entity_ids = config["sensor"]["entities"]
|
||||
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(entity_id, value)
|
||||
hass.states.async_set(entity_id, str(value))
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("sensor.test_last")
|
||||
assert str(float(value)) == state.state
|
||||
@@ -797,7 +885,7 @@ async def test_sensors_attributes_added_when_entity_info_available(
|
||||
for entity_id, value in dict(zip(entity_ids, VALUES, strict=False)).items():
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
value,
|
||||
str(value),
|
||||
{
|
||||
ATTR_DEVICE_CLASS: SensorDeviceClass.VOLUME,
|
||||
ATTR_STATE_CLASS: SensorStateClass.TOTAL,
|
||||
@@ -843,9 +931,9 @@ async def test_sensor_state_class_no_uom_not_available(
|
||||
"unit_of_measurement": PERCENTAGE,
|
||||
}
|
||||
|
||||
hass.states.async_set(entity_ids[0], VALUES[0], input_attributes)
|
||||
hass.states.async_set(entity_ids[1], VALUES[1], input_attributes)
|
||||
hass.states.async_set(entity_ids[2], VALUES[2], input_attributes)
|
||||
hass.states.async_set(entity_ids[0], str(VALUES[0]), input_attributes)
|
||||
hass.states.async_set(entity_ids[1], str(VALUES[1]), input_attributes)
|
||||
hass.states.async_set(entity_ids[2], str(VALUES[2]), input_attributes)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert await async_setup_component(hass, "sensor", config)
|
||||
@@ -864,7 +952,7 @@ async def test_sensor_state_class_no_uom_not_available(
|
||||
# sensor.test_3 drops the unit of measurement
|
||||
hass.states.async_set(
|
||||
entity_ids[2],
|
||||
VALUES[2],
|
||||
str(VALUES[2]),
|
||||
{
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
},
|
||||
@@ -914,7 +1002,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
test_cases = [
|
||||
{
|
||||
"entity": entity_ids[0],
|
||||
"value": VALUES[0],
|
||||
"value": str(VALUES[0]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
"unit_of_measurement": PERCENTAGE,
|
||||
@@ -926,7 +1014,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
},
|
||||
{
|
||||
"entity": entity_ids[1],
|
||||
"value": VALUES[1],
|
||||
"value": str(VALUES[1]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
@@ -939,7 +1027,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
},
|
||||
{
|
||||
"entity": entity_ids[2],
|
||||
"value": VALUES[2],
|
||||
"value": str(VALUES[2]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
"device_class": SensorDeviceClass.TEMPERATURE,
|
||||
@@ -952,7 +1040,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
},
|
||||
{
|
||||
"entity": entity_ids[2],
|
||||
"value": VALUES[2],
|
||||
"value": str(VALUES[2]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
@@ -966,7 +1054,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
},
|
||||
{
|
||||
"entity": entity_ids[0],
|
||||
"value": VALUES[0],
|
||||
"value": str(VALUES[0]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
"device_class": SensorDeviceClass.HUMIDITY,
|
||||
@@ -980,7 +1068,7 @@ async def test_sensor_different_attributes_ignore_non_numeric(
|
||||
},
|
||||
{
|
||||
"entity": entity_ids[0],
|
||||
"value": VALUES[0],
|
||||
"value": str(VALUES[0]),
|
||||
"attributes": {
|
||||
"state_class": SensorStateClass.MEASUREMENT,
|
||||
},
|
||||
|
||||
@@ -439,54 +439,6 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[eve_thermo_v4][binary_sensor.eve_thermo_20ebp1701_outdoor_temperature_remote_sensing-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.eve_thermo_20ebp1701_outdoor_temperature_remote_sensing',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Outdoor temperature remote sensing',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_remote_sensing_outdoor_temperature',
|
||||
'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-ThermostatRemoteSensing_OutdoorTemperature-513-26',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[eve_thermo_v4][binary_sensor.eve_thermo_20ebp1701_outdoor_temperature_remote_sensing-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Eve Thermo 20EBP1701 Outdoor temperature remote sensing',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.eve_thermo_20ebp1701_outdoor_temperature_remote_sensing',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[eve_thermo_v5][binary_sensor.eve_thermo_20ecd1701_local_temperature_remote_sensing-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@@ -535,54 +487,6 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[eve_thermo_v5][binary_sensor.eve_thermo_20ecd1701_outdoor_temperature_remote_sensing-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.eve_thermo_20ecd1701_outdoor_temperature_remote_sensing',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Outdoor temperature remote sensing',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'thermostat_remote_sensing_outdoor_temperature',
|
||||
'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-ThermostatRemoteSensing_OutdoorTemperature-513-26',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[eve_thermo_v5][binary_sensor.eve_thermo_20ecd1701_outdoor_temperature_remote_sensing-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Eve Thermo 20ECD1701 Outdoor temperature remote sensing',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.eve_thermo_20ecd1701_outdoor_temperature_remote_sensing',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[heiman_motion_sensor_m1][binary_sensor.smart_motion_sensor_occupancy-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -7,6 +7,7 @@ import pytest
|
||||
|
||||
from homeassistant.components.namecheapdns.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
|
||||
from homeassistant.const import CONF_PASSWORD
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
@@ -14,6 +15,8 @@ from homeassistant.setup import async_setup_component
|
||||
|
||||
from .conftest import TEST_USER_INPUT
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_namecheap")
|
||||
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
@@ -140,3 +143,68 @@ async def test_init_import_flow(
|
||||
)
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_namecheap")
|
||||
async def test_reconfigure(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test reconfigure flow."""
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await config_entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_PASSWORD: "new-password"}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reconfigure_successful"
|
||||
assert config_entry.data[CONF_PASSWORD] == "new-password"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("side_effect", "text_error"),
|
||||
[
|
||||
(ValueError, "unknown"),
|
||||
(False, "update_failed"),
|
||||
(ClientError, "cannot_connect"),
|
||||
],
|
||||
)
|
||||
async def test_reconfigure_errors(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
mock_namecheap: AsyncMock,
|
||||
side_effect: Exception | bool,
|
||||
text_error: str,
|
||||
) -> None:
|
||||
"""Test we handle errors."""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await config_entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
mock_namecheap.side_effect = [side_effect]
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_PASSWORD: "new-password"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["errors"] == {"base": text_error}
|
||||
|
||||
mock_namecheap.side_effect = None
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_PASSWORD: "new-password"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reconfigure_successful"
|
||||
|
||||
assert config_entry.data[CONF_PASSWORD] == "new-password"
|
||||
|
||||
Reference in New Issue
Block a user