Move UsbServiceInfo to service_info helpers (#135663)

* Move UsbServiceInfo to service_info helpers

* Adjust components
pull/135625/head^2
epenet 2025-01-15 15:10:25 +01:00 committed by GitHub
parent 8ae02aaba0
commit e83ee00af8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 73 additions and 17 deletions

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from collections.abc import Coroutine, Sequence from collections.abc import Coroutine, Sequence
import dataclasses import dataclasses
import fnmatch import fnmatch
from functools import partial
import logging import logging
import os import os
import sys import sys
@ -24,9 +25,15 @@ from homeassistant.core import (
HomeAssistant, HomeAssistant,
callback as hass_callback, callback as hass_callback,
) )
from homeassistant.data_entry_flow import BaseServiceInfo
from homeassistant.helpers import config_validation as cv, discovery_flow, system_info from homeassistant.helpers import config_validation as cv, discovery_flow, system_info
from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.deprecation import (
DeprecatedConstant,
all_with_deprecated_constants,
check_if_deprecated_constant,
dir_with_deprecated_constants,
)
from homeassistant.helpers.service_info.usb import UsbServiceInfo as _UsbServiceInfo
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import USBMatcher, async_get_usb from homeassistant.loader import USBMatcher, async_get_usb
@ -45,7 +52,6 @@ __all__ = [
"async_is_plugged_in", "async_is_plugged_in",
"async_register_scan_request_callback", "async_register_scan_request_callback",
"USBCallbackMatcher", "USBCallbackMatcher",
"UsbServiceInfo",
] ]
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
@ -104,16 +110,11 @@ def async_is_plugged_in(hass: HomeAssistant, matcher: USBCallbackMatcher) -> boo
) )
@dataclasses.dataclass(slots=True) _DEPRECATED_UsbServiceInfo = DeprecatedConstant(
class UsbServiceInfo(BaseServiceInfo): _UsbServiceInfo,
"""Prepared info from usb entries.""" "homeassistant.helpers.service_info.usb.UsbServiceInfo",
"2026.2",
device: str )
vid: str
pid: str
serial_number: str | None
manufacturer: str | None
description: str | None
@overload @overload
@ -352,7 +353,7 @@ class USBDiscovery:
if not matched: if not matched:
return return
service_info: UsbServiceInfo | None = None service_info: _UsbServiceInfo | None = None
sorted_by_most_targeted = sorted(matched, key=lambda item: -len(item)) sorted_by_most_targeted = sorted(matched, key=lambda item: -len(item))
most_matched_fields = len(sorted_by_most_targeted[0]) most_matched_fields = len(sorted_by_most_targeted[0])
@ -364,7 +365,7 @@ class USBDiscovery:
break break
if service_info is None: if service_info is None:
service_info = UsbServiceInfo( service_info = _UsbServiceInfo(
device=await self.hass.async_add_executor_job( device=await self.hass.async_add_executor_job(
get_serial_by_id, device.device get_serial_by_id, device.device
), ),
@ -457,3 +458,11 @@ async def websocket_usb_scan(
if not usb_discovery.observer_active: if not usb_discovery.observer_active:
await usb_discovery.async_request_scan() await usb_discovery.async_request_scan()
connection.send_result(msg["id"]) connection.send_result(msg["id"])
# These can be removed if no deprecated constant are in this module anymore
__getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
__dir__ = partial(
dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
)
__all__ = all_with_deprecated_constants(globals())

View File

@ -87,11 +87,11 @@ from .util.enum import try_parse_enum
if TYPE_CHECKING: if TYPE_CHECKING:
from .components.bluetooth import BluetoothServiceInfoBleak from .components.bluetooth import BluetoothServiceInfoBleak
from .components.usb import UsbServiceInfo
from .helpers.service_info.dhcp import DhcpServiceInfo from .helpers.service_info.dhcp import DhcpServiceInfo
from .helpers.service_info.hassio import HassioServiceInfo from .helpers.service_info.hassio import HassioServiceInfo
from .helpers.service_info.mqtt import MqttServiceInfo from .helpers.service_info.mqtt import MqttServiceInfo
from .helpers.service_info.ssdp import SsdpServiceInfo from .helpers.service_info.ssdp import SsdpServiceInfo
from .helpers.service_info.usb import UsbServiceInfo
from .helpers.service_info.zeroconf import ZeroconfServiceInfo from .helpers.service_info.zeroconf import ZeroconfServiceInfo

View File

@ -0,0 +1,17 @@
"""USB discovery data."""
from dataclasses import dataclass
from homeassistant.data_entry_flow import BaseServiceInfo
@dataclass(slots=True)
class UsbServiceInfo(BaseServiceInfo):
"""Prepared info from usb entries."""
device: str
vid: str
pid: str
serial_number: str | None
manufacturer: str | None
description: str | None

View File

@ -8,7 +8,7 @@ from homeassistant.components.homeassistant_sky_connect.util import (
get_hardware_variant, get_hardware_variant,
get_usb_service_info, get_usb_service_info,
) )
from homeassistant.components.usb import UsbServiceInfo from homeassistant.helpers.service_info.usb import UsbServiceInfo
from tests.common import MockConfigEntry from tests.common import MockConfigEntry

View File

@ -2,6 +2,7 @@
import os import os
import sys import sys
from typing import Any
from unittest.mock import MagicMock, Mock, call, patch, sentinel from unittest.mock import MagicMock, Mock, call, patch, sentinel
import pytest import pytest
@ -9,10 +10,12 @@ import pytest
from homeassistant.components import usb from homeassistant.components import usb
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.service_info.usb import UsbServiceInfo
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from . import conbee_device, slae_sh_device from . import conbee_device, slae_sh_device
from tests.common import import_and_test_deprecated_constant
from tests.typing import WebSocketGenerator from tests.typing import WebSocketGenerator
@ -1160,3 +1163,30 @@ async def test_cp2102n_ordering_on_macos(
# We always use `cu.SLAB_USBtoUART` # We always use `cu.SLAB_USBtoUART`
assert mock_config_flow.mock_calls[0][2]["data"].device == "/dev/cu.SLAB_USBtoUART2" assert mock_config_flow.mock_calls[0][2]["data"].device == "/dev/cu.SLAB_USBtoUART2"
@pytest.mark.parametrize(
("constant_name", "replacement_name", "replacement"),
[
(
"UsbServiceInfo",
"homeassistant.helpers.service_info.usb.UsbServiceInfo",
UsbServiceInfo,
),
],
)
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
constant_name: str,
replacement_name: str,
replacement: Any,
) -> None:
"""Test deprecated automation constants."""
import_and_test_deprecated_constant(
caplog,
usb,
constant_name,
replacement_name,
replacement,
"2026.2",
)

View File

@ -11,12 +11,12 @@ import zigpy.config
from zigpy.config import CONF_DEVICE_PATH from zigpy.config import CONF_DEVICE_PATH
import zigpy.types import zigpy.types
from homeassistant.components.usb import UsbServiceInfo
from homeassistant.components.zha import radio_manager from homeassistant.components.zha import radio_manager
from homeassistant.components.zha.const import DOMAIN from homeassistant.components.zha.const import DOMAIN
from homeassistant.components.zha.radio_manager import ProbeResult, ZhaRadioManager from homeassistant.components.zha.radio_manager import ProbeResult, ZhaRadioManager
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.service_info.usb import UsbServiceInfo
from tests.common import MockConfigEntry from tests.common import MockConfigEntry