mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Improve ESPHome abort messages for already-configured devices (#143289)
* Improve ESPHome abort messages for already-configured devices Users often struggle to identify which ESPHome device is already configured—especially when replacing a device or renaming an existing one. This PR improves the abort messages to include more helpful details, so users can pinpoint the conflicting device without needing to dig through the `core.config_entries` file manually. * Update homeassistant/components/esphome/strings.json
This commit is contained in:
parent
352ef0d009
commit
6698b3a1dc
@ -306,7 +306,32 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
updates[CONF_HOST] = host
|
||||
if port is not None:
|
||||
updates[CONF_PORT] = port
|
||||
self._abort_if_unique_id_configured(updates=updates)
|
||||
self._abort_unique_id_configured_with_details(updates=updates)
|
||||
|
||||
@callback
|
||||
def _abort_unique_id_configured_with_details(self, updates: dict[str, Any]) -> None:
|
||||
"""Abort if unique_id is already configured with details."""
|
||||
assert self.unique_id is not None
|
||||
if not (
|
||||
conflict_entry := self.hass.config_entries.async_entry_for_domain_unique_id(
|
||||
self.handler, self.unique_id
|
||||
)
|
||||
):
|
||||
return
|
||||
assert conflict_entry.unique_id is not None
|
||||
if updates:
|
||||
error = "already_configured_updates"
|
||||
else:
|
||||
error = "already_configured_detailed"
|
||||
self._abort_if_unique_id_configured(
|
||||
updates=updates,
|
||||
error=error,
|
||||
description_placeholders={
|
||||
"title": conflict_entry.title,
|
||||
"name": conflict_entry.data.get(CONF_DEVICE_NAME, "unknown"),
|
||||
"mac": format_mac(conflict_entry.unique_id),
|
||||
},
|
||||
)
|
||||
|
||||
async def async_step_mqtt(
|
||||
self, discovery_info: MqttServiceInfo
|
||||
@ -341,7 +366,7 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
# Check if already configured
|
||||
await self.async_set_unique_id(mac_address)
|
||||
self._abort_if_unique_id_configured(
|
||||
self._abort_unique_id_configured_with_details(
|
||||
updates={CONF_HOST: self._host, CONF_PORT: self._port}
|
||||
)
|
||||
|
||||
@ -479,7 +504,7 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
data=self._reauth_entry.data | self._async_make_config_data(),
|
||||
)
|
||||
assert self._host is not None
|
||||
self._abort_if_unique_id_configured(
|
||||
self._abort_unique_id_configured_with_details(
|
||||
updates={
|
||||
CONF_HOST: self._host,
|
||||
CONF_PORT: self._port,
|
||||
@ -510,7 +535,7 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
if not (
|
||||
unique_id_matches := (self.unique_id == self._reconfig_entry.unique_id)
|
||||
):
|
||||
self._abort_if_unique_id_configured(
|
||||
self._abort_unique_id_configured_with_details(
|
||||
updates={
|
||||
CONF_HOST: self._host,
|
||||
CONF_PORT: self._port,
|
||||
@ -640,7 +665,7 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
mac_address = format_mac(self._device_info.mac_address)
|
||||
await self.async_set_unique_id(mac_address, raise_on_progress=False)
|
||||
if self.source not in (SOURCE_REAUTH, SOURCE_RECONFIGURE):
|
||||
self._abort_if_unique_id_configured(
|
||||
self._abort_unique_id_configured_with_details(
|
||||
updates={
|
||||
CONF_HOST: self._host,
|
||||
CONF_PORT: self._port,
|
||||
|
@ -2,6 +2,8 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_configured_detailed": "A device `{name}`, with MAC address `{mac}` is already configured as `{title}`.",
|
||||
"already_configured_updates": "A device `{name}`, with MAC address `{mac}` is already configured as `{title}`; the existing configuration will be updated with the validated data.",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"mdns_missing_mac": "Missing MAC address in mDNS properties.",
|
||||
|
@ -119,7 +119,12 @@ async def test_user_connection_updates_host(
|
||||
data={CONF_HOST: "127.0.0.1", CONF_PORT: 80},
|
||||
)
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
assert entry.data[CONF_HOST] == "127.0.0.1"
|
||||
|
||||
|
||||
@ -173,7 +178,12 @@ async def test_user_sets_unique_id(
|
||||
{CONF_HOST: "127.0.0.1", CONF_PORT: 6053},
|
||||
)
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "test",
|
||||
"name": "test",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
@ -645,7 +655,12 @@ async def test_discovery_already_configured(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
|
||||
async def test_discovery_duplicate_data(
|
||||
@ -701,7 +716,12 @@ async def test_discovery_updates_unique_id(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
assert entry.unique_id == "11:22:33:44:55:aa"
|
||||
|
||||
@ -1159,7 +1179,12 @@ async def test_discovery_dhcp_updates_host(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
assert entry.data[CONF_HOST] == "192.168.43.184"
|
||||
|
||||
@ -1188,7 +1213,12 @@ async def test_discovery_dhcp_does_not_update_host_wrong_mac(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_detailed"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
# Mac was wrong, should not update
|
||||
assert entry.data[CONF_HOST] == "192.168.43.183"
|
||||
@ -1217,7 +1247,12 @@ async def test_discovery_dhcp_does_not_update_host_wrong_mac_bad_key(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_detailed"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
# Mac was wrong, should not update
|
||||
assert entry.data[CONF_HOST] == "192.168.43.183"
|
||||
@ -1246,7 +1281,12 @@ async def test_discovery_dhcp_does_not_update_host_missing_mac_bad_key(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_detailed"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "unknown",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
|
||||
# Mac was missing, should not update
|
||||
assert entry.data[CONF_HOST] == "192.168.43.183"
|
||||
@ -1999,7 +2039,12 @@ async def test_reconfig_mac_used_by_other_entry(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "test4",
|
||||
"mac": "11:22:33:44:55:bb",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf", "mock_setup_entry")
|
||||
|
@ -743,7 +743,12 @@ async def test_connection_aborted_wrong_device(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "test",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
assert entry.data[CONF_HOST] == "192.168.43.184"
|
||||
await hass.async_block_till_done()
|
||||
assert len(new_info.mock_calls) == 2
|
||||
@ -812,7 +817,12 @@ async def test_connection_aborted_wrong_device_same_name(
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert result["reason"] == "already_configured_updates"
|
||||
assert result["description_placeholders"] == {
|
||||
"title": "Mock Title",
|
||||
"name": "test",
|
||||
"mac": "11:22:33:44:55:aa",
|
||||
}
|
||||
assert entry.data[CONF_HOST] == "192.168.43.184"
|
||||
await hass.async_block_till_done()
|
||||
assert len(new_info.mock_calls) == 2
|
||||
|
Loading…
x
Reference in New Issue
Block a user