Example #1
0
    async def async_step_connect(self, user_input=None):
        """Connect to the Motion Gateway."""
        errors = {}
        if user_input is not None:
            key = user_input[CONF_API_KEY]
            multicast_interface = user_input[CONF_INTERFACE]

            # check socket interface
            if multicast_interface != DEFAULT_INTERFACE:
                motion_multicast = AsyncMotionMulticast(
                    interface=multicast_interface)
                try:
                    await motion_multicast.Start_listen()
                    motion_multicast.Stop_listen()
                except gaierror:
                    errors[CONF_INTERFACE] = "invalid_interface"
                    return self.async_show_form(
                        step_id="connect",
                        data_schema=self._config_settings,
                        errors=errors,
                    )

            connect_gateway_class = ConnectMotionGateway(self.hass,
                                                         multicast=None)
            if not await connect_gateway_class.async_connect_gateway(
                    self._host, key):
                return self.async_abort(reason="connection_error")
            motion_gateway = connect_gateway_class.gateway_device

            mac_address = motion_gateway.mac

            await self.async_set_unique_id(mac_address)
            self._abort_if_unique_id_configured()

            return self.async_create_entry(
                title=DEFAULT_GATEWAY_NAME,
                data={
                    CONF_HOST: self._host,
                    CONF_API_KEY: key,
                    CONF_INTERFACE: multicast_interface,
                },
            )

        (interfaces, default_interface) = await self.async_get_interfaces()

        self._config_settings = vol.Schema({
            vol.Required(CONF_API_KEY):
            vol.All(str, vol.Length(min=16, max=16)),
            vol.Optional(CONF_INTERFACE, default=default_interface):
            vol.In(interfaces),
        })

        return self.async_show_form(step_id="connect",
                                    data_schema=self._config_settings,
                                    errors=errors)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up the motion_blinds components from a config entry."""
    hass.data.setdefault(DOMAIN, {})
    host = entry.data[CONF_HOST]
    key = entry.data[CONF_API_KEY]
    multicast_interface = entry.data.get(CONF_INTERFACE, DEFAULT_INTERFACE)
    wait_for_push = entry.options.get(CONF_WAIT_FOR_PUSH,
                                      DEFAULT_WAIT_FOR_PUSH)

    entry.async_on_unload(entry.add_update_listener(update_listener))

    # Create multicast Listener
    if KEY_MULTICAST_LISTENER not in hass.data[DOMAIN]:
        multicast = AsyncMotionMulticast(interface=multicast_interface)
        hass.data[DOMAIN][KEY_MULTICAST_LISTENER] = multicast
        # start listening for local pushes (only once)
        await multicast.Start_listen()

        # register stop callback to shutdown listening for local pushes
        def stop_motion_multicast(event):
            """Stop multicast thread."""
            _LOGGER.debug("Shutting down Motion Listener")
            multicast.Stop_listen()

        hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                                   stop_motion_multicast)

    # Connect to motion gateway
    multicast = hass.data[DOMAIN][KEY_MULTICAST_LISTENER]
    connect_gateway_class = ConnectMotionGateway(hass, multicast)
    if not await connect_gateway_class.async_connect_gateway(host, key):
        raise ConfigEntryNotReady
    motion_gateway = connect_gateway_class.gateway_device
    api_lock = asyncio.Lock()
    coordinator_info = {
        KEY_GATEWAY: motion_gateway,
        KEY_API_LOCK: api_lock,
        CONF_WAIT_FOR_PUSH: wait_for_push,
    }

    coordinator = DataUpdateCoordinatorMotionBlinds(
        hass,
        _LOGGER,
        coordinator_info,
        # Name of the data. For logging purposes.
        name=entry.title,
        # Polling interval. Will only be polled if there are subscribers.
        update_interval=timedelta(seconds=UPDATE_INTERVAL),
    )

    # Fetch initial data so we have data when entities subscribe
    await coordinator.async_config_entry_first_refresh()

    if motion_gateway.firmware is not None:
        version = f"{motion_gateway.firmware}, protocol: {motion_gateway.protocol}"
    else:
        version = f"Protocol: {motion_gateway.protocol}"

    hass.data[DOMAIN][entry.entry_id] = {
        KEY_GATEWAY: motion_gateway,
        KEY_COORDINATOR: coordinator,
        KEY_VERSION: version,
    }

    if TYPE_CHECKING:
        assert entry.unique_id is not None

    if motion_gateway.device_type not in DEVICE_TYPES_WIFI:
        device_registry = dr.async_get(hass)
        device_registry.async_get_or_create(
            config_entry_id=entry.entry_id,
            connections={(dr.CONNECTION_NETWORK_MAC, motion_gateway.mac)},
            identifiers={(DOMAIN, motion_gateway.mac)},
            manufacturer=MANUFACTURER,
            name=entry.title,
            model="Wi-Fi bridge",
            sw_version=version,
        )

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True