mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Improve Google Cast options flow (#50028)
This commit is contained in:
parent
3a36a976ee
commit
934d241b70
@ -107,53 +107,77 @@ class CastOptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
"""Handle Google Cast options."""
|
"""Handle Google Cast options."""
|
||||||
|
|
||||||
def __init__(self, config_entry):
|
def __init__(self, config_entry):
|
||||||
"""Initialize MQTT options flow."""
|
"""Initialize Google Cast options flow."""
|
||||||
self.config_entry = config_entry
|
self.config_entry = config_entry
|
||||||
self.broker_config = {}
|
self.updated_config = {}
|
||||||
self.options = dict(config_entry.options)
|
|
||||||
|
|
||||||
async def async_step_init(self, user_input=None):
|
async def async_step_init(self, user_input=None):
|
||||||
"""Manage the Cast options."""
|
"""Manage the Google Cast options."""
|
||||||
return await self.async_step_options()
|
return await self.async_step_basic_options()
|
||||||
|
|
||||||
async def async_step_options(self, user_input=None):
|
async def async_step_basic_options(self, user_input=None):
|
||||||
"""Manage the MQTT options."""
|
"""Manage the Google Cast options."""
|
||||||
errors = {}
|
errors = {}
|
||||||
current_config = self.config_entry.data
|
current_config = self.config_entry.data
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
bad_cec, ignore_cec = _string_to_list(
|
|
||||||
user_input.get(CONF_IGNORE_CEC, ""), IGNORE_CEC_SCHEMA
|
|
||||||
)
|
|
||||||
bad_hosts, known_hosts = _string_to_list(
|
bad_hosts, known_hosts = _string_to_list(
|
||||||
user_input.get(CONF_KNOWN_HOSTS, ""), KNOWN_HOSTS_SCHEMA
|
user_input.get(CONF_KNOWN_HOSTS, ""), KNOWN_HOSTS_SCHEMA
|
||||||
)
|
)
|
||||||
bad_uuid, wanted_uuid = _string_to_list(
|
|
||||||
user_input.get(CONF_UUID, ""), WANTED_UUID_SCHEMA
|
|
||||||
)
|
|
||||||
|
|
||||||
if not bad_cec and not bad_hosts and not bad_uuid:
|
if not bad_hosts:
|
||||||
updated_config = dict(current_config)
|
self.updated_config = dict(current_config)
|
||||||
updated_config[CONF_IGNORE_CEC] = ignore_cec
|
self.updated_config[CONF_KNOWN_HOSTS] = known_hosts
|
||||||
updated_config[CONF_KNOWN_HOSTS] = known_hosts
|
|
||||||
updated_config[CONF_UUID] = wanted_uuid
|
if self.show_advanced_options:
|
||||||
|
return await self.async_step_advanced_options()
|
||||||
|
|
||||||
self.hass.config_entries.async_update_entry(
|
self.hass.config_entries.async_update_entry(
|
||||||
self.config_entry, data=updated_config
|
self.config_entry, data=self.updated_config
|
||||||
)
|
)
|
||||||
return self.async_create_entry(title="", data=None)
|
return self.async_create_entry(title="", data=None)
|
||||||
|
|
||||||
fields = {}
|
fields = {}
|
||||||
suggested_value = _list_to_string(current_config.get(CONF_KNOWN_HOSTS))
|
suggested_value = _list_to_string(current_config.get(CONF_KNOWN_HOSTS))
|
||||||
_add_with_suggestion(fields, CONF_KNOWN_HOSTS, suggested_value)
|
_add_with_suggestion(fields, CONF_KNOWN_HOSTS, suggested_value)
|
||||||
if self.show_advanced_options:
|
|
||||||
suggested_value = _list_to_string(current_config.get(CONF_UUID))
|
|
||||||
_add_with_suggestion(fields, CONF_UUID, suggested_value)
|
|
||||||
suggested_value = _list_to_string(current_config.get(CONF_IGNORE_CEC))
|
|
||||||
_add_with_suggestion(fields, CONF_IGNORE_CEC, suggested_value)
|
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="options",
|
step_id="basic_options",
|
||||||
data_schema=vol.Schema(fields),
|
data_schema=vol.Schema(fields),
|
||||||
errors=errors,
|
errors=errors,
|
||||||
|
last_step=not self.show_advanced_options,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_advanced_options(self, user_input=None):
|
||||||
|
"""Manage the Google Cast options."""
|
||||||
|
errors = {}
|
||||||
|
if user_input is not None:
|
||||||
|
bad_cec, ignore_cec = _string_to_list(
|
||||||
|
user_input.get(CONF_IGNORE_CEC, ""), IGNORE_CEC_SCHEMA
|
||||||
|
)
|
||||||
|
bad_uuid, wanted_uuid = _string_to_list(
|
||||||
|
user_input.get(CONF_UUID, ""), WANTED_UUID_SCHEMA
|
||||||
|
)
|
||||||
|
|
||||||
|
if not bad_cec and not bad_uuid:
|
||||||
|
self.updated_config[CONF_IGNORE_CEC] = ignore_cec
|
||||||
|
self.updated_config[CONF_UUID] = wanted_uuid
|
||||||
|
self.hass.config_entries.async_update_entry(
|
||||||
|
self.config_entry, data=self.updated_config
|
||||||
|
)
|
||||||
|
return self.async_create_entry(title="", data=None)
|
||||||
|
|
||||||
|
fields = {}
|
||||||
|
current_config = self.config_entry.data
|
||||||
|
suggested_value = _list_to_string(current_config.get(CONF_UUID))
|
||||||
|
_add_with_suggestion(fields, CONF_UUID, suggested_value)
|
||||||
|
suggested_value = _list_to_string(current_config.get(CONF_IGNORE_CEC))
|
||||||
|
_add_with_suggestion(fields, CONF_IGNORE_CEC, suggested_value)
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="advanced_options",
|
||||||
|
data_schema=vol.Schema(fields),
|
||||||
|
errors=errors,
|
||||||
|
last_step=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
"description": "[%key:common::config_flow::description::confirm_setup%]"
|
"description": "[%key:common::config_flow::description::confirm_setup%]"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"title": "Google Cast",
|
"title": "Google Cast configuration",
|
||||||
"description": "Please enter the Google Cast configuration.",
|
"description": "Known Hosts - A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
|
||||||
"data": {
|
"data": {
|
||||||
"known_hosts": "Optional list of known hosts if mDNS discovery is not working."
|
"known_hosts": "Known hosts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -21,12 +21,19 @@
|
|||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"step": {
|
"step": {
|
||||||
"options": {
|
"basic_options": {
|
||||||
"description": "Please enter the Google Cast configuration.",
|
"title": "Google Cast configuration",
|
||||||
|
"description": "Known Hosts - A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
|
||||||
"data": {
|
"data": {
|
||||||
"ignore_cec": "Optional list which will be passed to pychromecast.IGNORE_CEC.",
|
"known_hosts": "Known hosts"
|
||||||
"known_hosts": "Optional list of known hosts if mDNS discovery is not working.",
|
}
|
||||||
"uuid": "Optional list of UUIDs. Casts not listed will not be added."
|
},
|
||||||
|
"advanced_options": {
|
||||||
|
"title": "Advanced Google Cast configuration",
|
||||||
|
"description": "Allowed UUIDs - A comma-separated list of UUIDs of Cast devices to add to Home Assistant. Use only if you don’t want to add all available cast devices.\nIgnore CEC - A comma-separated list of Chromecasts that should ignore CEC data for determining the active input. This will be will be passed to pychromecast.IGNORE_CEC.",
|
||||||
|
"data": {
|
||||||
|
"ignore_cec": "Ignore CEC",
|
||||||
|
"uuid": "Allowed UUIDs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"abort": {
|
"abort": {
|
||||||
"no_devices_found": "No devices found on the network",
|
|
||||||
"single_instance_allowed": "Already configured. Only a single configuration possible."
|
"single_instance_allowed": "Already configured. Only a single configuration possible."
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
@ -10,10 +9,10 @@
|
|||||||
"step": {
|
"step": {
|
||||||
"config": {
|
"config": {
|
||||||
"data": {
|
"data": {
|
||||||
"known_hosts": "Optional list of known hosts if mDNS discovery is not working."
|
"known_hosts": "Known hosts"
|
||||||
},
|
},
|
||||||
"description": "Please enter the Google Cast configuration.",
|
"description": "### Known Hosts \n A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
|
||||||
"title": "Google Cast"
|
"title": "Google Cast configuration"
|
||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"description": "Do you want to start set up?"
|
"description": "Do you want to start set up?"
|
||||||
@ -25,13 +24,20 @@
|
|||||||
"invalid_known_hosts": "Known hosts must be a comma separated list of hosts."
|
"invalid_known_hosts": "Known hosts must be a comma separated list of hosts."
|
||||||
},
|
},
|
||||||
"step": {
|
"step": {
|
||||||
"options": {
|
"advanced_options": {
|
||||||
"data": {
|
"data": {
|
||||||
"ignore_cec": "Optional list which will be passed to pychromecast.IGNORE_CEC.",
|
"ignore_cec": "Ignore CEC",
|
||||||
"known_hosts": "Optional list of known hosts if mDNS discovery is not working.",
|
"uuid": "Allowed UUIDs"
|
||||||
"uuid": "Optional list of UUIDs. Casts not listed will not be added."
|
|
||||||
},
|
},
|
||||||
"description": "Please enter the Google Cast configuration."
|
"description": "### Allowed UUIDs\n A comma-separated list of UUIDs of Cast devices to add to Home Assistant. **Use only if you don\u2019t want to add all available cast devices.** \n ### Ignore CEC \n A comma-separated list of Chromecasts that should ignore CEC data for determining the active input. This will be will be passed to pychromecast.IGNORE_CEC. [See the upstream documentation for more information](https://github.com/balloob/pychromecast#ignoring-cec-data).",
|
||||||
|
"title": "Advanced Google Cast configuration"
|
||||||
|
},
|
||||||
|
"basic_options": {
|
||||||
|
"data": {
|
||||||
|
"known_hosts": "Known hosts"
|
||||||
|
},
|
||||||
|
"description": "### Known Hosts \n A comma-separated list of hostnames or IP-addresses of cast devices, use if mDNS discovery is not working.",
|
||||||
|
"title": "Google Cast configuration"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,8 @@ def get_suggested(schema, key):
|
|||||||
)
|
)
|
||||||
async def test_option_flow(hass, parameter_data):
|
async def test_option_flow(hass, parameter_data):
|
||||||
"""Test config flow options."""
|
"""Test config flow options."""
|
||||||
all_parameters = ["ignore_cec", "known_hosts", "uuid"]
|
basic_parameters = ["known_hosts"]
|
||||||
|
advanced_parameters = ["ignore_cec", "uuid"]
|
||||||
parameter, initial, suggested, user_input, updated = parameter_data
|
parameter, initial, suggested, user_input, updated = parameter_data
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
@ -170,32 +171,61 @@ async def test_option_flow(hass, parameter_data):
|
|||||||
# Test ignore_cec and uuid options are hidden if advanced options are disabled
|
# Test ignore_cec and uuid options are hidden if advanced options are disabled
|
||||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "options"
|
assert result["step_id"] == "basic_options"
|
||||||
data_schema = result["data_schema"].schema
|
data_schema = result["data_schema"].schema
|
||||||
assert set(data_schema) == {"known_hosts"}
|
assert set(data_schema) == {"known_hosts"}
|
||||||
orig_data = dict(config_entry.data)
|
orig_data = dict(config_entry.data)
|
||||||
|
|
||||||
# Reconfigure ignore_cec, known_hosts, uuid
|
# Reconfigure known_hosts
|
||||||
context = {"source": config_entries.SOURCE_USER, "show_advanced_options": True}
|
context = {"source": config_entries.SOURCE_USER, "show_advanced_options": True}
|
||||||
result = await hass.config_entries.options.async_init(
|
result = await hass.config_entries.options.async_init(
|
||||||
config_entry.entry_id, context=context
|
config_entry.entry_id, context=context
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "options"
|
assert result["step_id"] == "basic_options"
|
||||||
data_schema = result["data_schema"].schema
|
data_schema = result["data_schema"].schema
|
||||||
for other_param in all_parameters:
|
for other_param in basic_parameters:
|
||||||
if other_param == parameter:
|
if other_param == parameter:
|
||||||
continue
|
continue
|
||||||
assert get_suggested(data_schema, other_param) == ""
|
assert get_suggested(data_schema, other_param) == ""
|
||||||
assert get_suggested(data_schema, parameter) == suggested
|
if parameter in basic_parameters:
|
||||||
|
assert get_suggested(data_schema, parameter) == suggested
|
||||||
|
|
||||||
|
user_input_dict = {}
|
||||||
|
if parameter in basic_parameters:
|
||||||
|
user_input_dict[parameter] = user_input
|
||||||
result = await hass.config_entries.options.async_configure(
|
result = await hass.config_entries.options.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={parameter: user_input},
|
user_input=user_input_dict,
|
||||||
|
)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "advanced_options"
|
||||||
|
for other_param in basic_parameters:
|
||||||
|
if other_param == parameter:
|
||||||
|
continue
|
||||||
|
assert config_entry.data[other_param] == []
|
||||||
|
# No update yet
|
||||||
|
assert config_entry.data[parameter] == initial
|
||||||
|
|
||||||
|
# Reconfigure ignore_cec, uuid
|
||||||
|
data_schema = result["data_schema"].schema
|
||||||
|
for other_param in advanced_parameters:
|
||||||
|
if other_param == parameter:
|
||||||
|
continue
|
||||||
|
assert get_suggested(data_schema, other_param) == ""
|
||||||
|
if parameter in advanced_parameters:
|
||||||
|
assert get_suggested(data_schema, parameter) == suggested
|
||||||
|
|
||||||
|
user_input_dict = {}
|
||||||
|
if parameter in advanced_parameters:
|
||||||
|
user_input_dict[parameter] = user_input
|
||||||
|
result = await hass.config_entries.options.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input=user_input_dict,
|
||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["data"] is None
|
assert result["data"] is None
|
||||||
for other_param in all_parameters:
|
for other_param in advanced_parameters:
|
||||||
if other_param == parameter:
|
if other_param == parameter:
|
||||||
continue
|
continue
|
||||||
assert config_entry.data[other_param] == []
|
assert config_entry.data[other_param] == []
|
||||||
@ -209,12 +239,10 @@ async def test_option_flow(hass, parameter_data):
|
|||||||
)
|
)
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["data"] is None
|
assert result["data"] is None
|
||||||
assert config_entry.data == {
|
expected_data = {**orig_data, "known_hosts": []}
|
||||||
**orig_data,
|
if parameter in advanced_parameters:
|
||||||
"ignore_cec": [],
|
expected_data[parameter] = updated
|
||||||
"known_hosts": [],
|
assert dict(config_entry.data) == expected_data
|
||||||
"uuid": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_known_hosts(hass, castbrowser_mock, castbrowser_constructor_mock):
|
async def test_known_hosts(hass, castbrowser_mock, castbrowser_constructor_mock):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user