|
1 | | -#!/usr/bin/env python3 |
2 | 1 | """Runs mDNS zeroconf service for Home Assistant discovery.""" |
| 2 | + |
3 | 3 | import logging |
4 | 4 | import socket |
| 5 | +import uuid |
5 | 6 | from typing import Optional |
6 | 7 |
|
7 | 8 | _LOGGER = logging.getLogger(__name__) |
|
15 | 16 | MDNS_TARGET_IP = "224.0.0.251" |
16 | 17 |
|
17 | 18 |
|
18 | | -async def register_server(name: str, port: int, host: Optional[str] = None) -> None: |
19 | | - if not host: |
20 | | - test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
21 | | - test_sock.setblocking(False) |
22 | | - test_sock.connect((MDNS_TARGET_IP, 1)) |
23 | | - host = test_sock.getsockname()[0] |
24 | | - _LOGGER.debug("Detected IP: %s", host) |
| 19 | +class HomeAssistantZeroconf: |
| 20 | + """ZeroConf (mDNS) discovery for Home Assistant.""" |
| 21 | + |
| 22 | + def __init__( |
| 23 | + self, port: int, name: Optional[str] = None, host: Optional[str] = None |
| 24 | + ) -> None: |
| 25 | + self.port = port |
| 26 | + self.name = name or _get_mac_address() |
| 27 | + |
| 28 | + if not host: |
| 29 | + test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
| 30 | + test_sock.setblocking(False) |
| 31 | + test_sock.connect((MDNS_TARGET_IP, 1)) |
| 32 | + host = test_sock.getsockname()[0] |
| 33 | + _LOGGER.debug("Detected IP: %s", host) |
| 34 | + |
| 35 | + assert host |
| 36 | + self.host = host |
| 37 | + self._aiozc = AsyncZeroconf() |
| 38 | + |
| 39 | + async def register_server(self) -> None: |
| 40 | + """Register ZeroConf server.""" |
| 41 | + |
| 42 | + service_info = AsyncServiceInfo( |
| 43 | + "_wyoming._tcp.local.", |
| 44 | + f"{self.name}._wyoming._tcp.local.", |
| 45 | + addresses=[socket.inet_aton(self.host)], |
| 46 | + port=self.port, |
| 47 | + ) |
| 48 | + await self._aiozc.async_register_service(service_info) |
| 49 | + _LOGGER.debug("Zeroconf discovery enabled: %s", service_info) |
25 | 50 |
|
26 | | - assert host |
27 | 51 |
|
28 | | - service_info = AsyncServiceInfo( |
29 | | - "_wyoming._tcp.local.", |
30 | | - f"{name}._wyoming._tcp.local.", |
31 | | - addresses=[socket.inet_aton(host)], |
32 | | - port=port, |
| 52 | +def _get_mac_address() -> str: |
| 53 | + """Return MAC address formatted as hex with no colons.""" |
| 54 | + return "".join( |
| 55 | + # pylint: disable=consider-using-f-string |
| 56 | + ["{:02x}".format((uuid.getnode() >> ele) & 0xFF) for ele in range(0, 8 * 6, 8)][ |
| 57 | + ::-1 |
| 58 | + ] |
33 | 59 | ) |
34 | | - aiozc = AsyncZeroconf() |
35 | | - await aiozc.async_register_service(service_info) |
|
0 commit comments