mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Prioritize the correct CP2102N serial port on macOS (#116461)
This commit is contained in:
parent
4d982a9227
commit
bd65afa207
@ -362,10 +362,33 @@ class USBDiscovery:
|
||||
|
||||
async def _async_process_ports(self, ports: list[ListPortInfo]) -> None:
|
||||
"""Process each discovered port."""
|
||||
for port in ports:
|
||||
if port.vid is None and port.pid is None:
|
||||
continue
|
||||
await self._async_process_discovered_usb_device(usb_device_from_port(port))
|
||||
usb_devices = [
|
||||
usb_device_from_port(port)
|
||||
for port in ports
|
||||
if port.vid is not None or port.pid is not None
|
||||
]
|
||||
|
||||
# CP2102N chips create *two* serial ports on macOS: `/dev/cu.usbserial-` and
|
||||
# `/dev/cu.SLAB_USBtoUART*`. The former does not work and we should ignore them.
|
||||
if sys.platform == "darwin":
|
||||
silabs_serials = {
|
||||
dev.serial_number
|
||||
for dev in usb_devices
|
||||
if dev.device.startswith("/dev/cu.SLAB_USBtoUART")
|
||||
}
|
||||
|
||||
usb_devices = [
|
||||
dev
|
||||
for dev in usb_devices
|
||||
if dev.serial_number not in silabs_serials
|
||||
or (
|
||||
dev.serial_number in silabs_serials
|
||||
and dev.device.startswith("/dev/cu.SLAB_USBtoUART")
|
||||
)
|
||||
]
|
||||
|
||||
for usb_device in usb_devices:
|
||||
await self._async_process_discovered_usb_device(usb_device)
|
||||
|
||||
async def _async_scan_serial(self) -> None:
|
||||
"""Scan serial ports."""
|
||||
|
@ -1054,3 +1054,109 @@ async def test_resolve_serial_by_id(
|
||||
assert len(mock_config_flow.mock_calls) == 1
|
||||
assert mock_config_flow.mock_calls[0][1][0] == "test1"
|
||||
assert mock_config_flow.mock_calls[0][2]["data"].device == "/dev/serial/by-id/bla"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"ports",
|
||||
[
|
||||
[
|
||||
MagicMock(
|
||||
device="/dev/cu.usbserial-2120",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=conbee_device.serial_number,
|
||||
manufacturer=conbee_device.manufacturer,
|
||||
description=conbee_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.usbserial-1120",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=slae_sh_device.serial_number,
|
||||
manufacturer=slae_sh_device.manufacturer,
|
||||
description=slae_sh_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.SLAB_USBtoUART",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=conbee_device.serial_number,
|
||||
manufacturer=conbee_device.manufacturer,
|
||||
description=conbee_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.SLAB_USBtoUART2",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=slae_sh_device.serial_number,
|
||||
manufacturer=slae_sh_device.manufacturer,
|
||||
description=slae_sh_device.description,
|
||||
),
|
||||
],
|
||||
[
|
||||
MagicMock(
|
||||
device="/dev/cu.SLAB_USBtoUART2",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=slae_sh_device.serial_number,
|
||||
manufacturer=slae_sh_device.manufacturer,
|
||||
description=slae_sh_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.SLAB_USBtoUART",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=conbee_device.serial_number,
|
||||
manufacturer=conbee_device.manufacturer,
|
||||
description=conbee_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.usbserial-1120",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=slae_sh_device.serial_number,
|
||||
manufacturer=slae_sh_device.manufacturer,
|
||||
description=slae_sh_device.description,
|
||||
),
|
||||
MagicMock(
|
||||
device="/dev/cu.usbserial-2120",
|
||||
vid=0x3039,
|
||||
pid=0x3039,
|
||||
serial_number=conbee_device.serial_number,
|
||||
manufacturer=conbee_device.manufacturer,
|
||||
description=conbee_device.description,
|
||||
),
|
||||
],
|
||||
],
|
||||
)
|
||||
async def test_cp2102n_ordering_on_macos(
|
||||
ports: list[MagicMock], hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
) -> None:
|
||||
"""Test CP2102N ordering on macOS."""
|
||||
|
||||
new_usb = [
|
||||
{"domain": "test1", "vid": "3039", "pid": "3039", "description": "*2652*"}
|
||||
]
|
||||
|
||||
with (
|
||||
patch("sys.platform", "darwin"),
|
||||
patch("pyudev.Context", side_effect=ImportError),
|
||||
patch("homeassistant.components.usb.async_get_usb", return_value=new_usb),
|
||||
patch("homeassistant.components.usb.comports", return_value=ports),
|
||||
patch.object(hass.config_entries.flow, "async_init") as mock_config_flow,
|
||||
):
|
||||
assert await async_setup_component(hass, "usb", {"usb": {}})
|
||||
await hass.async_block_till_done()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||
await hass.async_block_till_done()
|
||||
ws_client = await hass_ws_client(hass)
|
||||
await ws_client.send_json({"id": 1, "type": "usb/scan"})
|
||||
response = await ws_client.receive_json()
|
||||
assert response["success"]
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_config_flow.mock_calls) == 1
|
||||
assert mock_config_flow.mock_calls[0][1][0] == "test1"
|
||||
|
||||
# We always use `cu.SLAB_USBtoUART`
|
||||
assert mock_config_flow.mock_calls[0][2]["data"].device == "/dev/cu.SLAB_USBtoUART2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user