Import and create pyudev for usb in the executor (#113478)
This commit is contained in:
parent
29f07260f9
commit
b7f7bed46c
3 changed files with 28 additions and 11 deletions
|
@ -35,7 +35,7 @@ from .models import USBDevice
|
||||||
from .utils import usb_device_from_port
|
from .utils import usb_device_from_port
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from pyudev import Device
|
from pyudev import Device, MonitorObserver
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -228,6 +228,25 @@ class USBDiscovery:
|
||||||
if info.get("docker"):
|
if info.get("docker"):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not (
|
||||||
|
observer := await self.hass.async_add_executor_job(
|
||||||
|
self._get_monitor_observer
|
||||||
|
)
|
||||||
|
):
|
||||||
|
return
|
||||||
|
|
||||||
|
def _stop_observer(event: Event) -> None:
|
||||||
|
observer.stop()
|
||||||
|
|
||||||
|
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_observer)
|
||||||
|
self.observer_active = True
|
||||||
|
|
||||||
|
def _get_monitor_observer(self) -> MonitorObserver | None:
|
||||||
|
"""Get the monitor observer.
|
||||||
|
|
||||||
|
This runs in the executor because the import
|
||||||
|
does blocking I/O.
|
||||||
|
"""
|
||||||
from pyudev import ( # pylint: disable=import-outside-toplevel
|
from pyudev import ( # pylint: disable=import-outside-toplevel
|
||||||
Context,
|
Context,
|
||||||
Monitor,
|
Monitor,
|
||||||
|
@ -237,7 +256,7 @@ class USBDiscovery:
|
||||||
try:
|
try:
|
||||||
context = Context()
|
context = Context()
|
||||||
except (ImportError, OSError):
|
except (ImportError, OSError):
|
||||||
return
|
return None
|
||||||
|
|
||||||
monitor = Monitor.from_netlink(context)
|
monitor = Monitor.from_netlink(context)
|
||||||
try:
|
try:
|
||||||
|
@ -246,17 +265,14 @@ class USBDiscovery:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Unable to setup pyudev filtering; This is expected on WSL: %s", ex
|
"Unable to setup pyudev filtering; This is expected on WSL: %s", ex
|
||||||
)
|
)
|
||||||
return
|
return None
|
||||||
|
|
||||||
observer = MonitorObserver(
|
observer = MonitorObserver(
|
||||||
monitor, callback=self._device_discovered, name="usb-observer"
|
monitor, callback=self._device_discovered, name="usb-observer"
|
||||||
)
|
)
|
||||||
|
|
||||||
observer.start()
|
observer.start()
|
||||||
|
return observer
|
||||||
def _stop_observer(event: Event) -> None:
|
|
||||||
observer.stop()
|
|
||||||
|
|
||||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_observer)
|
|
||||||
self.observer_active = True
|
|
||||||
|
|
||||||
def _device_discovered(self, device: Device) -> None:
|
def _device_discovered(self, device: Device) -> None:
|
||||||
"""Call when the observer discovers a new usb tty device."""
|
"""Call when the observer discovers a new usb tty device."""
|
||||||
|
|
|
@ -590,6 +590,7 @@ async def test_supervisor_issues_initial_failure(
|
||||||
|
|
||||||
with patch("homeassistant.components.hassio.issues.REQUEST_REFRESH_DELAY", new=0.1):
|
with patch("homeassistant.components.hassio.issues.REQUEST_REFRESH_DELAY", new=0.1):
|
||||||
result = await async_setup_component(hass, "hassio", {})
|
result = await async_setup_component(hass, "hassio", {})
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert result
|
assert result
|
||||||
|
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
|
|
@ -85,7 +85,7 @@ async def test_observer_discovery(
|
||||||
|
|
||||||
def _create_mock_monitor_observer(monitor, callback, name):
|
def _create_mock_monitor_observer(monitor, callback, name):
|
||||||
nonlocal mock_observer
|
nonlocal mock_observer
|
||||||
hass.async_create_task(_mock_monitor_observer_callback(callback))
|
hass.create_task(_mock_monitor_observer_callback(callback))
|
||||||
mock_observer = MagicMock()
|
mock_observer = MagicMock()
|
||||||
return mock_observer
|
return mock_observer
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ async def test_observer_discovery(
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert mock_observer.mock_calls == [call.start(), call.stop()]
|
assert mock_observer.mock_calls == [call.start(), call.__bool__(), call.stop()]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
|
|
Loading…
Add table
Reference in a new issue