fix circular import

This commit is contained in:
J. Nick Koston 2025-04-16 08:53:04 -10:00
parent 3356ee5ded
commit 75885ba9b6
No known key found for this signature in database
5 changed files with 89 additions and 42 deletions

View File

@ -4,15 +4,13 @@ from __future__ import annotations
import asyncio import asyncio
from collections.abc import Callable from collections.abc import Callable
import dataclasses
from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
from fnmatch import translate from fnmatch import translate
from functools import lru_cache, partial from functools import lru_cache, partial
import itertools import itertools
import logging import logging
import re import re
from typing import TYPE_CHECKING, Any, Final, TypedDict from typing import TYPE_CHECKING, Any, Final
import aiodhcpwatcher import aiodhcpwatcher
from aiodiscover import DiscoverHosts from aiodiscover import DiscoverHosts
@ -67,16 +65,13 @@ from homeassistant.helpers.event import (
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo as _DhcpServiceInfo from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo as _DhcpServiceInfo
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import DHCPMatcher, async_get_dhcp from homeassistant.loader import DHCPMatcher, async_get_dhcp
from homeassistant.util.hass_dict import HassKey
from . import websocket_api from . import websocket_api
from .const import DOMAIN from .const import DOMAIN, HOSTNAME, IP_ADDRESS, MAC_ADDRESS
from .models import DATA_DHCP, DHCPAddressData, DHCPData, DhcpMatchers
CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN) CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
HOSTNAME: Final = "hostname"
MAC_ADDRESS: Final = "macaddress"
IP_ADDRESS: Final = "ip"
REGISTERED_DEVICES: Final = "registered_devices" REGISTERED_DEVICES: Final = "registered_devices"
SCAN_INTERVAL = timedelta(minutes=60) SCAN_INTERVAL = timedelta(minutes=60)
@ -91,36 +86,6 @@ _DEPRECATED_DhcpServiceInfo = DeprecatedConstant(
) )
@dataclass(slots=True)
class DhcpMatchers:
"""Prepared info from dhcp entries."""
registered_devices_domains: set[str]
no_oui_matchers: dict[str, list[DHCPMatcher]]
oui_matchers: dict[str, list[DHCPMatcher]]
class DHCPAddressData(TypedDict):
"""Typed dict for DHCP address data."""
hostname: str
ip: str
@dataclasses.dataclass(slots=True)
class DHCPData:
"""Data for the dhcp component."""
integration_matchers: DhcpMatchers
callbacks: set[Callable[[_DhcpServiceInfo], None]] = dataclasses.field(
default_factory=set
)
address_data: dict[str, DHCPAddressData] = dataclasses.field(default_factory=dict)
DATA_DHCP: HassKey[DHCPData] = HassKey(DOMAIN)
def async_index_integration_matchers( def async_index_integration_matchers(
integration_matchers: list[DHCPMatcher], integration_matchers: list[DHCPMatcher],
) -> DhcpMatchers: ) -> DhcpMatchers:

View File

@ -1,3 +1,8 @@
"""Constants for the dhcp integration.""" """Constants for the dhcp integration."""
from typing import Final
DOMAIN = "dhcp" DOMAIN = "dhcp"
HOSTNAME: Final = "hostname"
MAC_ADDRESS: Final = "macaddress"
IP_ADDRESS: Final = "ip"

View File

@ -0,0 +1,34 @@
"""The dhcp integration."""
from __future__ import annotations
from collections.abc import Callable
from functools import partial
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo as _DhcpServiceInfo
from .models import DATA_DHCP, DHCPAddressData
@callback
def async_register_dhcp_callback_internal(
hass: HomeAssistant,
callback_: Callable[[_DhcpServiceInfo], None],
) -> CALLBACK_TYPE:
"""Register a dhcp callback.
For internal use only.
This is not intended for use by integrations.
"""
callbacks = hass.data[DATA_DHCP].callbacks
callbacks.add(callback_)
return partial(callbacks.remove, callback_)
@callback
def async_get_address_data_internal(
hass: HomeAssistant,
) -> dict[str, DHCPAddressData]:
"""Get the address data."""
return hass.data[DATA_DHCP].address_data

View File

@ -0,0 +1,44 @@
"""The dhcp integration."""
from __future__ import annotations
from collections.abc import Callable
import dataclasses
from dataclasses import dataclass
from typing import TypedDict
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo as _DhcpServiceInfo
from homeassistant.loader import DHCPMatcher
from homeassistant.util.hass_dict import HassKey
from .const import DOMAIN
@dataclass(slots=True)
class DhcpMatchers:
"""Prepared info from dhcp entries."""
registered_devices_domains: set[str]
no_oui_matchers: dict[str, list[DHCPMatcher]]
oui_matchers: dict[str, list[DHCPMatcher]]
class DHCPAddressData(TypedDict):
"""Typed dict for DHCP address data."""
hostname: str
ip: str
@dataclasses.dataclass(slots=True)
class DHCPData:
"""Data for the dhcp component."""
integration_matchers: DhcpMatchers
callbacks: set[Callable[[_DhcpServiceInfo], None]] = dataclasses.field(
default_factory=set
)
address_data: dict[str, DHCPAddressData] = dataclasses.field(default_factory=dict)
DATA_DHCP: HassKey[DHCPData] = HassKey(DOMAIN)

View File

@ -9,11 +9,10 @@ import voluptuous as vol
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.json import json_bytes from homeassistant.helpers.json import json_bytes
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo as _DhcpServiceInfo
from . import ( from .const import HOSTNAME, IP_ADDRESS
HOSTNAME, from .helpers import (
IP_ADDRESS,
_DhcpServiceInfo,
async_get_address_data_internal, async_get_address_data_internal,
async_register_dhcp_callback_internal, async_register_dhcp_callback_internal,
) )