mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Add ability to remove sensors in scrape config flow (#82912)
* Add ability to remove sensors in scrape config flow * Add test * Cleanup registry * Cleanup * Adjust comments * Fix bad cleanup
This commit is contained in:
parent
ce1b2f45c7
commit
23831d746e
@ -12,6 +12,7 @@ from homeassistant.components.rest.data import DEFAULT_TIMEOUT
|
|||||||
from homeassistant.components.rest.schema import DEFAULT_METHOD, METHODS
|
from homeassistant.components.rest.schema import DEFAULT_METHOD, METHODS
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
CONF_STATE_CLASS,
|
CONF_STATE_CLASS,
|
||||||
|
DOMAIN as SENSOR_DOMAIN,
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorStateClass,
|
SensorStateClass,
|
||||||
)
|
)
|
||||||
@ -35,6 +36,7 @@ from homeassistant.const import (
|
|||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
)
|
)
|
||||||
from homeassistant.core import async_get_hass
|
from homeassistant.core import async_get_hass
|
||||||
|
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||||
from homeassistant.helpers.schema_config_entry_flow import (
|
from homeassistant.helpers.schema_config_entry_flow import (
|
||||||
SchemaCommonFlowHandler,
|
SchemaCommonFlowHandler,
|
||||||
SchemaConfigFlowHandler,
|
SchemaConfigFlowHandler,
|
||||||
@ -136,11 +138,47 @@ def validate_sensor_setup(
|
|||||||
|
|
||||||
# Standard behavior is to merge the result with the options.
|
# Standard behavior is to merge the result with the options.
|
||||||
# In this case, we want to add a sub-item so we update the options directly.
|
# In this case, we want to add a sub-item so we update the options directly.
|
||||||
sensors: list[dict[str, Any]] = handler.options.setdefault("sensor", [])
|
sensors: list[dict[str, Any]] = handler.options.setdefault(SENSOR_DOMAIN, [])
|
||||||
sensors.append(user_input)
|
sensors.append(user_input)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_remove_sensor_schema(handler: SchemaCommonFlowHandler) -> vol.Schema:
|
||||||
|
"""Return schema for sensor removal."""
|
||||||
|
return vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_INDEX): cv.multi_select(
|
||||||
|
{
|
||||||
|
str(index): config[CONF_NAME]
|
||||||
|
for index, config in enumerate(handler.options[SENSOR_DOMAIN])
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_remove_sensor(
|
||||||
|
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Validate remove sensor."""
|
||||||
|
removed_indexes: set[str] = set(user_input[CONF_INDEX])
|
||||||
|
|
||||||
|
# Standard behavior is to merge the result with the options.
|
||||||
|
# In this case, we want to remove sub-items so we update the options directly.
|
||||||
|
entity_registry = er.async_get(handler.parent_handler.hass)
|
||||||
|
sensors: list[dict[str, Any]] = []
|
||||||
|
sensor: dict[str, Any]
|
||||||
|
for index, sensor in enumerate(handler.options[SENSOR_DOMAIN]):
|
||||||
|
if str(index) not in removed_indexes:
|
||||||
|
sensors.append(sensor)
|
||||||
|
elif entity_id := entity_registry.async_get_entity_id(
|
||||||
|
SENSOR_DOMAIN, DOMAIN, sensor[CONF_UNIQUE_ID]
|
||||||
|
):
|
||||||
|
entity_registry.async_remove(entity_id)
|
||||||
|
handler.options[SENSOR_DOMAIN] = sensors
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
DATA_SCHEMA_RESOURCE = vol.Schema(RESOURCE_SETUP)
|
DATA_SCHEMA_RESOURCE = vol.Schema(RESOURCE_SETUP)
|
||||||
DATA_SCHEMA_SENSOR = vol.Schema(SENSOR_SETUP)
|
DATA_SCHEMA_SENSOR = vol.Schema(SENSOR_SETUP)
|
||||||
|
|
||||||
@ -156,7 +194,7 @@ CONFIG_FLOW = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
OPTIONS_FLOW = {
|
OPTIONS_FLOW = {
|
||||||
"init": SchemaFlowMenuStep(["resource", "add_sensor"]),
|
"init": SchemaFlowMenuStep(["resource", "add_sensor", "remove_sensor"]),
|
||||||
"resource": SchemaFlowFormStep(
|
"resource": SchemaFlowFormStep(
|
||||||
DATA_SCHEMA_RESOURCE,
|
DATA_SCHEMA_RESOURCE,
|
||||||
validate_user_input=validate_rest_setup,
|
validate_user_input=validate_rest_setup,
|
||||||
@ -166,6 +204,11 @@ OPTIONS_FLOW = {
|
|||||||
suggested_values=None,
|
suggested_values=None,
|
||||||
validate_user_input=validate_sensor_setup,
|
validate_user_input=validate_sensor_setup,
|
||||||
),
|
),
|
||||||
|
"remove_sensor": SchemaFlowFormStep(
|
||||||
|
get_remove_sensor_schema,
|
||||||
|
suggested_values=None,
|
||||||
|
validate_user_input=validate_remove_sensor,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
"init": {
|
"init": {
|
||||||
"menu_options": {
|
"menu_options": {
|
||||||
"add_sensor": "Add sensor",
|
"add_sensor": "Add sensor",
|
||||||
|
"remove_sensor": "Remove sensor",
|
||||||
"resource": "Configure resource"
|
"resource": "Configure resource"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
"init": {
|
"init": {
|
||||||
"menu_options": {
|
"menu_options": {
|
||||||
"add_sensor": "Add sensor",
|
"add_sensor": "Add sensor",
|
||||||
|
"remove_sensor": "Remove sensor",
|
||||||
"resource": "Configure resource"
|
"resource": "Configure resource"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -221,10 +221,10 @@ async def test_options_resource_flow(
|
|||||||
assert state.state == "Hidden Version: 2021.12.10"
|
assert state.state == "Hidden Version: 2021.12.10"
|
||||||
|
|
||||||
|
|
||||||
async def test_options_add_sensor_flow(
|
async def test_options_add_remove_sensor_flow(
|
||||||
hass: HomeAssistant, loaded_entry: MockConfigEntry
|
hass: HomeAssistant, loaded_entry: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test options flow to add a sensor."""
|
"""Test options flow to add and remove a sensor."""
|
||||||
|
|
||||||
state = hass.states.get("sensor.current_version")
|
state = hass.states.get("sensor.current_version")
|
||||||
assert state.state == "Current Version: 2021.12.10"
|
assert state.state == "Current Version: 2021.12.10"
|
||||||
@ -290,3 +290,53 @@ async def test_options_add_sensor_flow(
|
|||||||
|
|
||||||
state = hass.states.get("sensor.template")
|
state = hass.states.get("sensor.template")
|
||||||
assert state.state == "Trying to get"
|
assert state.state == "Trying to get"
|
||||||
|
|
||||||
|
# Now remove the original sensor
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_init(loaded_entry.entry_id)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.MENU
|
||||||
|
assert result["step_id"] == "init"
|
||||||
|
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{"next_step_id": "remove_sensor"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "remove_sensor"
|
||||||
|
|
||||||
|
mocker = MockRestData("test_scrape_sensor2")
|
||||||
|
with patch("homeassistant.components.rest.RestData", return_value=mocker):
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={
|
||||||
|
CONF_INDEX: ["0"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["data"] == {
|
||||||
|
CONF_RESOURCE: "https://www.home-assistant.io",
|
||||||
|
CONF_METHOD: "GET",
|
||||||
|
CONF_VERIFY_SSL: True,
|
||||||
|
CONF_TIMEOUT: 10,
|
||||||
|
"sensor": [
|
||||||
|
{
|
||||||
|
CONF_NAME: "Template",
|
||||||
|
CONF_SELECT: "template",
|
||||||
|
CONF_INDEX: 0,
|
||||||
|
CONF_UNIQUE_ID: "3699ef88-69e6-11ed-a1eb-0242ac120003",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
# Check the original entity was removed, with only the new entity left
|
||||||
|
assert len(hass.states.async_all()) == 1
|
||||||
|
|
||||||
|
# Check the state of the new entity
|
||||||
|
state = hass.states.get("sensor.template")
|
||||||
|
assert state.state == "Trying to get"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user