2021-03-30 16:48:04 +00:00
|
|
|
"""Models for Zeroconf."""
|
|
|
|
|
2021-05-11 16:03:36 +00:00
|
|
|
import asyncio
|
|
|
|
from typing import Any
|
|
|
|
|
2021-03-30 16:48:04 +00:00
|
|
|
from zeroconf import DNSPointer, DNSRecord, ServiceBrowser, Zeroconf
|
2021-05-11 16:03:36 +00:00
|
|
|
from zeroconf.asyncio import AsyncZeroconf
|
2021-03-30 16:48:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
class HaZeroconf(Zeroconf):
|
|
|
|
"""Zeroconf that cannot be closed."""
|
|
|
|
|
|
|
|
def close(self) -> None:
|
|
|
|
"""Fake method to avoid integrations closing it."""
|
|
|
|
|
|
|
|
ha_close = Zeroconf.close
|
|
|
|
|
|
|
|
|
2021-05-11 16:03:36 +00:00
|
|
|
class HaAsyncZeroconf(AsyncZeroconf):
|
|
|
|
"""Home Assistant version of AsyncZeroconf."""
|
|
|
|
|
|
|
|
def __init__( # pylint: disable=super-init-not-called
|
|
|
|
self, *args: Any, **kwargs: Any
|
|
|
|
) -> None:
|
|
|
|
"""Wrap AsyncZeroconf."""
|
|
|
|
self.zeroconf = HaZeroconf(*args, **kwargs)
|
|
|
|
self.loop = asyncio.get_running_loop()
|
|
|
|
|
|
|
|
async def async_close(self) -> None:
|
|
|
|
"""Fake method to avoid integrations closing it."""
|
|
|
|
|
|
|
|
|
2021-03-30 16:48:04 +00:00
|
|
|
class HaServiceBrowser(ServiceBrowser):
|
|
|
|
"""ServiceBrowser that only consumes DNSPointer records."""
|
|
|
|
|
|
|
|
def update_record(self, zc: Zeroconf, now: float, record: DNSRecord) -> None:
|
|
|
|
"""Pre-Filter update_record to DNSPointers for the configured type."""
|
|
|
|
|
|
|
|
#
|
|
|
|
# Each ServerBrowser currently runs in its own thread which
|
|
|
|
# processes every A or AAAA record update per instance.
|
|
|
|
#
|
|
|
|
# As the list of zeroconf names we watch for grows, each additional
|
|
|
|
# ServiceBrowser would process all the A and AAAA updates on the network.
|
|
|
|
#
|
2021-06-11 11:35:03 +00:00
|
|
|
# To avoid overwhelming the system we pre-filter here and only process
|
2021-03-30 16:48:04 +00:00
|
|
|
# DNSPointers for the configured record name (type)
|
|
|
|
#
|
|
|
|
if record.name not in self.types or not isinstance(record, DNSPointer):
|
|
|
|
return
|
|
|
|
super().update_record(zc, now, record)
|