Exemplo n.º 1
0
 async def async_start(self) -> None:
     """Start the scanner."""
     self.description_manager = DescriptionManager(self.hass)
     self.flow_dispatcher = FlowDispatcher(self.hass)
     for source_ip in await self._async_build_source_set():
         self._ssdp_listeners.append(
             SSDPListener(async_callback=self._async_process_entry,
                          source_ip=source_ip))
         try:
             IPv4Address(source_ip)
         except ValueError:
             continue
         # Some sonos devices only seem to respond if we send to the broadcast
         # address. This matches pysonos' behavior
         # https://github.com/amelchio/pysonos/blob/d4329b4abb657d106394ae69357805269708c996/pysonos/discovery.py#L120
         self._ssdp_listeners.append(
             SSDPListener(
                 async_callback=self._async_process_entry,
                 source_ip=source_ip,
                 target_ip=IPV4_BROADCAST,
             ))
     self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                     self.async_stop)
     self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED,
                                     self.flow_dispatcher.async_start)
     await asyncio.gather(
         *[listener.async_start() for listener in self._ssdp_listeners])
     self._cancel_scan = async_track_time_interval(self.hass,
                                                   self.async_scan,
                                                   SCAN_INTERVAL)
Exemplo n.º 2
0
def _patched_ssdp_listener(info, *args, **kwargs):
    listener = SSDPListener(*args, **kwargs)

    async def _async_callback(*_):
        await listener.async_callback(info)

    listener.async_start = _async_callback
    return listener
Exemplo n.º 3
0
    def _generate_failing_ssdp_listener(*args, **kwargs):
        create_args.append([args, kwargs])
        listener = SSDPListener(*args, **kwargs)

        async def _async_callback(*_):
            if kwargs["source_ip"] == IPv6Address("2001:db8::"):
                raise OSError
            pass

        listener.async_start = _async_callback
        listener.async_search = _callback
        return listener
Exemplo n.º 4
0
    def _generate_fake_ssdp_listener(*args, **kwargs):
        listener = SSDPListener(*args, **kwargs)

        async def _async_callback(*_):
            pass

        @callback
        def _callback(*_):
            hass.async_create_task(listener.async_callback(mock_ssdp_response))

        listener.async_start = _async_callback
        listener.async_search = _callback
        return listener
Exemplo n.º 5
0
    def _generate_fake_ssdp_listener(*args, **kwargs):
        create_args.append([args, kwargs])
        listener = SSDPListener(*args, **kwargs)

        async def _async_callback(*_):
            pass

        @callback
        def _callback(*_):
            pass

        listener.async_start = _async_callback
        listener.async_search = _callback
        return listener
Exemplo n.º 6
0
def _patched_ssdp_listener(info, *args, **kwargs):
    listener = SSDPListener(*args, **kwargs)

    async def _async_callback(*_):
        await listener.async_callback(info)

    @callback
    def _async_search(*_):
        # Prevent an actual scan.
        pass

    listener.async_start = _async_callback
    listener.async_search = _async_search
    return listener
Exemplo n.º 7
0
    def _generate_fake_ssdp_listener(*args, **kwargs):
        listener = SSDPListener(*args, **kwargs)

        async def _async_callback(*_):
            pass

        @callback
        def _callback(*args):
            nonlocal search_args
            search_args.append(args)
            pass

        listener.async_start = _async_callback
        listener.async_search = _callback
        return listener
Exemplo n.º 8
0
 async def async_start(self) -> None:
     """Start the scanner."""
     self.description_manager = DescriptionManager(self.hass)
     self.flow_dispatcher = FlowDispatcher(self.hass)
     for source_ip in await self._async_build_source_set():
         self._ssdp_listeners.append(
             SSDPListener(
                 async_connect_callback=self.async_scan,
                 async_callback=self._async_process_entry,
                 source_ip=source_ip,
             )
         )
     self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.async_stop)
     self.hass.bus.async_listen_once(
         EVENT_HOMEASSISTANT_STARTED, self.flow_dispatcher.async_start
     )
     results = await asyncio.gather(
         *(listener.async_start() for listener in self._ssdp_listeners),
         return_exceptions=True,
     )
     failed_listeners = []
     for idx, result in enumerate(results):
         if isinstance(result, Exception):
             _LOGGER.warning(
                 "Failed to setup listener for %s: %s",
                 self._ssdp_listeners[idx].source_ip,
                 result,
             )
             failed_listeners.append(self._ssdp_listeners[idx])
     for listener in failed_listeners:
         self._ssdp_listeners.remove(listener)
     self._cancel_scan = async_track_time_interval(
         self.hass, self.async_scan, SCAN_INTERVAL
     )
Exemplo n.º 9
0
def _patched_ssdp_listener(info, *args, **kwargs):
    listener = SSDPListener(*args, **kwargs)

    async def _async_callback(*_):
        if kwargs["source_ip"] == IPv4Address(FAIL_TO_BIND_IP):
            raise OSError
        await listener.async_connect_callback()

    @callback
    def _async_search(*_):
        if info:
            asyncio.create_task(listener.async_callback(info))

    listener.async_start = _async_callback
    listener.async_search = _async_search
    return listener
Exemplo n.º 10
0
    async def async_setup(self):
        """Set up the scanner."""
        if self._connected_events:
            await asyncio.gather(*(event.wait()
                                   for event in self._connected_events))
            return

        for idx, source_ip in enumerate(await self._async_build_source_set()):
            self._connected_events.append(asyncio.Event())

            def _wrap_async_connected_idx(idx):
                """Create a function to capture the idx cell variable."""
                async def _async_connected():
                    self._connected_events[idx].set()

                return _async_connected

            self._listeners.append(
                SSDPListener(
                    async_callback=self._async_process_entry,
                    service_type=SSDP_ST,
                    target=SSDP_TARGET,
                    source_ip=source_ip,
                    async_connect_callback=_wrap_async_connected_idx(idx),
                ))

        results = await asyncio.gather(
            *(listener.async_start() for listener in self._listeners),
            return_exceptions=True,
        )
        failed_listeners = []
        for idx, result in enumerate(results):
            if not isinstance(result, Exception):
                continue
            _LOGGER.warning(
                "Failed to setup listener for %s: %s",
                self._listeners[idx].source_ip,
                result,
            )
            failed_listeners.append(self._listeners[idx])
            self._connected_events[idx].set()

        for listener in failed_listeners:
            self._listeners.remove(listener)

        await asyncio.gather(*(event.wait()
                               for event in self._connected_events))
        self.async_scan()
Exemplo n.º 11
0
    async def async_start(self) -> None:
        """Start the scanner."""
        self.description_manager = DescriptionManager(self.hass)
        self.flow_dispatcher = FlowDispatcher(self.hass)
        for source_ip in await self._async_build_source_set():
            self._ssdp_listeners.append(
                SSDPListener(async_callback=self._async_process_entry,
                             source_ip=source_ip))

        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                        self.async_stop)
        self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED,
                                        self.flow_dispatcher.async_start)
        await asyncio.gather(
            *[listener.async_start() for listener in self._ssdp_listeners])
        self._cancel_scan = async_track_time_interval(self.hass,
                                                      self.async_scan,
                                                      SCAN_INTERVAL)