async def async_step_user(self, user_input=None):
        """Obtain host and validate connection."""
        self.hass.data.setdefault(DATA_DISCOVERED_HOSTS, {})
        # Only a single entry is needed for all devices
        if self._async_current_entries():
            return self.async_abort(reason="already_setup")
        # Try connecting to host if provided
        errors = {}
        host = None
        if user_input is not None:
            host = user_input[CONF_HOST]
            # Map host from friendly name if in discovered hosts
            host = self.hass.data[DATA_DISCOVERED_HOSTS].get(host, host)
            heos = Heos(host)
            try:
                await heos.connect()
                self.hass.data.pop(DATA_DISCOVERED_HOSTS)
                return await self.async_step_import({CONF_HOST: host})
            except HeosError:
                errors[CONF_HOST] = "connection_failure"
            finally:
                await heos.disconnect()

        # Return form
        host_type = (str if not self.hass.data[DATA_DISCOVERED_HOSTS] else
                     vol.In(list(self.hass.data[DATA_DISCOVERED_HOSTS])))
        return self.async_show_form(
            step_id="user",
            data_schema=vol.Schema(
                {vol.Required(CONF_HOST, default=host): host_type}),
            errors=errors,
        )
Example #2
0
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
    """Initialize config entry which represents the HEOS controller."""
    # For backwards compat
    if entry.unique_id is None:
        hass.config_entries.async_update_entry(entry, unique_id=DOMAIN)

    host = entry.data[CONF_HOST]
    # Setting all_progress_events=False ensures that we only receive a
    # media position update upon start of playback or when media changes
    controller = Heos(host, all_progress_events=False)
    try:
        await controller.connect(auto_reconnect=True)
    # Auto reconnect only operates if initial connection was successful.
    except HeosError as error:
        await controller.disconnect()
        _LOGGER.debug("Unable to connect to controller %s: %s", host, error)
        raise ConfigEntryNotReady from error

    # Disconnect when shutting down
    async def disconnect_controller(event):
        await controller.disconnect()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, disconnect_controller)

    # Get players and sources
    try:
        players = await controller.get_players()
        favorites = {}
        if controller.is_signed_in:
            favorites = await controller.get_favorites()
        else:
            _LOGGER.warning(
                "%s is not logged in to a HEOS account and will be unable to retrieve "
                "HEOS favorites: Use the 'heos.sign_in' service to sign-in to a HEOS account",
                host,
            )
        inputs = await controller.get_input_sources()
    except HeosError as error:
        await controller.disconnect()
        _LOGGER.debug("Unable to retrieve players and sources: %s", error)
        raise ConfigEntryNotReady from error

    controller_manager = ControllerManager(hass, controller)
    await controller_manager.connect_listeners()

    source_manager = SourceManager(favorites, inputs)
    source_manager.connect_update(hass, controller)

    hass.data[DOMAIN] = {
        DATA_CONTROLLER_MANAGER: controller_manager,
        DATA_SOURCE_MANAGER: source_manager,
        MEDIA_PLAYER_DOMAIN: players,
    }

    services.register(hass, controller)

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(entry, MEDIA_PLAYER_DOMAIN)
    )
    return True
Example #3
0
    async def async_step_user(self, user_input=None):
        """Obtain host and validate connection."""
        from pyheos import Heos

        # Only a single entry is needed for all devices
        entries = self.hass.config_entries.async_entries(DOMAIN)
        if entries:
            return self.async_abort(reason='already_setup')

        # Try connecting to host if provided
        errors = {}
        host = None
        if user_input is not None:
            host = user_input[CONF_HOST]
            heos = Heos(host)
            try:
                await heos.connect()
                return await self.async_step_import(user_input)
            except (asyncio.TimeoutError, ConnectionError):
                errors[CONF_HOST] = 'connection_failure'
            finally:
                await heos.disconnect()

        # Return form
        return self.async_show_form(step_id='user',
                                    data_schema=vol.Schema({
                                        vol.Required(CONF_HOST, default=host):
                                        str
                                    }),
                                    errors=errors)
Example #4
0
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
    """Initialize config entry which represents the HEOS controller."""
    from pyheos import Heos, CommandError
    host = entry.data[CONF_HOST]
    # Setting all_progress_events=False ensures that we only receive a
    # media position update upon start of playback or when media changes
    controller = Heos(host, all_progress_events=False)
    try:
        await controller.connect(auto_reconnect=True)
    # Auto reconnect only operates if initial connection was successful.
    except (asyncio.TimeoutError, ConnectionError, CommandError) as error:
        await controller.disconnect()
        _LOGGER.debug("Unable to connect to controller %s: %s", host, error)
        raise ConfigEntryNotReady

    # Disconnect when shutting down

    async def disconnect_controller(event):
        await controller.disconnect()

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, disconnect_controller)

    # Get players and sources
    try:
        players = await controller.get_players()
        favorites = {}
        if controller.is_signed_in:
            favorites = await controller.get_favorites()
        else:
            _LOGGER.warning(
                "%s is not logged in to your HEOS account and will"
                " be unable to retrieve your favorites", host)
        inputs = await controller.get_input_sources()
    except (asyncio.TimeoutError, ConnectionError, CommandError) as error:
        await controller.disconnect()
        _LOGGER.debug("Unable to retrieve players and sources: %s",
                      error,
                      exc_info=isinstance(error, CommandError))
        raise ConfigEntryNotReady

    source_manager = SourceManager(favorites, inputs)
    source_manager.connect_update(hass, controller)

    hass.data[DOMAIN] = {
        DATA_CONTROLLER: controller,
        DATA_SOURCE_MANAGER: source_manager,
        MEDIA_PLAYER_DOMAIN: players
    }
    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(entry,
                                                      MEDIA_PLAYER_DOMAIN))
    return True