|
22 | 22 | import asyncio |
23 | 23 | import contextlib |
24 | 24 | from types import TracebackType # noqa # used in type hints |
25 | | -from typing import Awaitable, Callable, Dict, List, Optional, Type, Union |
| 25 | +from typing import Awaitable, Callable, Dict, List, Optional, Tuple, Type, Union |
26 | 26 |
|
27 | 27 | from ._core import NotifyListener, Zeroconf |
28 | 28 | from ._exceptions import NonUniqueNameException |
29 | 29 | from ._services import ServiceInfo, _ServiceBrowserBase, instance_name_from_service_info |
| 30 | +from ._services.types import ZeroconfServiceTypes |
30 | 31 | from ._utils.aio import wait_condition_or_timeout |
31 | 32 | from ._utils.net import IPVersion, InterfaceChoice, InterfacesType |
32 | 33 | from ._utils.time import current_time_millis, millis_to_seconds |
33 | | -from .const import _BROWSER_TIME, _CHECK_TIME, _LISTENER_TIME, _MDNS_PORT, _REGISTER_TIME, _UNREGISTER_TIME |
| 34 | +from .const import ( |
| 35 | + _BROWSER_TIME, |
| 36 | + _CHECK_TIME, |
| 37 | + _LISTENER_TIME, |
| 38 | + _MDNS_PORT, |
| 39 | + _REGISTER_TIME, |
| 40 | + _SERVICE_TYPE_ENUMERATION_NAME, |
| 41 | + _UNREGISTER_TIME, |
| 42 | +) |
34 | 43 |
|
35 | 44 |
|
36 | 45 | __all__ = [ |
37 | 46 | "AsyncZeroconf", |
38 | 47 | "AsyncServiceInfo", |
39 | 48 | "AsyncServiceBrowser", |
40 | 49 | "AsyncServiceListener", |
| 50 | + "AsyncZeroconfServiceTypes", |
41 | 51 | ] |
42 | 52 |
|
43 | 53 |
|
@@ -137,6 +147,7 @@ async def async_cancel(self) -> None: |
137 | 147 | async def async_run(self) -> None: |
138 | 148 | """Run the browser task.""" |
139 | 149 | self.run() |
| 150 | + await self.aiozc.zeroconf.async_wait_for_start() |
140 | 151 | while True: |
141 | 152 | timeout = self._seconds_to_wait() |
142 | 153 | if timeout: |
@@ -164,6 +175,45 @@ async def async_run(self) -> None: |
164 | 175 | ) |
165 | 176 |
|
166 | 177 |
|
| 178 | +class AsyncZeroconfServiceTypes(ZeroconfServiceTypes): |
| 179 | + """An async version of ZeroconfServiceTypes.""" |
| 180 | + |
| 181 | + @classmethod |
| 182 | + async def async_find( |
| 183 | + cls, |
| 184 | + aiozc: Optional['AsyncZeroconf'] = None, |
| 185 | + timeout: Union[int, float] = 5, |
| 186 | + interfaces: InterfacesType = InterfaceChoice.All, |
| 187 | + ip_version: Optional[IPVersion] = None, |
| 188 | + ) -> Tuple[str, ...]: |
| 189 | + """ |
| 190 | + Return all of the advertised services on any local networks. |
| 191 | +
|
| 192 | + :param aiozc: AsyncZeroconf() instance. Pass in if already have an |
| 193 | + instance running or if non-default interfaces are needed |
| 194 | + :param timeout: seconds to wait for any responses |
| 195 | + :param interfaces: interfaces to listen on. |
| 196 | + :param ip_version: IP protocol version to use. |
| 197 | + :return: tuple of service type strings |
| 198 | + """ |
| 199 | + local_zc = aiozc or AsyncZeroconf(interfaces=interfaces, ip_version=ip_version) |
| 200 | + listener = cls() |
| 201 | + async_browser = AsyncServiceBrowser( |
| 202 | + local_zc, _SERVICE_TYPE_ENUMERATION_NAME, listener=listener # type: ignore |
| 203 | + ) |
| 204 | + |
| 205 | + # wait for responses |
| 206 | + await asyncio.sleep(timeout) |
| 207 | + |
| 208 | + await async_browser.async_cancel() |
| 209 | + |
| 210 | + # close down anything we opened |
| 211 | + if aiozc is None: |
| 212 | + await local_zc.async_close() |
| 213 | + |
| 214 | + return tuple(sorted(listener.found_services)) |
| 215 | + |
| 216 | + |
167 | 217 | class AsyncZeroconf: |
168 | 218 | """Implementation of Zeroconf Multicast DNS Service Discovery |
169 | 219 |
|
|
0 commit comments