|
8 | 8 | from bleak.backends.scanner import AdvertisementData, BLEDevice |
9 | 9 | from bluetooth_adapters import AdvertisementHistory |
10 | 10 | from freezegun import freeze_time |
11 | | -from habluetooth import HaScanner |
| 11 | +from habluetooth import BluetoothScanningMode, HaScanner |
12 | 12 |
|
13 | 13 | # pylint: disable-next=no-name-in-module |
14 | 14 | from habluetooth.advertisement_tracker import TRACKER_BUFFERING_WOBBLE_SECONDS |
|
21 | 21 | MONOTONIC_TIME, |
22 | 22 | BaseHaRemoteScanner, |
23 | 23 | BluetoothChange, |
24 | | - BluetoothScanningMode, |
25 | 24 | BluetoothServiceInfo, |
26 | 25 | BluetoothServiceInfoBleak, |
27 | 26 | HaBluetoothConnector, |
@@ -1911,3 +1910,133 @@ async def test_no_repair_issue_for_remote_scanner( |
1911 | 1910 | and "bluetooth_adapter_missing_permissions" in issue.issue_id |
1912 | 1911 | ] |
1913 | 1912 | assert len(issues) == 0 |
| 1913 | + |
| 1914 | + |
| 1915 | +@pytest.mark.usefixtures("one_adapter") |
| 1916 | +async def test_repair_issue_created_for_passive_mode_fallback( |
| 1917 | + hass: HomeAssistant, |
| 1918 | +) -> None: |
| 1919 | + """Test repair issue is created when scanner falls back to passive mode.""" |
| 1920 | + assert await async_setup_component(hass, bluetooth.DOMAIN, {}) |
| 1921 | + await hass.async_block_till_done() |
| 1922 | + |
| 1923 | + manager = _get_manager() |
| 1924 | + |
| 1925 | + scanner = HaScanner( |
| 1926 | + mode=BluetoothScanningMode.ACTIVE, |
| 1927 | + adapter="hci0", |
| 1928 | + address="00:11:22:33:44:55", |
| 1929 | + ) |
| 1930 | + scanner.async_setup() |
| 1931 | + |
| 1932 | + cancel = manager.async_register_scanner(scanner, connection_slots=1) |
| 1933 | + |
| 1934 | + # Set scanner to passive mode when active was requested |
| 1935 | + scanner.set_requested_mode(BluetoothScanningMode.ACTIVE) |
| 1936 | + scanner.set_current_mode(BluetoothScanningMode.PASSIVE) |
| 1937 | + |
| 1938 | + manager.on_scanner_start(scanner) |
| 1939 | + |
| 1940 | + # Check repair issue is created |
| 1941 | + issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}" |
| 1942 | + registry = ir.async_get(hass) |
| 1943 | + issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id) |
| 1944 | + assert issue is not None |
| 1945 | + assert issue.severity == ir.IssueSeverity.WARNING |
| 1946 | + # Should default to USB translation key when adapter type is unknown |
| 1947 | + assert issue.translation_key == "bluetooth_adapter_passive_mode_usb" |
| 1948 | + assert not issue.is_fixable |
| 1949 | + |
| 1950 | + cancel() |
| 1951 | + |
| 1952 | + |
| 1953 | +async def test_repair_issue_created_for_passive_mode_fallback_uart( |
| 1954 | + hass: HomeAssistant, |
| 1955 | +) -> None: |
| 1956 | + """Test repair issue is created with UART-specific message for UART adapters.""" |
| 1957 | + with patch( |
| 1958 | + "bluetooth_adapters.systems.linux.LinuxAdapters.adapters", |
| 1959 | + { |
| 1960 | + "hci0": { |
| 1961 | + "address": "00:11:22:33:44:55", |
| 1962 | + "sw_version": "homeassistant", |
| 1963 | + "hw_version": "uart:bcm2711", |
| 1964 | + "passive_scan": False, |
| 1965 | + "manufacturer": "Raspberry Pi", |
| 1966 | + "product": "BCM2711", |
| 1967 | + "adapter_type": "uart", # UART adapter type |
| 1968 | + } |
| 1969 | + }, |
| 1970 | + ): |
| 1971 | + assert await async_setup_component(hass, bluetooth.DOMAIN, {}) |
| 1972 | + await hass.async_block_till_done() |
| 1973 | + |
| 1974 | + manager = _get_manager() |
| 1975 | + |
| 1976 | + scanner = HaScanner( |
| 1977 | + mode=BluetoothScanningMode.ACTIVE, |
| 1978 | + adapter="hci0", |
| 1979 | + address="00:11:22:33:44:55", |
| 1980 | + ) |
| 1981 | + scanner.async_setup() |
| 1982 | + |
| 1983 | + cancel = manager.async_register_scanner(scanner, connection_slots=1) |
| 1984 | + |
| 1985 | + # Set scanner to passive mode when active was requested |
| 1986 | + scanner.set_requested_mode(BluetoothScanningMode.ACTIVE) |
| 1987 | + scanner.set_current_mode(BluetoothScanningMode.PASSIVE) |
| 1988 | + |
| 1989 | + manager.on_scanner_start(scanner) |
| 1990 | + |
| 1991 | + # Check repair issue is created with UART-specific translation key |
| 1992 | + issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}" |
| 1993 | + registry = ir.async_get(hass) |
| 1994 | + issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id) |
| 1995 | + assert issue is not None |
| 1996 | + assert issue.severity == ir.IssueSeverity.WARNING |
| 1997 | + assert issue.translation_key == "bluetooth_adapter_passive_mode_uart" |
| 1998 | + assert not issue.is_fixable |
| 1999 | + |
| 2000 | + cancel() |
| 2001 | + |
| 2002 | + |
| 2003 | +@pytest.mark.usefixtures("one_adapter") |
| 2004 | +async def test_repair_issue_deleted_when_passive_mode_resolved( |
| 2005 | + hass: HomeAssistant, |
| 2006 | +) -> None: |
| 2007 | + """Test repair issue is deleted when scanner no longer in passive mode.""" |
| 2008 | + assert await async_setup_component(hass, bluetooth.DOMAIN, {}) |
| 2009 | + await hass.async_block_till_done() |
| 2010 | + |
| 2011 | + manager = _get_manager() |
| 2012 | + |
| 2013 | + scanner = HaScanner( |
| 2014 | + mode=BluetoothScanningMode.ACTIVE, |
| 2015 | + adapter="hci0", |
| 2016 | + address="00:11:22:33:44:55", |
| 2017 | + ) |
| 2018 | + scanner.async_setup() |
| 2019 | + |
| 2020 | + cancel = manager.async_register_scanner(scanner, connection_slots=1) |
| 2021 | + |
| 2022 | + # Initially set scanner to passive mode when active was requested |
| 2023 | + scanner.set_requested_mode(BluetoothScanningMode.ACTIVE) |
| 2024 | + scanner.set_current_mode(BluetoothScanningMode.PASSIVE) |
| 2025 | + |
| 2026 | + manager.on_scanner_start(scanner) |
| 2027 | + |
| 2028 | + # Check repair issue is created |
| 2029 | + issue_id = f"bluetooth_adapter_passive_mode_{scanner.source}" |
| 2030 | + registry = ir.async_get(hass) |
| 2031 | + issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id) |
| 2032 | + assert issue is not None |
| 2033 | + |
| 2034 | + # Now simulate scanner recovering to active mode |
| 2035 | + scanner.set_current_mode(BluetoothScanningMode.ACTIVE) |
| 2036 | + manager.on_scanner_start(scanner) |
| 2037 | + |
| 2038 | + # Check repair issue is deleted |
| 2039 | + issue = registry.async_get_issue(bluetooth.DOMAIN, issue_id) |
| 2040 | + assert issue is None |
| 2041 | + |
| 2042 | + cancel() |
0 commit comments