async def _async_discovery_handler(
        self, host: str, name: str, device_id: str
    ) -> FlowResult:
        """Handle Nanoleaf discovery."""
        # The name is unique and printed on the device and cannot be changed.
        await self.async_set_unique_id(name)
        self._abort_if_unique_id_configured({CONF_HOST: host})

        # Import from discovery integration
        self.device_id = device_id
        self.discovery_conf = cast(
            dict,
            await self.hass.async_add_executor_job(
                load_json, self.hass.config.path(CONFIG_FILE)
            ),
        )
        auth_token: str | None = self.discovery_conf.get(self.device_id, {}).get(
            "token",  # >= 2021.4
            self.discovery_conf.get(host, {}).get("token"),  # < 2021.4
        )
        if auth_token is not None:
            self.nanoleaf = Nanoleaf(
                async_get_clientsession(self.hass), host, auth_token
            )
            _LOGGER.warning(
                "Importing Nanoleaf %s from the discovery integration", name
            )
            return await self.async_setup_finish(discovery_integration_import=True)
        self.nanoleaf = Nanoleaf(async_get_clientsession(self.hass), host)
        self.context["title_placeholders"] = {"name": name}
        return await self.async_step_link()
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Nanoleaf from a config entry."""
    nanoleaf = Nanoleaf(
        async_get_clientsession(hass), entry.data[CONF_HOST], entry.data[CONF_TOKEN]
    )
    try:
        await nanoleaf.get_info()
    except Unavailable as err:
        raise ConfigEntryNotReady from err
    except InvalidToken as err:
        raise ConfigEntryAuthFailed from err

    async def _callback_update_light_state(event: StateEvent | EffectsEvent) -> None:
        """Receive state and effect event."""
        async_dispatcher_send(hass, f"{DOMAIN}_update_light_{nanoleaf.serial_no}")

    event_listener = asyncio.create_task(
        nanoleaf.listen_events(
            state_callback=_callback_update_light_state,
            effects_callback=_callback_update_light_state,
        )
    )

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = NanoleafEntryData(
        nanoleaf, event_listener
    )

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
 async def async_step_user(
     self, user_input: dict[str, Any] | None = None
 ) -> FlowResult:
     """Handle Nanoleaf flow initiated by the user."""
     if user_input is None:
         return self.async_show_form(
             step_id="user", data_schema=USER_SCHEMA, last_step=False
         )
     self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]})
     self.nanoleaf = Nanoleaf(
         async_get_clientsession(self.hass), user_input[CONF_HOST]
     )
     try:
         await self.nanoleaf.authorize()
     except Unavailable:
         return self.async_show_form(
             step_id="user",
             data_schema=USER_SCHEMA,
             errors={"base": "cannot_connect"},
             last_step=False,
         )
     except Unauthorized:
         pass
     except Exception:  # pylint: disable=broad-except
         _LOGGER.exception("Unknown error connecting to Nanoleaf")
         return self.async_show_form(
             step_id="user",
             data_schema=USER_SCHEMA,
             last_step=False,
             errors={"base": "unknown"},
         )
     return await self.async_step_link()
Exemple #4
0
 async def async_step_import(self, config: dict[str, Any]) -> FlowResult:
     """Handle Nanoleaf configuration import."""
     self._async_abort_entries_match({CONF_HOST: config[CONF_HOST]})
     _LOGGER.debug("Importing Nanoleaf on %s from your configuration.yaml",
                   config[CONF_HOST])
     self.nanoleaf = Nanoleaf(async_get_clientsession(self.hass),
                              config[CONF_HOST], config[CONF_TOKEN])
     return await self.async_setup_finish()
 async def async_step_reauth(self, data: dict[str, str]) -> FlowResult:
     """Handle Nanoleaf reauth flow if token is invalid."""
     self.reauth_entry = cast(
         config_entries.ConfigEntry,
         self.hass.config_entries.async_get_entry(self.context["entry_id"]),
     )
     self.nanoleaf = Nanoleaf(async_get_clientsession(self.hass), data[CONF_HOST])
     self.context["title_placeholders"] = {"name": self.reauth_entry.title}
     return await self.async_step_link()
Exemple #6
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Nanoleaf from a config entry."""
    nanoleaf = Nanoleaf(async_get_clientsession(hass), entry.data[CONF_HOST],
                        entry.data[CONF_TOKEN])

    async def async_get_state() -> None:
        """Get the state of the device."""
        try:
            await nanoleaf.get_info()
        except Unavailable as err:
            raise UpdateFailed from err
        except InvalidToken as err:
            raise ConfigEntryAuthFailed from err

    coordinator = DataUpdateCoordinator(
        hass,
        logging.getLogger(__name__),
        name=entry.title,
        update_interval=timedelta(minutes=1),
        update_method=async_get_state,
    )

    await coordinator.async_config_entry_first_refresh()

    async def update_light_state_callback(
            event: StateEvent | EffectsEvent) -> None:
        """Receive state and effect event."""
        coordinator.async_set_updated_data(None)

    event_listener = asyncio.create_task(
        nanoleaf.listen_events(
            state_callback=update_light_state_callback,
            effects_callback=update_light_state_callback,
        ))

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = NanoleafEntryData(
        nanoleaf, coordinator, event_listener)

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
Exemple #7
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Nanoleaf from a config entry."""
    nanoleaf = Nanoleaf(async_get_clientsession(hass), entry.data[CONF_HOST],
                        entry.data[CONF_TOKEN])

    async def async_get_state() -> None:
        """Get the state of the device."""
        try:
            await nanoleaf.get_info()
        except Unavailable as err:
            raise UpdateFailed from err
        except InvalidToken as err:
            raise ConfigEntryAuthFailed from err

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=entry.title,
        update_interval=timedelta(minutes=1),
        update_method=async_get_state,
    )

    await coordinator.async_config_entry_first_refresh()

    async def light_event_callback(event: StateEvent | EffectsEvent) -> None:
        """Receive state and effect event."""
        coordinator.async_set_updated_data(None)

    if supports_touch := nanoleaf.model in TOUCH_MODELS:
        device_registry = dr.async_get(hass)
        device_entry = device_registry.async_get_or_create(
            config_entry_id=entry.entry_id,
            identifiers={(DOMAIN, nanoleaf.serial_no)},
        )

        async def touch_event_callback(event: TouchEvent) -> None:
            """Receive touch event."""
            gesture_type = TOUCH_GESTURE_TRIGGER_MAP.get(event.gesture_id)
            if gesture_type is None:
                _LOGGER.debug("Received unknown touch gesture ID %s",
                              event.gesture_id)
                return
            _LOGGER.warning("Received touch gesture %s", gesture_type)
            hass.bus.async_fire(
                NANOLEAF_EVENT,
                {
                    CONF_DEVICE_ID: device_entry.id,
                    CONF_TYPE: gesture_type
                },
            )
Exemple #8
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Nanoleaf from a config entry."""
    nanoleaf = Nanoleaf(async_get_clientsession(hass), entry.data[CONF_HOST],
                        entry.data[CONF_TOKEN])
    try:
        await nanoleaf.get_info()
    except Unavailable as err:
        raise ConfigEntryNotReady from err
    except InvalidToken as err:
        raise ConfigEntryAuthFailed from err

    hass.data.setdefault(DOMAIN, {})[entry.entry_id] = nanoleaf

    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(entry, "light"))
    return True