async def connect(self) -> None: """Initiate connection to device.""" if not self._protocol_handlers: raise exceptions.NoServiceError("no service to connect to") # TODO: Parallelize with asyncio.gather? Needs to handle cancling # of ongoing tasks in case of error. for protocol_connect, _, _ in self._protocol_handlers.values(): await protocol_connect()
def main_service(self, protocol: Protocol = None) -> BaseService: """Return suggested service used to establish connection.""" protocols = ([protocol] if protocol is not None else [Protocol.MRP, Protocol.DMAP]) for prot in protocols: service = self._services.get(prot) if service is not None: return service raise exceptions.NoServiceError("no service to connect to")
def main_service(self, protocol=None): """Return suggested service used to establish connection.""" protocols = [protocol] if protocol is not None else \ [Protocol.MRP, Protocol.DMAP] for prot in protocols: service = self.get_service(prot) if service is not None: return service raise exceptions.NoServiceError( 'no service to connect to')
async def connect( config: interface.BaseConfig, loop: asyncio.AbstractEventLoop, protocol: Protocol = None, session: aiohttp.ClientSession = None, ) -> interface.AppleTV: """Connect to a device based on a configuration.""" if not config.services: raise exceptions.NoServiceError("no service to connect to") if config.identifier is None: raise exceptions.DeviceIdMissingError("no device identifier") config_copy = deepcopy(config) session_manager = await http.create_session(session) core_dispatcher = CoreStateDispatcher() atv = FacadeAppleTV(config_copy, session_manager, core_dispatcher) try: for proto, proto_methods in PROTOCOLS.items(): service = config_copy.get_service(proto) if service is None or not service.enabled: continue if not service.enabled: _LOGGER.debug("Ignore %s as it is disabled", proto.name) continue # Lock protocol argument so protocol does not have to deal # with that takeover_method = partial(atv.takeover, proto) # Core provides core access with a protocol specific twist core = Core( loop, config_copy, service, atv, session_manager, takeover_method, ProtocolStateDispatcher(proto, core_dispatcher), ) for setup_data in proto_methods.setup(core): atv.add_protocol(setup_data) await atv.connect() except Exception: await session_manager.close() raise else: return atv
async def connect(self) -> None: """Initiate connection to device.""" # No protocols to setup + no protocols previously set up => no service if self._protocols_to_setup.empty() and not self._protocol_handlers: raise exceptions.NoServiceError("no service to connect to") # Protocols set up already => we have already connected if self._protocol_handlers: raise exceptions.InvalidStateError("already connected") devinfo: Dict[str, Any] = {} # Set up protocols, ignoring duplicates while not self._protocols_to_setup.empty(): setup_data = self._protocols_to_setup.get() if setup_data.protocol in self._protocol_handlers: _LOGGER.debug("Protocol %s already set up, ignoring", setup_data.protocol) continue _LOGGER.debug("Connecting to protocol: %s", setup_data.protocol) if await setup_data.connect(): _LOGGER.debug("Connected to protocol: %s", setup_data.protocol) self._protocol_handlers[setup_data.protocol] = setup_data for iface, instance in setup_data.interfaces.items(): self._interfaces[iface].register(instance, setup_data.protocol) self._features.add_mapping(setup_data.protocol, setup_data.features) dict_merge(devinfo, setup_data.device_info()) self._device_info = interface.DeviceInfo(devinfo) # Forward power events in case an interface exists for it try: power = cast(interface.Power, self._interfaces[interface.Power].main_instance) power.listener = self._interfaces[interface.Power] except exceptions.NotSupportedError: _LOGGER.debug("Power management not supported by any protocols")
async def pair(config: interface.BaseConfig, protocol: Protocol, loop: asyncio.AbstractEventLoop, session: aiohttp.ClientSession = None, **kwargs): """Pair a protocol for an Apple TV.""" service = config.get_service(protocol) if not service: raise exceptions.NoServiceError(f"no service available for {protocol}") proto_methods = PROTOCOLS.get(protocol) if not proto_methods: raise RuntimeError(f"missing implementation for {protocol}") session = await http.create_session(session) try: return proto_methods.pair(config, service, session, loop, **kwargs) except Exception: await session.close() raise
async def pair(config, protocol, loop, session=None, **kwargs): """Pair with an Apple TV.""" service = config.get_service(protocol) if not service: raise exceptions.NoServiceError('no service available for protocol ' + str(protocol)) protocol_handlers = { Protocol.DMAP: DmapPairingHandler, Protocol.MRP: MrpPairingHandler, Protocol.AirPlay: AirPlayPairingHandler, } handler = protocol_handlers.get(protocol, None) if handler is None: raise exceptions.UnsupportedProtocolError(str(protocol)) if session is None: session = await net.create_session(loop) return handler(config, session, loop, **kwargs)
async def pair(config: conf.AppleTV, protocol: Protocol, loop: asyncio.AbstractEventLoop, session: aiohttp.ClientSession = None, **kwargs): """Pair a protocol for an Apple TV.""" service = config.get_service(protocol) if not service: raise exceptions.NoServiceError(f"no service available for {protocol}") handler = { Protocol.DMAP: DmapPairingHandler, Protocol.MRP: MrpPairingHandler, Protocol.AirPlay: AirPlayPairingHandler, Protocol.Companion: CompanionPairingHandler, }.get(protocol) if handler is None: raise RuntimeError(f"missing implementation for {protocol}") return handler(config, await http.create_session(session), loop, **kwargs)
async def pair(config: conf.AppleTV, protocol: Protocol, loop: asyncio.AbstractEventLoop, session: aiohttp.ClientSession = None, **kwargs): """Pair a protocol for an Apple TV.""" service = config.get_service(protocol) if not service: raise exceptions.NoServiceError("no service available for protocol " + str(protocol)) handler = { Protocol.DMAP: DmapPairingHandler, Protocol.MRP: MrpPairingHandler, Protocol.AirPlay: AirPlayPairingHandler, }.get(protocol) if handler is None: raise exceptions.UnsupportedProtocolError(str(protocol)) return handler(config, await net.create_session(session), loop, **kwargs)
async def connect( config: conf.AppleTV, loop: asyncio.AbstractEventLoop, protocol: Protocol = None, session: aiohttp.ClientSession = None, ) -> interface.AppleTV: """Connect to a device based on a configuration.""" if not config.services: raise exceptions.NoServiceError("no service to connect to") if config.identifier is None: raise exceptions.DeviceIdMissingError("no device identifier") session_manager = await http.create_session(session) atv = FacadeAppleTV(config, session_manager) for service in config.services: setup_method = _PROTOCOL_IMPLEMENTATIONS.get(service.protocol) if not setup_method: raise RuntimeError( "missing implementation for protocol {service.protocol}") setup_data = setup_method(loop, config, atv.interfaces, atv, session_manager) if setup_data: _LOGGER.debug("Adding protocol %s", service.protocol) atv.add_protocol(service.protocol, setup_data) else: _LOGGER.debug("Not adding protocol: %s", service.protocol) try: await atv.connect() except Exception: await session_manager.close() raise else: return atv