Strip out deleted entities when configuring homekit (#59844)

This commit is contained in:
J. Nick Koston 2021-11-18 17:21:51 -06:00 committed by GitHub
parent 8fb84270d5
commit 0fb21af07f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 11 deletions

View file

@ -330,13 +330,19 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
return self.async_create_entry(title="", data=self.hk_options) return self.async_create_entry(title="", data=self.hk_options)
all_supported_devices = await _async_get_supported_devices(self.hass) all_supported_devices = await _async_get_supported_devices(self.hass)
# Strip out devices that no longer exist to prevent error in the UI
devices = [
device_id
for device_id in self.hk_options.get(CONF_DEVICES, [])
if device_id in all_supported_devices
]
return self.async_show_form( return self.async_show_form(
step_id="advanced", step_id="advanced",
data_schema=vol.Schema( data_schema=vol.Schema(
{ {
vol.Optional( vol.Optional(CONF_DEVICES, default=devices): cv.multi_select(
CONF_DEVICES, default=self.hk_options.get(CONF_DEVICES, []) all_supported_devices
): cv.multi_select(all_supported_devices) )
} }
), ),
) )
@ -445,13 +451,16 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
) )
data_schema = {} data_schema = {}
entities = entity_filter.get(CONF_INCLUDE_ENTITIES, [])
if self.hk_options[CONF_HOMEKIT_MODE] == HOMEKIT_MODE_ACCESSORY:
entity_schema = vol.In entity_schema = vol.In
else: # Strip out entities that no longer exist to prevent error in the UI
if entities: entities = [
entity_id
for entity_id in entity_filter.get(CONF_INCLUDE_ENTITIES, [])
if entity_id in all_supported_entities
]
if self.hk_options[CONF_HOMEKIT_MODE] != HOMEKIT_MODE_ACCESSORY:
include_exclude_mode = MODE_INCLUDE include_exclude_mode = MODE_INCLUDE
else: if not entities:
include_exclude_mode = MODE_EXCLUDE include_exclude_mode = MODE_EXCLUDE
entities = entity_filter.get(CONF_EXCLUDE_ENTITIES, []) entities = entity_filter.get(CONF_EXCLUDE_ENTITIES, [])
data_schema[ data_schema[

View file

@ -365,7 +365,24 @@ async def test_options_flow_devices(
mock_hap, hass, demo_cleanup, device_reg, entity_reg, mock_get_source_ip mock_hap, hass, demo_cleanup, device_reg, entity_reg, mock_get_source_ip
): ):
"""Test devices can be bridged.""" """Test devices can be bridged."""
config_entry = _mock_config_entry_with_options_populated() config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
options={
"devices": ["notexist"],
"filter": {
"include_domains": [
"fan",
"humidifier",
"vacuum",
"media_player",
"climate",
"alarm_control_panel",
],
"exclude_entities": ["climate.front_gate"],
},
},
)
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
demo_config_entry = MockConfigEntry(domain="domain") demo_config_entry = MockConfigEntry(domain="domain")
@ -491,6 +508,60 @@ async def test_options_flow_devices_preserved_when_advanced_off(
} }
async def test_options_flow_with_non_existant_entity(hass, mock_get_source_ip):
"""Test config flow options in include mode."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
options={
"filter": {
"include_entities": ["climate.not_exist", "climate.front_gate"],
},
},
)
config_entry.add_to_hass(hass)
hass.states.async_set("climate.front_gate", "off")
hass.states.async_set("climate.new", "off")
await hass.async_block_till_done()
result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": False}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={"domains": ["fan", "vacuum", "climate"]},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "include_exclude"
entities = result["data_schema"]({})["entities"]
assert "climate.not_exist" not in entities
result2 = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
"entities": ["climate.new", "climate.front_gate"],
"include_exclude_mode": "include",
},
)
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
"mode": "bridge",
"filter": {
"exclude_domains": [],
"exclude_entities": [],
"include_domains": ["fan", "vacuum"],
"include_entities": ["climate.new", "climate.front_gate"],
},
}
async def test_options_flow_include_mode_basic(hass, mock_get_source_ip): async def test_options_flow_include_mode_basic(hass, mock_get_source_ip):
"""Test config flow options in include mode.""" """Test config flow options in include mode."""