mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 17:57:55 +00:00
Bump bleak-esphome to 2.9.0 (#139467)
* Bump bleak-esphome to 2.9.0 changelog: https://github.com/Bluetooth-Devices/bleak-esphome/compare/v2.8.0...v2.9.0 * fixes
This commit is contained in:
parent
db05aa17d3
commit
ee1fe2cae4
@ -22,5 +22,5 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["eq3btsmart"],
|
||||
"requirements": ["eq3btsmart==1.4.1", "bleak-esphome==2.8.0"]
|
||||
"requirements": ["eq3btsmart==1.4.1", "bleak-esphome==2.9.0"]
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import CONF_NOISE_PSK, DATA_FFMPEG_PROXY, DOMAIN
|
||||
from .const import CONF_BLUETOOTH_MAC_ADDRESS, CONF_NOISE_PSK, DATA_FFMPEG_PROXY, DOMAIN
|
||||
from .dashboard import async_setup as async_setup_dashboard
|
||||
from .domain_data import DomainData
|
||||
|
||||
@ -87,6 +87,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ESPHomeConfigEntry) ->
|
||||
|
||||
async def async_remove_entry(hass: HomeAssistant, entry: ESPHomeConfigEntry) -> None:
|
||||
"""Remove an esphome config entry."""
|
||||
if mac_address := entry.unique_id:
|
||||
async_remove_scanner(hass, mac_address.upper())
|
||||
if bluetooth_mac_address := entry.data.get(CONF_BLUETOOTH_MAC_ADDRESS):
|
||||
async_remove_scanner(hass, bluetooth_mac_address.upper())
|
||||
await DomainData.get(hass).get_or_create_store(hass, entry).async_remove()
|
||||
|
@ -8,6 +8,7 @@ CONF_ALLOW_SERVICE_CALLS = "allow_service_calls"
|
||||
CONF_SUBSCRIBE_LOGS = "subscribe_logs"
|
||||
CONF_DEVICE_NAME = "device_name"
|
||||
CONF_NOISE_PSK = "noise_psk"
|
||||
CONF_BLUETOOTH_MAC_ADDRESS = "bluetooth_mac_address"
|
||||
|
||||
DEFAULT_ALLOW_SERVICE_CALLS = True
|
||||
DEFAULT_NEW_CONFIG_ALLOW_ALLOW_SERVICE_CALLS = False
|
||||
|
@ -25,13 +25,17 @@ async def async_get_config_entry_diagnostics(
|
||||
diag["config"] = config_entry.as_dict()
|
||||
|
||||
entry_data = config_entry.runtime_data
|
||||
device_info = entry_data.device_info
|
||||
|
||||
if (storage_data := await entry_data.store.async_load()) is not None:
|
||||
diag["storage_data"] = storage_data
|
||||
|
||||
if (
|
||||
config_entry.unique_id
|
||||
and (scanner := async_scanner_by_source(hass, config_entry.unique_id.upper()))
|
||||
device_info
|
||||
and (
|
||||
scanner_mac := device_info.bluetooth_mac_address or device_info.mac_address
|
||||
)
|
||||
and (scanner := async_scanner_by_source(hass, scanner_mac.upper()))
|
||||
and (bluetooth_device := entry_data.bluetooth_device)
|
||||
):
|
||||
diag["bluetooth"] = {
|
||||
|
@ -63,6 +63,7 @@ from homeassistant.util.async_ import create_eager_task
|
||||
from .bluetooth import async_connect_scanner
|
||||
from .const import (
|
||||
CONF_ALLOW_SERVICE_CALLS,
|
||||
CONF_BLUETOOTH_MAC_ADDRESS,
|
||||
CONF_DEVICE_NAME,
|
||||
CONF_SUBSCRIBE_LOGS,
|
||||
DEFAULT_ALLOW_SERVICE_CALLS,
|
||||
@ -431,6 +432,13 @@ class ESPHomeManager:
|
||||
|
||||
device_mac = format_mac(device_info.mac_address)
|
||||
mac_address_matches = unique_id == device_mac
|
||||
if (
|
||||
bluetooth_mac_address := device_info.bluetooth_mac_address
|
||||
) and entry.data.get(CONF_BLUETOOTH_MAC_ADDRESS) != bluetooth_mac_address:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
data={**entry.data, CONF_BLUETOOTH_MAC_ADDRESS: bluetooth_mac_address},
|
||||
)
|
||||
#
|
||||
# Migrate config entry to new unique ID if the current
|
||||
# unique id is not a mac address.
|
||||
@ -498,7 +506,9 @@ class ESPHomeManager:
|
||||
)
|
||||
)
|
||||
else:
|
||||
bluetooth.async_remove_scanner(hass, device_info.mac_address)
|
||||
bluetooth.async_remove_scanner(
|
||||
hass, device_info.bluetooth_mac_address or device_info.mac_address
|
||||
)
|
||||
|
||||
if device_info.voice_assistant_feature_flags_compat(api_version) and (
|
||||
Platform.ASSIST_SATELLITE not in entry_data.loaded_platforms
|
||||
@ -617,11 +627,22 @@ class ESPHomeManager:
|
||||
)
|
||||
_setup_services(hass, entry_data, services)
|
||||
|
||||
if entry_data.device_info is not None and entry_data.device_info.name:
|
||||
reconnect_logic.name = entry_data.device_info.name
|
||||
if (device_info := entry_data.device_info) is not None:
|
||||
if device_info.name:
|
||||
reconnect_logic.name = device_info.name
|
||||
if (
|
||||
bluetooth_mac_address := device_info.bluetooth_mac_address
|
||||
) and entry.data.get(CONF_BLUETOOTH_MAC_ADDRESS) != bluetooth_mac_address:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
data={
|
||||
**entry.data,
|
||||
CONF_BLUETOOTH_MAC_ADDRESS: bluetooth_mac_address,
|
||||
},
|
||||
)
|
||||
if entry.unique_id is None:
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, unique_id=format_mac(entry_data.device_info.mac_address)
|
||||
entry, unique_id=format_mac(device_info.mac_address)
|
||||
)
|
||||
|
||||
await reconnect_logic.start()
|
||||
|
@ -18,7 +18,7 @@
|
||||
"requirements": [
|
||||
"aioesphomeapi==29.3.1",
|
||||
"esphome-dashboard-api==1.2.3",
|
||||
"bleak-esphome==2.8.0"
|
||||
"bleak-esphome==2.9.0"
|
||||
],
|
||||
"zeroconf": ["_esphomelib._tcp.local."]
|
||||
}
|
||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -603,7 +603,7 @@ bizkaibus==0.1.1
|
||||
|
||||
# homeassistant.components.eq3btsmart
|
||||
# homeassistant.components.esphome
|
||||
bleak-esphome==2.8.0
|
||||
bleak-esphome==2.9.0
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
bleak-retry-connector==3.9.0
|
||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -534,7 +534,7 @@ bimmer-connected[china]==0.17.2
|
||||
|
||||
# homeassistant.components.eq3btsmart
|
||||
# homeassistant.components.esphome
|
||||
bleak-esphome==2.8.0
|
||||
bleak-esphome==2.9.0
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
bleak-retry-connector==3.9.0
|
||||
|
@ -30,6 +30,7 @@ from zeroconf import Zeroconf
|
||||
from homeassistant.components.esphome import dashboard
|
||||
from homeassistant.components.esphome.const import (
|
||||
CONF_ALLOW_SERVICE_CALLS,
|
||||
CONF_BLUETOOTH_MAC_ADDRESS,
|
||||
CONF_DEVICE_NAME,
|
||||
CONF_NOISE_PSK,
|
||||
DEFAULT_NEW_CONFIG_ALLOW_ALLOW_SERVICE_CALLS,
|
||||
@ -578,6 +579,19 @@ async def mock_bluetooth_entry(
|
||||
async def _mock_bluetooth_entry(
|
||||
bluetooth_proxy_feature_flags: BluetoothProxyFeature,
|
||||
) -> MockESPHomeDevice:
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "test.local",
|
||||
CONF_PORT: 6053,
|
||||
CONF_PASSWORD: "",
|
||||
CONF_BLUETOOTH_MAC_ADDRESS: "AA:BB:CC:DD:EE:FC",
|
||||
},
|
||||
options={
|
||||
CONF_ALLOW_SERVICE_CALLS: DEFAULT_NEW_CONFIG_ALLOW_ALLOW_SERVICE_CALLS
|
||||
},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
return await _mock_generic_device_entry(
|
||||
hass,
|
||||
mock_client,
|
||||
@ -587,6 +601,7 @@ async def mock_bluetooth_entry(
|
||||
},
|
||||
([], []),
|
||||
[],
|
||||
entry=entry,
|
||||
)
|
||||
|
||||
return _mock_bluetooth_entry
|
||||
|
@ -13,7 +13,7 @@ async def test_bluetooth_connect_with_raw_adv(
|
||||
hass: HomeAssistant, mock_bluetooth_entry_with_raw_adv: MockESPHomeDevice
|
||||
) -> None:
|
||||
"""Test bluetooth connect with raw advertisements."""
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner is not None
|
||||
assert scanner.connectable is True
|
||||
assert scanner.scanning is True
|
||||
@ -21,11 +21,11 @@ async def test_bluetooth_connect_with_raw_adv(
|
||||
await mock_bluetooth_entry_with_raw_adv.mock_disconnect(True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner is None
|
||||
await mock_bluetooth_entry_with_raw_adv.mock_connect()
|
||||
await hass.async_block_till_done()
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner.scanning is True
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ async def test_bluetooth_connect_with_legacy_adv(
|
||||
hass: HomeAssistant, mock_bluetooth_entry_with_legacy_adv: MockESPHomeDevice
|
||||
) -> None:
|
||||
"""Test bluetooth connect with legacy advertisements."""
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner is not None
|
||||
assert scanner.connectable is True
|
||||
assert scanner.scanning is True
|
||||
@ -41,11 +41,11 @@ async def test_bluetooth_connect_with_legacy_adv(
|
||||
await mock_bluetooth_entry_with_legacy_adv.mock_disconnect(True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner is None
|
||||
await mock_bluetooth_entry_with_legacy_adv.mock_connect()
|
||||
await hass.async_block_till_done()
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner.scanning is True
|
||||
|
||||
|
||||
@ -55,10 +55,10 @@ async def test_bluetooth_device_linked_via_device(
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test the Bluetooth device is linked to the ESPHome device."""
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner.connectable is True
|
||||
entry = hass.config_entries.async_entry_for_domain_unique_id(
|
||||
"bluetooth", "11:22:33:44:55:AA"
|
||||
"bluetooth", "AA:BB:CC:DD:EE:FC"
|
||||
)
|
||||
assert entry is not None
|
||||
esp_device = device_registry.async_get_device(
|
||||
@ -71,7 +71,7 @@ async def test_bluetooth_device_linked_via_device(
|
||||
)
|
||||
assert esp_device is not None
|
||||
device = device_registry.async_get_device(
|
||||
connections={(dr.CONNECTION_BLUETOOTH, "11:22:33:44:55:AA")}
|
||||
connections={(dr.CONNECTION_BLUETOOTH, "AA:BB:CC:DD:EE:FC")}
|
||||
)
|
||||
assert device is not None
|
||||
assert device.via_device_id == esp_device.id
|
||||
@ -81,7 +81,7 @@ async def test_bluetooth_cleanup_on_remove_entry(
|
||||
hass: HomeAssistant, mock_bluetooth_entry_with_raw_adv: MockESPHomeDevice
|
||||
) -> None:
|
||||
"""Test bluetooth is cleaned up on entry removal."""
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner.connectable is True
|
||||
await hass.config_entries.async_unload(
|
||||
mock_bluetooth_entry_with_raw_adv.entry.entry_id
|
||||
|
@ -37,7 +37,7 @@ async def test_diagnostics_with_bluetooth(
|
||||
mock_bluetooth_entry_with_raw_adv: MockESPHomeDevice,
|
||||
) -> None:
|
||||
"""Test diagnostics for config entry with Bluetooth."""
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
|
||||
scanner = bluetooth.async_scanner_by_source(hass, "AA:BB:CC:DD:EE:FC")
|
||||
assert scanner is not None
|
||||
assert scanner.connectable is True
|
||||
entry = mock_bluetooth_entry_with_raw_adv.entry
|
||||
@ -55,9 +55,9 @@ async def test_diagnostics_with_bluetooth(
|
||||
"discovered_devices_and_advertisement_data": [],
|
||||
"last_detection": ANY,
|
||||
"monotonic_time": ANY,
|
||||
"name": "test (11:22:33:44:55:AA)",
|
||||
"name": "test (AA:BB:CC:DD:EE:FC)",
|
||||
"scanning": True,
|
||||
"source": "11:22:33:44:55:AA",
|
||||
"source": "AA:BB:CC:DD:EE:FC",
|
||||
"start_time": ANY,
|
||||
"time_since_last_device_detection": {},
|
||||
"type": "ESPHomeScanner",
|
||||
@ -66,6 +66,7 @@ async def test_diagnostics_with_bluetooth(
|
||||
"config": {
|
||||
"created_at": ANY,
|
||||
"data": {
|
||||
"bluetooth_mac_address": "**REDACTED**",
|
||||
"device_name": "test",
|
||||
"host": "test.local",
|
||||
"password": "",
|
||||
|
@ -25,6 +25,7 @@ import pytest
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.esphome.const import (
|
||||
CONF_ALLOW_SERVICE_CALLS,
|
||||
CONF_BLUETOOTH_MAC_ADDRESS,
|
||||
CONF_DEVICE_NAME,
|
||||
CONF_SUBSCRIBE_LOGS,
|
||||
DOMAIN,
|
||||
@ -475,6 +476,39 @@ async def test_unique_id_updated_to_mac(hass: HomeAssistant, mock_client) -> Non
|
||||
assert entry.unique_id == "11:22:33:44:55:aa"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
async def test_add_missing_bluetooth_mac_address(
|
||||
hass: HomeAssistant, mock_client
|
||||
) -> None:
|
||||
"""Test bluetooth mac is added if its missing."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "test.local", CONF_PORT: 6053, CONF_PASSWORD: ""},
|
||||
unique_id="mock-config-name",
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
subscribe_done = hass.loop.create_future()
|
||||
|
||||
def async_subscribe_states(*args, **kwargs) -> None:
|
||||
subscribe_done.set_result(None)
|
||||
|
||||
mock_client.subscribe_states = async_subscribe_states
|
||||
mock_client.device_info = AsyncMock(
|
||||
return_value=DeviceInfo(
|
||||
mac_address="1122334455aa",
|
||||
bluetooth_mac_address="AA:BB:CC:DD:EE:FF",
|
||||
)
|
||||
)
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
async with asyncio.timeout(1):
|
||||
await subscribe_done
|
||||
|
||||
assert entry.unique_id == "11:22:33:44:55:aa"
|
||||
assert entry.data.get(CONF_BLUETOOTH_MAC_ADDRESS) == "AA:BB:CC:DD:EE:FF"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_zeroconf")
|
||||
async def test_unique_id_not_updated_if_name_same_and_already_mac(
|
||||
hass: HomeAssistant, mock_client: APIClient
|
||||
@ -1337,3 +1371,32 @@ async def test_entry_missing_unique_id(
|
||||
await mock_esphome_device(mock_client=mock_client, mock_storage=True)
|
||||
await hass.async_block_till_done()
|
||||
assert entry.unique_id == "11:22:33:44:55:aa"
|
||||
|
||||
|
||||
async def test_entry_missing_bluetooth_mac_address(
|
||||
hass: HomeAssistant,
|
||||
mock_client: APIClient,
|
||||
mock_esphome_device: Callable[
|
||||
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
|
||||
Awaitable[MockESPHomeDevice],
|
||||
],
|
||||
) -> None:
|
||||
"""Test the bluetooth_mac_address is added if available."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=None,
|
||||
data={
|
||||
CONF_HOST: "test.local",
|
||||
CONF_PORT: 6053,
|
||||
CONF_PASSWORD: "",
|
||||
},
|
||||
options={CONF_ALLOW_SERVICE_CALLS: True},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
await mock_esphome_device(
|
||||
mock_client=mock_client,
|
||||
mock_storage=True,
|
||||
device_info={"bluetooth_mac_address": "AA:BB:CC:DD:EE:FC"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert entry.data[CONF_BLUETOOTH_MAC_ADDRESS] == "AA:BB:CC:DD:EE:FC"
|
||||
|
Loading…
x
Reference in New Issue
Block a user