Esempio n. 1
0
    async def _connect(self, conf):
        """Connect to device."""
        credentials = self.config_entry.data[CONF_CREDENTIALS]
        session = async_get_clientsession(self.hass)

        for protocol_int, creds in credentials.items():
            protocol = Protocol(int(protocol_int))
            if conf.get_service(protocol) is not None:
                conf.set_credentials(protocol, creds)
            else:
                _LOGGER.warning(
                    "Protocol %s not found for %s, functionality will be reduced",
                    protocol.name,
                    self.config_entry.data[CONF_NAME],
                )

        _LOGGER.debug("Connecting to device %s", self.config_entry.data[CONF_NAME])
        self.atv = await connect(conf, self.hass.loop, session=session)
        self.atv.listener = self

        self._dispatch_send(SIGNAL_CONNECTED, self.atv)
        self._address_updated(str(conf.address))

        await self._async_setup_device_registry()

        self._connection_attempts = 0
        if self._connection_was_lost:
            _LOGGER.info(
                'Connection was re-established to device "%s"',
                self.config_entry.data[CONF_NAME],
            )
            self._connection_was_lost = False
Esempio n. 2
0
    async def _connect(self, conf):
        """Connect to device."""
        credentials = self.config_entry.data[CONF_CREDENTIALS]
        session = async_get_clientsession(self.hass)

        for protocol, creds in credentials.items():
            conf.set_credentials(Protocol(int(protocol)), creds)

        _LOGGER.debug("Connecting to device %s",
                      self.config_entry.data[CONF_NAME])
        self.atv = await connect(conf, self.hass.loop, session=session)
        self.atv.listener = self

        self._dispatch_send(SIGNAL_CONNECTED, self.atv)
        self._address_updated(str(conf.address))

        await self._async_setup_device_registry()

        self._connection_attempts = 0
        if self._connection_was_lost:
            _LOGGER.info(
                'Connection was re-established to Apple TV "%s"',
                self.config_entry.data[CONF_NAME],
            )
            self._connection_was_lost = False
Esempio n. 3
0
    async def _scan(self):
        """Try to find device by scanning for it."""
        identifiers = set(self.config_entry.data[CONF_IDENTIFIERS])
        address = self.config_entry.data[CONF_ADDRESS]

        # Only scan for and set up protocols that was successfully paired
        protocols = {
            Protocol(int(protocol))
            for protocol in self.config_entry.data[CONF_CREDENTIALS]
        }

        _LOGGER.debug("Discovering device %s", self.config_entry.title)
        atvs = await scan(
            self.hass.loop, identifier=identifiers, protocol=protocols, hosts=[address]
        )
        if atvs:
            return atvs[0]

        _LOGGER.debug(
            "Failed to find device %s with address %s, trying to scan",
            self.config_entry.title,
            address,
        )

        atvs = await scan(self.hass.loop, identifier=identifiers, protocol=protocols)
        if atvs:
            return atvs[0]

        _LOGGER.debug("Failed to find device %s, trying later", self.config_entry.title)

        return None
Esempio n. 4
0
    async def _scan(self):
        identifier = self.config_entry.unique_id
        address = self.config_entry.data[CONF_ADDRESS]
        protocol = Protocol(self.config_entry.data[CONF_PROTOCOL])

        self._update_state(message="Discovering device...")
        atvs = await scan(self.hass.loop,
                          identifier=identifier,
                          protocol=protocol,
                          hosts=[address])
        if atvs:
            return atvs[0]

        _LOGGER.debug(
            "Failed to find device %s with address %s, trying to scan",
            identifier,
            address,
        )

        atvs = await scan(self.hass.loop,
                          identifier=identifier,
                          protocol=protocol)
        if atvs:
            return atvs[0]

        self._update_state("Device not found, trying again later...")
        _LOGGER.debug("Failed to find device %s, trying later", identifier)

        return None
Esempio n. 5
0
    async def _scan(self):
        """Try to find device by scanning for it."""
        identifier = self.config_entry.unique_id
        address = self.config_entry.data[CONF_ADDRESS]
        protocol = Protocol(self.config_entry.data[CONF_PROTOCOL])

        _LOGGER.debug("Discovering device %s", identifier)
        atvs = await scan(self.hass.loop,
                          identifier=identifier,
                          protocol=protocol,
                          hosts=[address])
        if atvs:
            return atvs[0]

        _LOGGER.debug(
            "Failed to find device %s with address %s, trying to scan",
            identifier,
            address,
        )

        atvs = await scan(self.hass.loop,
                          identifier=identifier,
                          protocol=protocol)
        if atvs:
            return atvs[0]

        _LOGGER.debug("Failed to find device %s, trying later", identifier)

        return None
Esempio n. 6
0
    async def _scan(self):
        """Try to find device by scanning for it."""
        identifiers = set(
            self.config_entry.data.get(CONF_IDENTIFIERS,
                                       [self.config_entry.unique_id]))
        address = self.config_entry.data[CONF_ADDRESS]

        # Only scan for and set up protocols that was successfully paired
        protocols = {
            Protocol(int(protocol))
            for protocol in self.config_entry.data[CONF_CREDENTIALS]
        }

        _LOGGER.debug("Discovering device %s", self.config_entry.title)
        aiozc = await zeroconf.async_get_async_instance(self.hass)
        atvs = await scan(
            self.hass.loop,
            identifier=identifiers,
            protocol=protocols,
            hosts=[address],
            aiozc=aiozc,
        )
        if atvs:
            return atvs[0]

        _LOGGER.debug(
            "Failed to find device %s with address %s",
            self.config_entry.title,
            address,
        )
        # We no longer multicast scan for the device since as soon as async_step_zeroconf runs,
        # it will update the address and reload the config entry when the device is found.
        return None
Esempio n. 7
0
    async def _connect(self, conf):
        credentials = self.config_entry.data[CONF_CREDENTIALS]
        session = async_get_clientsession(self.hass)

        for protocol, creds in credentials.items():
            conf.set_credentials(Protocol(int(protocol)), creds)

        self._update_state("Connecting to device...")
        self.atv = await connect(conf, self.hass.loop, session=session)
        self.atv.listener = self

        self._update_state("Connected, waiting for update...", connected=True)
        self.atv.push_updater.start()

        self.address_updated(str(conf.address))

        await self._setup_device_registry()

        self.power_listener = PowerListener(self)
        self.atv.power.listener = self.power_listener
        if self.atv.power.power_state in [PowerState.On, PowerState.Unknown]:
            self._update_state(connected=True)
        else:
            self._update_state(disconnected=True)

        self._connection_attempts = 0
        if self._connection_was_lost:
            _LOGGER.info(
                'Connection was re-established to Apple TV "%s"',
                self.config_entry.data.get(CONF_NAME),
            )
            self._connection_was_lost = False
Esempio n. 8
0
    async def _connect(self, conf):
        import pyatv
        from pyatv.const import Protocol

        for protocol, credentials in self.credentials.items():
            conf.set_credentials(Protocol(int(protocol)), credentials)

        self._update_state("Connecting to device...")
        self.atv = await pyatv.connect(conf, self.hass.loop, session=self.session)
        self.atv.listener = self

        self._update_state("Connected, waiting for update...", connected=True)
        self.atv.push_updater.start()

        self.address_updater(str(conf.address))
Esempio n. 9
0
async def async_setup_entry(hass, entry):
    """Set up a config entry for Apple TV."""
    def address_updater(address):
        _LOGGER.debug("Changing address to %s", address)
        entry.data[CONF_ADDRESS] = address
        update_entry = partial(
            hass.config_entries.async_update_entry, data={**entry.data}
        )
        hass.add_job(update_entry, entry)

    from pyatv.const import Protocol
    address = entry.data[CONF_ADDRESS]
    identifier = entry.data[CONF_IDENTIFIER]
    protocol = Protocol(entry.data[CONF_PROTOCOL])
    credentials = entry.data[CONF_CREDENTIALS]
    start_off = entry.options.get(CONF_START_OFF, False)

    manager = AppleTVManager(
        hass, address, identifier, protocol, credentials, not start_off, address_updater)
    hass.data.setdefault(DOMAIN, {})[identifier] = manager

    @callback
    def on_hass_stop(event):
        """Stop push updates when hass stops."""
        asyncio.ensure_future(manager.disconnect(), loop=hass.loop)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop)

    dev_reg = await hass.helpers.device_registry.async_get_registry()
    dev_reg.async_get_or_create(
        config_entry_id=entry.entry_id,
        connections=set(),
        identifiers={(DOMAIN, entry.data[CONF_IDENTIFIER])},
        manufacturer="Apple",
        name="Apple TV",
        model="Unknown",
        sw_version="Unknown"
    )

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(entry, "media_player")
    )

    hass.async_create_task(
        discovery.async_load_platform(hass, "remote", DOMAIN, entry.data, entry.data)
    )

    return True
Esempio n. 10
0
    async def _connect(self, conf, raise_missing_credentials):
        """Connect to device."""
        credentials = self.config_entry.data[CONF_CREDENTIALS]
        name = self.config_entry.data[CONF_NAME]
        missing_protocols = []
        for protocol_int, creds in credentials.items():
            protocol = Protocol(int(protocol_int))
            if conf.get_service(protocol) is not None:
                conf.set_credentials(protocol, creds)
            else:
                missing_protocols.append(protocol.name)

        if missing_protocols:
            missing_protocols_str = ", ".join(missing_protocols)
            if raise_missing_credentials:
                raise ConfigEntryNotReady(
                    f"Protocol(s) {missing_protocols_str} not yet found for {name}, waiting for discovery."
                )
            _LOGGER.info(
                "Protocol(s) %s not yet found for %s, trying later",
                missing_protocols_str,
                name,
            )
            return

        _LOGGER.debug("Connecting to device %s",
                      self.config_entry.data[CONF_NAME])
        session = async_get_clientsession(self.hass)
        self.atv = await connect(conf, self.hass.loop, session=session)
        self.atv.listener = self

        self._dispatch_send(SIGNAL_CONNECTED, self.atv)
        self._address_updated(str(conf.address))

        self._async_setup_device_registry()

        self._connection_attempts = 0
        if self._connection_was_lost:
            _LOGGER.info(
                'Connection was re-established to device "%s"',
                self.config_entry.data[CONF_NAME],
            )
            self._connection_was_lost = False
Esempio n. 11
0
    async def _connect(self, conf):
        credentials = self.config_entry.data[CONF_CREDENTIALS]
        session = async_get_clientsession(self.hass)

        for protocol, creds in credentials.items():
            conf.set_credentials(Protocol(int(protocol)), creds)

        self._update_state("Connecting to device...")
        self.atv = await connect(conf, self.hass.loop, session=session)
        self.atv.listener = self

        self._update_state("Connected, waiting for update...", connected=True)
        self.atv.push_updater.start()

        self.address_updated(str(conf.address))

        self._connection_attempts = 0
        if self._connection_was_lost:
            _LOGGER.info('Connection was re-established to Apple TV "%s"',
                         self.atv.service.name)
            self._connection_was_lost = False
Esempio n. 12
0
    async def _scan(self):
        identifier = self.config_entry.unique_id
        address = self.config_entry.data[CONF_ADDRESS]
        protocol = Protocol(self.config_entry.data[CONF_PROTOCOL])

        self._update_state(message="Discovering device...")
        try:
            atvs = await scan(
                self.hass.loop,
                identifier=identifier,
                protocol=protocol,
                hosts=[address],
            )
            if atvs:
                return atvs[0]
        except exceptions.NonLocalSubnetError:
            _LOGGER.debug(
                "Address %s is on non-local subnet, relying on regular scan",
                address)

        _LOGGER.debug(
            "Failed to find device %s with address %s, trying to scan",
            identifier,
            address,
        )

        atvs = await scan(self.hass.loop,
                          identifier=identifier,
                          protocol=protocol)
        if atvs:
            return atvs[0]

        self._update_state("Device not found, trying again later...")
        _LOGGER.debug("Failed to find device %s, trying later", identifier)

        return None