diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py index 560fb0663a8..4768d58379a 100644 --- a/homeassistant/components/bluetooth/__init__.py +++ b/homeassistant/components/bluetooth/__init__.py @@ -86,6 +86,7 @@ from .manager import HomeAssistantBluetoothManager from .match import BluetoothCallbackMatcher, IntegrationMatcher from .models import BluetoothCallback, BluetoothChange from .storage import BluetoothStorage +from .util import adapter_title if TYPE_CHECKING: from homeassistant.helpers.typing import ConfigType @@ -332,6 +333,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: ) from err adapters = await manager.async_get_bluetooth_adapters() details = adapters[adapter] + if entry.title == address: + hass.config_entries.async_update_entry( + entry, title=adapter_title(adapter, details) + ) slots: int = details.get(ADAPTER_CONNECTION_SLOTS) or DEFAULT_CONNECTION_SLOTS entry.async_on_unload(async_register_scanner(hass, scanner, connection_slots=slots)) await async_update_device(hass, entry, adapter, details) diff --git a/homeassistant/components/bluetooth/config_flow.py b/homeassistant/components/bluetooth/config_flow.py index 87038d48151..90d2624fb0f 100644 --- a/homeassistant/components/bluetooth/config_flow.py +++ b/homeassistant/components/bluetooth/config_flow.py @@ -12,7 +12,6 @@ from bluetooth_adapters import ( AdapterDetails, adapter_human_name, adapter_model, - adapter_unique_name, get_adapters, ) import voluptuous as vol @@ -28,6 +27,7 @@ from homeassistant.helpers.typing import DiscoveryInfoType from . import models from .const import CONF_ADAPTER, CONF_DETAILS, CONF_PASSIVE, DOMAIN +from .util import adapter_title OPTIONS_SCHEMA = vol.Schema( { @@ -47,14 +47,6 @@ def adapter_display_info(adapter: str, details: AdapterDetails) -> str: return f"{name} {manufacturer} {model}" -def adapter_title(adapter: str, details: AdapterDetails) -> str: - """Return the adapter title.""" - unique_name = adapter_unique_name(adapter, details[ADAPTER_ADDRESS]) - model = adapter_model(details) - manufacturer = details[ADAPTER_MANUFACTURER] or "Unknown" - return f"{manufacturer} {model} ({unique_name})" - - class BluetoothConfigFlow(ConfigFlow, domain=DOMAIN): """Config flow for Bluetooth.""" diff --git a/homeassistant/components/bluetooth/util.py b/homeassistant/components/bluetooth/util.py index 0faac9a8613..8c7ad13294a 100644 --- a/homeassistant/components/bluetooth/util.py +++ b/homeassistant/components/bluetooth/util.py @@ -2,7 +2,14 @@ from __future__ import annotations -from bluetooth_adapters import BluetoothAdapters +from bluetooth_adapters import ( + ADAPTER_ADDRESS, + ADAPTER_MANUFACTURER, + ADAPTER_PRODUCT, + AdapterDetails, + BluetoothAdapters, + adapter_unique_name, +) from bluetooth_data_tools import monotonic_time_coarse from homeassistant.core import callback @@ -69,3 +76,12 @@ def async_load_history_from_system( connectable_loaded_history[address] = service_info return all_loaded_history, connectable_loaded_history + + +@callback +def adapter_title(adapter: str, details: AdapterDetails) -> str: + """Return the adapter title.""" + unique_name = adapter_unique_name(adapter, details[ADAPTER_ADDRESS]) + model = details.get(ADAPTER_PRODUCT, "Unknown") + manufacturer = details[ADAPTER_MANUFACTURER] or "Unknown" + return f"{manufacturer} {model} ({unique_name})" diff --git a/tests/components/bluetooth/test_config_flow.py b/tests/components/bluetooth/test_config_flow.py index d044be76e6d..33474280ec4 100644 --- a/tests/components/bluetooth/test_config_flow.py +++ b/tests/components/bluetooth/test_config_flow.py @@ -99,9 +99,7 @@ async def test_async_step_user_linux_one_adapter( result["flow_id"], user_input={} ) assert result2["type"] is FlowResultType.CREATE_ENTRY - assert ( - result2["title"] == "ACME Bluetooth Adapter 5.0 (cc01:aa01) (00:00:00:00:00:01)" - ) + assert result2["title"] == "ACME Bluetooth Adapter 5.0 (00:00:00:00:00:01)" assert result2["data"] == {} assert len(mock_setup_entry.mock_calls) == 1 @@ -144,9 +142,7 @@ async def test_async_step_user_linux_two_adapters( result["flow_id"], user_input={CONF_ADAPTER: "hci1"} ) assert result2["type"] is FlowResultType.CREATE_ENTRY - assert ( - result2["title"] == "ACME Bluetooth Adapter 5.0 (cc01:aa01) (00:00:00:00:00:02)" - ) + assert result2["title"] == "ACME Bluetooth Adapter 5.0 (00:00:00:00:00:02)" assert result2["data"] == {} assert len(mock_setup_entry.mock_calls) == 1 diff --git a/tests/components/bluetooth/test_init.py b/tests/components/bluetooth/test_init.py index 82fa0341966..8c26745d541 100644 --- a/tests/components/bluetooth/test_init.py +++ b/tests/components/bluetooth/test_init.py @@ -3173,3 +3173,16 @@ async def test_haos_9_or_later( registry = async_get_issue_registry(hass) issue = registry.async_get_issue(DOMAIN, "haos_outdated") assert issue is None + + +async def test_title_updated_if_mac_address( + hass: HomeAssistant, mock_bleak_scanner_start: MagicMock, one_adapter: None +) -> None: + """Test the title is updated if it is the mac address.""" + entry = MockConfigEntry( + domain="bluetooth", title="00:00:00:00:00:01", unique_id="00:00:00:00:00:01" + ) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + assert entry.title == "ACME Bluetooth Adapter 5.0 (00:00:00:00:00:01)"