コード例 #1
0
ファイル: __init__.py プロジェクト: Jc2k/aiohomekit
async def _async_find_data_for_device_id(
        device_id: str,
        max_seconds: int = 10,
        async_zeroconf_instance: AsyncZeroconf = None) -> tuple[str, int]:
    """Try to find a HomeKit Accessory via Bonjour.

    The process is time boxed by the second parameter which sets an upper
    limit of `max_seconds` before it times out. The runtime of the function may be longer because of the Bonjour
    handling code.
    """
    our_aio_zc = async_zeroconf_instance or AsyncZeroconf()
    found_device_event = asyncio.Event()
    listener = CollectingListener(device_id=device_id,
                                  found_device_event=found_device_event)
    async_service_browser = AsyncServiceBrowser(our_aio_zc.zeroconf, HAP_TYPE,
                                                listener)
    with contextlib.suppress(asyncio.TimeoutError):
        await asyncio.wait_for(found_device_event.wait(), timeout=max_seconds)
    device_id_bytes = device_id.encode()

    try:
        for info in listener.get_data():
            if _service_info_id_matches(info, device_id_bytes):
                logging.debug("Located Homekit IP accessory %s",
                              info.properties)
                return _build_data_from_service_info(info)
    finally:
        await async_service_browser.async_cancel()
        if not async_zeroconf_instance:
            await our_aio_zc.async_close()

    raise AccessoryNotFoundError(
        "Device not found via Bonjour within 10 seconds")
コード例 #2
0
ファイル: __init__.py プロジェクト: Jc2k/aiohomekit
async def async_discover_homekit_devices(
        max_seconds: int = 10,
        async_zeroconf_instance: AsyncZeroconf = None) -> list[Any]:
    """Discovers all HomeKit Accessories.

    It browses for devices in the _hap._tcp.local. domain and checks if
    all required fields are set in the text record. It one field is missing, it will be excluded from the result list.

    :param max_seconds: the number of seconds we will wait for the devices to be discovered
    :return: a list of dicts containing all fields as described in table 5.7 page 69
    """
    if async_zeroconf_instance and async_zeroconf_has_hap_service_browser(
            async_zeroconf_instance):
        return await _async_homekit_devices_from_cache(async_zeroconf_instance)

    our_aiozc = async_zeroconf_instance or AsyncZeroconf()
    listener = CollectingListener()
    service_browser = AsyncServiceBrowser(our_aiozc.zeroconf, HAP_TYPE,
                                          listener)
    await asyncio.sleep(max_seconds)
    tmp = []
    try:
        for info in listener.get_data():
            if not _service_info_is_homekit_device(info):
                continue
            data = _build_data_from_service_info(info)
            logging.debug("found Homekit IP accessory %s", data)
            tmp.append(data)
    finally:
        await service_browser.async_cancel()
        if not async_zeroconf_instance:
            await our_aiozc.async_close()
    return tmp
コード例 #3
0
ファイル: zeroconf.py プロジェクト: th33xitus/moonraker
 async def register_services(self, infos: List[AsyncServiceInfo]) -> None:
     self.aiozc = AsyncZeroconf(ip_version=self.ip_version)
     tasks = [
         self.aiozc.async_register_service(info, allow_name_change=True)
         for info in infos
     ]
     background_tasks = await asyncio.gather(*tasks)
     await asyncio.gather(*background_tasks)
コード例 #4
0
ファイル: device.py プロジェクト: 2Fake/devolo_plc_api
    async def async_connect(self, session_instance: httpx.AsyncClient | None = None) -> None:
        """
        Connect to a device asynchronous.

        :param: session_instance: Session client instance to be potentially reused.
        """
        self._session_instance = session_instance
        self._session = self._session_instance or httpx.AsyncClient()
        if not self._zeroconf_instance:
            self._zeroconf = AsyncZeroconf()
        elif isinstance(self._zeroconf_instance, Zeroconf):
            self._zeroconf = AsyncZeroconf(zc=self._zeroconf_instance)
        else:
            self._zeroconf = self._zeroconf_instance
        await asyncio.gather(self._get_device_info(), self._get_plcnet_info())
        if not self.device and not self.plcnet:
            raise DeviceNotFound(f"The device {self.ip} did not answer.")
        self._connected = True
コード例 #5
0
 async def register_services(self) -> None:
     self.aiozc = AsyncZeroconf(ip_version=self.ip_version,
                                interfaces=[self.interface])  # type: ignore
     tasks = [
         self.aiozc.async_register_service(info,
                                           cooperating_responders=True,
                                           ttl=25) for info in self.services
     ]
     background_tasks = await asyncio.gather(*tasks)
     await asyncio.gather(*background_tasks)
     logger.info("Finished registration, press Ctrl-C to exit...")
コード例 #6
0
 async def open(self):
     """Open the zeroconf browser and begin listening
     """
     if self.running:
         return
     loop = self.loop = asyncio.get_event_loop()
     azc = self.async_zeroconf = AsyncZeroconf()
     self.zeroconf = azc.zeroconf
     fqdn = PROCAM_FQDN
     listener = self.listener = ProcamListener(discovery=self)
     await azc.async_add_service_listener(fqdn, listener)
     self.running = True
コード例 #7
0
async def _create_zc_with_cache(
    records: List[DNSRecord], ) -> Tuple[AsyncZeroconf, AsyncServiceBrowser]:
    aiozc = AsyncZeroconf(interfaces=["127.0.0.1"])
    browser = AsyncServiceBrowser(
        aiozc.zeroconf,
        ALL_MDNS_SERVICES,
        None,
        DummyListener(),
    )
    aiozc.zeroconf.cache.async_add_records(records)
    await aiozc.zeroconf.async_wait_for_start()
    return aiozc, browser
コード例 #8
0
 async def open(self):
     if self.running:
         return
     zc = self.zeroconf = AsyncZeroconf()
     coros = set()
     for service in self.services.values():
         if service.published:
             logger.info(f'Register zc service: {service.info!r}')
             coros.add(zc.async_register_service(service.info))
     if len(coros):
         await asyncio.gather(*coros)
     self.running = True
コード例 #9
0
 async def start(self):
     if self.options.enabled:
         log.info(
             hp.lc(
                 "Enabling Zeroconf service discovery",
                 hostname=f"{socket.getfqdn()}.",
                 ipaddress=self.options.ip_address,
                 port=self.port,
                 sd=self.options.name,
             ))
         self.zeroconf = AsyncZeroconf(ip_version=IPVersion.V4Only)
         await self.zeroconf.async_register_service(
             await self.get_interactor_service_info())
コード例 #10
0
    async def async_start(self):
        """Starts the accessory.

        - Call the accessory's run method.
        - Start handling accessory events.
        - Start the HAP server.
        - Publish a mDNS advertisement.
        - Print the setup QR code if the accessory is not paired.

        All of the above are started in separate threads. Accessory thread is set as
        daemon.
        """
        self._validate_start()
        self.aio_stop_event = asyncio.Event()

        logger.info(
            "Starting accessory %s on address %s, port %s.",
            self.accessory.display_name,
            self.state.address,
            self.state.port,
        )

        # Start listening for requests
        logger.debug("Starting server.")
        await self.http_server.async_start(self.loop)

        # Advertise the accessory as a mDNS service.
        logger.debug("Starting mDNS.")
        self.mdns_service_info = AccessoryMDNSServiceInfo(self.accessory, self.state)

        if not self.advertiser:
            zc_args = {}
            if self.interface_choice is not None:
                zc_args["interfaces"] = self.interface_choice
            self.advertiser = AsyncZeroconf(**zc_args)
        await self.advertiser.async_register_service(
            self.mdns_service_info, cooperating_responders=True
        )

        # Print accessory setup message
        if not self.state.paired:
            self.accessory.setup_message()

        # Start the accessory so it can do stuff.
        logger.debug("Starting accessory %s", self.accessory.display_name)
        self.add_job(self.accessory.run)
        logger.debug(
            "AccessoryDriver for %s started successfully", self.accessory.display_name
        )
コード例 #11
0
 def __init__(self, logger):
     self.logger = logger
     self.loop = asyncio.get_event_loop()
     self.async_zeroconf = AsyncZeroconf()
     self.zeroconf = Zeroconf()