Esempio n. 1
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up Freebox entry."""
    router = FreeboxRouter(opp, entry)
    await router.setup()

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.unique_id] = router

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    # Services
    async def async_reboot(call):
        """Handle reboot service call."""
        await router.reboot()

    opp.services.async_register(DOMAIN, SERVICE_REBOOT, async_reboot)

    async def async_close_connection(event):
        """Close Freebox connection on OPP Stop."""
        await router.close()

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP,
                                  async_close_connection))

    return True
Esempio n. 2
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up a wemo config entry."""
    config = opp.data[DOMAIN].pop("config")

    # Keep track of WeMo device subscriptions for push updates
    registry = opp.data[DOMAIN]["registry"] = pywemo.SubscriptionRegistry()
    await opp.async_add_executor_job(registry.start)
    static_conf = config.get(CONF_STATIC, [])
    wemo_dispatcher = WemoDispatcher(entry)
    wemo_discovery = WemoDiscovery(opp, wemo_dispatcher, static_conf)

    async def async_stop_wemo(event):
        """Shutdown Wemo subscriptions and subscription thread on exit."""
        _LOGGER.debug("Shutting down WeMo event subscriptions")
        await opp.async_add_executor_job(registry.stop)
        wemo_discovery.async_stop_discovery()

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, async_stop_wemo))

    # Need to do this at least once in case statics are defined and discovery is disabled
    await wemo_discovery.discover_statics()

    if config.get(CONF_DISCOVERY, DEFAULT_DISCOVERY):
        await wemo_discovery.async_discover_and_schedule()

    return True
Esempio n. 3
0
async def async_setup_entry(opp: OpenPeerPower, config_entry: ConfigEntry):
    """Set up AEMET OpenData as config entry."""
    name = config_entry.data[CONF_NAME]
    api_key = config_entry.data[CONF_API_KEY]
    latitude = config_entry.data[CONF_LATITUDE]
    longitude = config_entry.data[CONF_LONGITUDE]
    station_updates = config_entry.options.get(CONF_STATION_UPDATES, True)

    aemet = AEMET(api_key)
    weather_coordinator = WeatherUpdateCoordinator(opp, aemet, latitude,
                                                   longitude, station_updates)

    await weather_coordinator.async_config_entry_first_refresh()

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][config_entry.entry_id] = {
        ENTRY_NAME: name,
        ENTRY_WEATHER_COORDINATOR: weather_coordinator,
    }

    opp.config_entries.async_setup_platforms(config_entry, PLATFORMS)

    config_entry.async_on_unload(
        config_entry.add_update_listener(async_update_options))

    return True
Esempio n. 4
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up Plum Lightpad from a config entry."""
    _LOGGER.debug("Setting up config entry with ID = %s", entry.unique_id)

    username = entry.data.get(CONF_USERNAME)
    password = entry.data.get(CONF_PASSWORD)

    try:
        plum = await load_plum(username, password, opp)
    except ContentTypeError as ex:
        _LOGGER.error("Unable to authenticate to Plum cloud: %s", ex)
        return False
    except (ConnectTimeout, HTTPError) as ex:
        _LOGGER.error("Unable to connect to Plum cloud: %s", ex)
        raise ConfigEntryNotReady from ex

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.entry_id] = plum

    for platform in PLATFORMS:
        opp.async_create_task(
            opp.config_entries.async_forward_entry_setup(entry, platform))

    def cleanup(event):
        """Clean up resources."""
        plum.cleanup()

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, cleanup))
    return True
Esempio n. 5
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up ONVIF from a config entry."""
    if DOMAIN not in opp.data:
        opp.data[DOMAIN] = {}

    if not entry.options:
        await async_populate_options(opp, entry)

    device = ONVIFDevice(opp, entry)

    if not await device.async_setup():
        await device.device.close()
        return False

    if not device.available:
        raise ConfigEntryNotReady()

    if not entry.data.get(CONF_SNAPSHOT_AUTH):
        await async_populate_snapshot_auth(opp, device, entry)

    opp.data[DOMAIN][entry.unique_id] = device

    platforms = ["camera"]

    if device.capabilities.events:
        platforms += ["binary_sensor", "sensor"]

    opp.config_entries.async_setup_platforms(entry, platforms)

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, device.async_stop)
    )

    return True
Esempio n. 6
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up HomeKit from a config entry."""
    _async_import_options_from_data_if_missing(opp, entry)

    conf = entry.data
    options = entry.options

    name = conf[CONF_NAME]
    port = conf[CONF_PORT]
    _LOGGER.debug("Begin setup HomeKit for %s", name)

    # ip_address and advertise_ip are yaml only
    ip_address = conf.get(CONF_IP_ADDRESS)
    advertise_ip = conf.get(CONF_ADVERTISE_IP)
    # exclude_accessory_mode is only used for config flow
    # to indicate that the config entry was setup after
    # we started creating config entries for entities that
    # to run in accessory mode and that we should never include
    # these entities on the bridge. For backwards compatibility
    # with users who have not migrated yet we do not do exclude
    # these entities by default as we cannot migrate automatically
    # since it requires a re-pairing.
    exclude_accessory_mode = conf.get(CONF_EXCLUDE_ACCESSORY_MODE,
                                      DEFAULT_EXCLUDE_ACCESSORY_MODE)
    homekit_mode = options.get(CONF_HOMEKIT_MODE, DEFAULT_HOMEKIT_MODE)
    entity_config = options.get(CONF_ENTITY_CONFIG, {}).copy()
    auto_start = options.get(CONF_AUTO_START, DEFAULT_AUTO_START)
    entity_filter = FILTER_SCHEMA(options.get(CONF_FILTER, {}))

    homekit = HomeKit(
        opp,
        name,
        port,
        ip_address,
        entity_filter,
        exclude_accessory_mode,
        entity_config,
        homekit_mode,
        advertise_ip,
        entry.entry_id,
        entry.title,
    )

    entry.async_on_unload(entry.add_update_listener(_async_update_listener))
    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP,
                                  homekit.async_stop))

    opp.data[DOMAIN][entry.entry_id] = {HOMEKIT: homekit}

    if opp.state == CoreState.running:
        await homekit.async_start()
    elif auto_start:
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STARTED,
                                  homekit.async_start)

    return True
Esempio n. 7
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up a bridge from a config entry."""
    LOGGER.debug("Setting up entry %s", entry.data)
    bridge = DynaliteBridge(opp, entry.data)
    # need to do it before the listener
    opp.data[DOMAIN][entry.entry_id] = bridge
    entry.async_on_unload(entry.add_update_listener(async_entry_changed))

    if not await bridge.async_setup():
        LOGGER.error("Could not set up bridge for entry %s", entry.data)
        opp.data[DOMAIN][entry.entry_id] = None
        raise ConfigEntryNotReady

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
Esempio n. 8
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry,
                            async_add_entities) -> None:
    """Set up device tracker for FRITZ!Box component."""
    _LOGGER.debug("Starting FRITZ!Box device tracker")
    router = opp.data[DOMAIN][entry.entry_id]
    data_fritz = opp.data[DATA_FRITZ]

    @callback
    def update_router():
        """Update the values of the router."""
        _async_add_entities(router, async_add_entities, data_fritz)

    entry.async_on_unload(
        async_dispatcher_connect(opp, router.signal_device_new, update_router))

    update_router()
Esempio n. 9
0
async def async_setup_entry(
    opp: OpenPeerPower, config_entry: config_entries.ConfigEntry
) -> bool:
    """Set up a Firmata board for a config entry."""
    if DOMAIN not in opp.data:
        opp.data[DOMAIN] = {}

    _LOGGER.debug(
        "Setting up Firmata id %s, name %s, config %s",
        config_entry.entry_id,
        config_entry.data[CONF_NAME],
        config_entry.data,
    )

    board = FirmataBoard(config_entry.data)

    if not await board.async_setup():
        return False

    opp.data[DOMAIN][config_entry.entry_id] = board

    async def handle_shutdown(event) -> None:
        """Handle shutdown of board when Open Peer Power shuts down."""
        # Ensure board was not already removed previously before shutdown
        if config_entry.entry_id in opp.data[DOMAIN]:
            await board.async_reset()

    config_entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, handle_shutdown)
    )

    device_registry = await dr.async_get_registry(opp)
    device_registry.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={},
        identifiers={(DOMAIN, board.name)},
        manufacturer=FIRMATA_MANUFACTURER,
        name=board.name,
        sw_version=board.firmware_version,
    )

    for (conf, platform) in CONF_PLATFORM_MAP.items():
        if conf in config_entry.data:
            opp.async_create_task(
                opp.config_entries.async_forward_entry_setup(config_entry, platform)
            )
    return True
Esempio n. 10
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up Verisure from a config entry."""
    coordinator = VerisureDataUpdateCoordinator(opp, entry=entry)

    if not await coordinator.async_login():
        raise ConfigEntryAuthFailed

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP,
                                  coordinator.async_logout))

    await coordinator.async_config_entry_first_refresh()

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.entry_id] = coordinator

    # Set up all platforms for this device/entry.
    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
Esempio n. 11
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up fritzboxtools from config entry."""
    _LOGGER.debug("Setting up FRITZ!Box Tools component")
    fritz_tools = FritzBoxTools(
        opp=opp,
        host=entry.data[CONF_HOST],
        port=entry.data[CONF_PORT],
        username=entry.data[CONF_USERNAME],
        password=entry.data[CONF_PASSWORD],
    )

    try:
        await fritz_tools.async_setup()
        await fritz_tools.async_start(entry.options)
    except FritzSecurityError as ex:
        raise ConfigEntryAuthFailed from ex
    except FritzConnectionException as ex:
        raise ConfigEntryNotReady from ex

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.entry_id] = fritz_tools

    if DATA_FRITZ not in opp.data:
        opp.data[DATA_FRITZ] = FritzData()

    @callback
    def _async_unload(event):
        fritz_tools.async_unload()

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, _async_unload)
    )
    entry.async_on_unload(entry.add_update_listener(update_listener))

    # Load the other platforms like switch
    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    await async_setup_services(opp)

    return True
Esempio n. 12
0
async def _async_initialize(
    opp: OpenPeerPower,
    entry: ConfigEntry,
    host: str,
    device: YeelightDevice | None = None,
) -> None:
    entry_data = opp.data[DOMAIN][DATA_CONFIG_ENTRIES][entry.entry_id] = {
        DATA_PLATFORMS_LOADED: False
    }
    entry.async_on_unload(entry.add_update_listener(_async_update_listener))

    @callback
    def _async_load_platforms():
        if entry_data[DATA_PLATFORMS_LOADED]:
            return
        entry_data[DATA_PLATFORMS_LOADED] = True
        opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    if not device:
        device = await _async_get_device(opp, host, entry)
    entry_data[DATA_DEVICE] = device

    entry.async_on_unload(
        async_dispatcher_connect(
            opp,
            DEVICE_INITIALIZED.format(host),
            _async_load_platforms,
        ))

    entry.async_on_unload(device.async_unload)
    await device.async_setup()
Esempio n. 13
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up RainMachine as config entry."""
    opp.data.setdefault(DOMAIN, {DATA_CONTROLLER: {}, DATA_COORDINATOR: {}})
    opp.data[DOMAIN][DATA_COORDINATOR][entry.entry_id] = {}
    websession = aiohttp_client.async_get_clientsession(opp)
    client = Client(session=websession)

    try:
        await client.load_local(
            entry.data[CONF_IP_ADDRESS],
            entry.data[CONF_PASSWORD],
            port=entry.data[CONF_PORT],
            ssl=entry.data.get(CONF_SSL, DEFAULT_SSL),
        )
    except RainMachineError as err:
        raise ConfigEntryNotReady from err

    # regenmaschine can load multiple controllers at once, but we only grab the one
    # we loaded above:
    controller = opp.data[DOMAIN][DATA_CONTROLLER][
        entry.entry_id] = get_client_controller(client)

    entry_updates = {}
    if not entry.unique_id or is_ip_address(entry.unique_id):
        # If the config entry doesn't already have a unique ID, set one:
        entry_updates["unique_id"] = controller.mac
    if CONF_ZONE_RUN_TIME in entry.data:
        # If a zone run time exists in the config entry's data, pop it and move it to
        # options:
        data = {**entry.data}
        entry_updates["data"] = data
        entry_updates["options"] = {
            **entry.options,
            CONF_ZONE_RUN_TIME: data.pop(CONF_ZONE_RUN_TIME),
        }
    if entry_updates:
        opp.config_entries.async_update_entry(entry, **entry_updates)

    async def async_update(api_category: str) -> dict:
        """Update the appropriate API data based on a category."""
        try:
            if api_category == DATA_PROGRAMS:
                return await controller.programs.all(include_inactive=True)

            if api_category == DATA_PROVISION_SETTINGS:
                return await controller.provisioning.settings()

            if api_category == DATA_RESTRICTIONS_CURRENT:
                return await controller.restrictions.current()

            if api_category == DATA_RESTRICTIONS_UNIVERSAL:
                return await controller.restrictions.universal()

            return await controller.zones.all(details=True,
                                              include_inactive=True)
        except RainMachineError as err:
            raise UpdateFailed(err) from err

    controller_init_tasks = []
    for api_category in [
            DATA_PROGRAMS,
            DATA_PROVISION_SETTINGS,
            DATA_RESTRICTIONS_CURRENT,
            DATA_RESTRICTIONS_UNIVERSAL,
            DATA_ZONES,
    ]:
        coordinator = opp.data[DOMAIN][DATA_COORDINATOR][
            entry.entry_id][api_category] = DataUpdateCoordinator(
                opp,
                LOGGER,
                name=f'{controller.name} ("{api_category}")',
                update_interval=DEFAULT_UPDATE_INTERVAL,
                update_method=partial(async_update, api_category),
            )
        controller_init_tasks.append(coordinator.async_refresh())

    await asyncio.gather(*controller_init_tasks)

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    entry.async_on_unload(entry.add_update_listener(async_reload_entry))

    return True
Esempio n. 14
0
async def async_setup_entry(opp: OpenPeerPower, config_entry: ConfigEntry) -> bool:
    """Do setup of vera."""
    # Use options entered during initial config flow or provided from configuration.yml
    if config_entry.data.get(CONF_LIGHTS) or config_entry.data.get(CONF_EXCLUDE):
        opp.config_entries.async_update_entry(
            entry=config_entry,
            data=config_entry.data,
            options=new_options(
                config_entry.data.get(CONF_LIGHTS, []),
                config_entry.data.get(CONF_EXCLUDE, []),
            ),
        )

    saved_light_ids = config_entry.options.get(CONF_LIGHTS, [])
    saved_exclude_ids = config_entry.options.get(CONF_EXCLUDE, [])

    base_url = config_entry.data[CONF_CONTROLLER]
    light_ids = fix_device_id_list(saved_light_ids)
    exclude_ids = fix_device_id_list(saved_exclude_ids)

    # If the ids were corrected. Update the config entry.
    if light_ids != saved_light_ids or exclude_ids != saved_exclude_ids:
        opp.config_entries.async_update_entry(
            entry=config_entry, options=new_options(light_ids, exclude_ids)
        )

    # Initialize the Vera controller.
    subscription_registry = SubscriptionRegistry(opp)
    controller = veraApi.VeraController(base_url, subscription_registry)

    try:
        all_devices = await opp.async_add_executor_job(controller.get_devices)

        all_scenes = await opp.async_add_executor_job(controller.get_scenes)
    except RequestException as exception:
        # There was a network related error connecting to the Vera controller.
        _LOGGER.exception("Error communicating with Vera API")
        raise ConfigEntryNotReady from exception

    # Exclude devices unwanted by user.
    devices = [device for device in all_devices if device.device_id not in exclude_ids]

    vera_devices = defaultdict(list)
    for device in devices:
        device_type = map_vera_device(device, light_ids)
        if device_type is not None:
            vera_devices[device_type].append(device)

    vera_scenes = []
    for scene in all_scenes:
        vera_scenes.append(scene)

    controller_data = ControllerData(
        controller=controller,
        devices=vera_devices,
        scenes=vera_scenes,
        config_entry=config_entry,
    )

    set_controller_data(opp, config_entry, controller_data)

    # Forward the config data to the necessary platforms.
    for platform in get_configured_platforms(controller_data):
        opp.async_create_task(
            opp.config_entries.async_forward_entry_setup(config_entry, platform)
        )

    def stop_subscription(event):
        """Stop SubscriptionRegistry updates."""
        controller.stop()

    await opp.async_add_executor_job(controller.start)
    config_entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, stop_subscription)
    )

    config_entry.async_on_unload(
        config_entry.add_update_listener(_async_update_listener)
    )
    return True
Esempio n. 15
0
async def async_setup_entry(opp: OpenPeerPower, config_entry: ConfigEntry) -> bool:
    """Set up the UpCloud config entry."""

    manager = upcloud_api.CloudManager(
        config_entry.data[CONF_USERNAME], config_entry.data[CONF_PASSWORD]
    )

    try:
        await opp.async_add_executor_job(manager.authenticate)
    except upcloud_api.UpCloudAPIError:
        _LOGGER.error("Authentication failed", exc_info=True)
        return False
    except requests.exceptions.RequestException as err:
        _LOGGER.error("Failed to connect", exc_info=True)
        raise ConfigEntryNotReady from err

    upcloud_data = opp.data.setdefault(DATA_UPCLOUD, UpCloudHassData())

    # Handle pre config entry (0.117) scan interval migration to options
    migrated_scan_interval = upcloud_data.scan_interval_migrations.pop(
        config_entry.data[CONF_USERNAME], None
    )
    if migrated_scan_interval and (
        not config_entry.options.get(CONF_SCAN_INTERVAL)
        or config_entry.options[CONF_SCAN_INTERVAL]
        == DEFAULT_SCAN_INTERVAL.total_seconds()
    ):
        update_interval = migrated_scan_interval
        opp.config_entries.async_update_entry(
            config_entry,
            options={CONF_SCAN_INTERVAL: update_interval.total_seconds()},
        )
    elif config_entry.options.get(CONF_SCAN_INTERVAL):
        update_interval = timedelta(seconds=config_entry.options[CONF_SCAN_INTERVAL])
    else:
        update_interval = DEFAULT_SCAN_INTERVAL

    coordinator = UpCloudDataUpdateCoordinator(
        opp,
        update_interval=update_interval,
        cloud_manager=manager,
        username=config_entry.data[CONF_USERNAME],
    )

    # Call the UpCloud API to refresh data
    await coordinator.async_config_entry_first_refresh()

    # Listen to config entry updates
    config_entry.async_on_unload(
        config_entry.add_update_listener(_async_signal_options_update)
    )
    config_entry.async_on_unload(
        async_dispatcher_connect(
            opp,
            _config_entry_update_signal_name(config_entry),
            coordinator.async_update_config,
        )
    )

    upcloud_data.coordinators[config_entry.data[CONF_USERNAME]] = coordinator

    # Forward entry setup
    opp.config_entries.async_setup_platforms(config_entry, CONFIG_ENTRY_DOMAINS)

    return True
Esempio n. 16
0
async def async_setup_entry(opp: OpenPeerPower,
                            entry: config_entries.ConfigEntry) -> bool:
    """Set up the ISY 994 integration."""
    # As there currently is no way to import options from yaml
    # when setting up a config entry, we fallback to adding
    # the options to the config entry and pull them out here if
    # they are missing from the options
    _async_import_options_from_data_if_missing(opp, entry)

    opp.data[DOMAIN][entry.entry_id] = {}
    opp_isy_data = opp.data[DOMAIN][entry.entry_id]

    opp_isy_data[ISY994_NODES] = {}
    for platform in PLATFORMS:
        opp_isy_data[ISY994_NODES][platform] = []

    opp_isy_data[ISY994_PROGRAMS] = {}
    for platform in PROGRAM_PLATFORMS:
        opp_isy_data[ISY994_PROGRAMS][platform] = []

    opp_isy_data[ISY994_VARIABLES] = []

    isy_config = entry.data
    isy_options = entry.options

    # Required
    user = isy_config[CONF_USERNAME]
    password = isy_config[CONF_PASSWORD]
    host = urlparse(isy_config[CONF_HOST])

    # Optional
    tls_version = isy_config.get(CONF_TLS_VER)
    ignore_identifier = isy_options.get(CONF_IGNORE_STRING,
                                        DEFAULT_IGNORE_STRING)
    sensor_identifier = isy_options.get(CONF_SENSOR_STRING,
                                        DEFAULT_SENSOR_STRING)
    variable_identifier = isy_options.get(CONF_VAR_SENSOR_STRING,
                                          DEFAULT_VAR_SENSOR_STRING)

    if host.scheme == "http":
        https = False
        port = host.port or 80
        session = aiohttp_client.async_create_clientsession(
            opp, verify_ssl=None, cookie_jar=CookieJar(unsafe=True))
    elif host.scheme == "https":
        https = True
        port = host.port or 443
        session = aiohttp_client.async_get_clientsession(opp)
    else:
        _LOGGER.error("The isy994 host value in configuration is invalid")
        return False

    # Connect to ISY controller.
    isy = ISY(
        host.hostname,
        port,
        username=user,
        password=password,
        use_https=https,
        tls_ver=tls_version,
        webroot=host.path,
        websession=session,
        use_websocket=True,
    )

    try:
        async with async_timeout.timeout(60):
            await isy.initialize()
    except asyncio.TimeoutError as err:
        raise ConfigEntryNotReady(
            f"Timed out initializing the ISY; device may be busy, trying again later: {err}"
        ) from err
    except ISYInvalidAuthError as err:
        _LOGGER.error(
            "Invalid credentials for the ISY, please adjust settings and try again: %s",
            err,
        )
        return False
    except ISYConnectionError as err:
        raise ConfigEntryNotReady(
            f"Failed to connect to the ISY, please adjust settings and try again: {err}"
        ) from err
    except ISYResponseParseError as err:
        raise ConfigEntryNotReady(
            f"Invalid XML response from ISY; Ensure the ISY is running the latest firmware: {err}"
        ) from err

    _categorize_nodes(opp_isy_data, isy.nodes, ignore_identifier,
                      sensor_identifier)
    _categorize_programs(opp_isy_data, isy.programs)
    _categorize_variables(opp_isy_data, isy.variables, variable_identifier)

    # Dump ISY Clock Information. Future: Add ISY as sensor to Opp with attrs
    _LOGGER.info(repr(isy.clock))

    opp_isy_data[ISY994_ISY] = isy
    await _async_get_or_create_isy_device_in_registry(opp, entry, isy)

    # Load platforms for the devices in the ISY controller that we support.
    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    def _start_auto_update() -> None:
        """Start isy auto update."""
        _LOGGER.debug("ISY Starting Event Stream and automatic updates")
        isy.websocket.start()

    def _stop_auto_update(event) -> None:
        """Stop the isy auto update on Open Peer Power Shutdown."""
        _LOGGER.debug("ISY Stopping Event Stream and automatic updates")
        isy.websocket.stop()

    await opp.async_add_executor_job(_start_auto_update)

    undo_listener = entry.add_update_listener(_async_update_listener)

    opp_isy_data[UNDO_UPDATE_LISTENER] = undo_listener
    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, _stop_auto_update))

    # Register Integration-wide Services:
    async_setup_services(opp)

    return True
Esempio n. 17
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up buienradar from a config entry."""
    opp.config_entries.async_setup_platforms(entry, PLATFORMS)
    entry.async_on_unload(entry.add_update_listener(async_update_options))
    return True
Esempio n. 18
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up Sense from a config entry."""

    entry_data = entry.data
    email = entry_data[CONF_EMAIL]
    password = entry_data[CONF_PASSWORD]
    timeout = entry_data[CONF_TIMEOUT]

    client_session = async_get_clientsession(opp)

    gateway = ASyncSenseable(
        api_timeout=timeout, wss_timeout=timeout, client_session=client_session
    )
    gateway.rate_limit = ACTIVE_UPDATE_RATE

    try:
        await gateway.authenticate(email, password)
    except SenseAuthenticationException:
        _LOGGER.error("Could not authenticate with sense server")
        return False
    except SENSE_TIMEOUT_EXCEPTIONS as err:
        raise ConfigEntryNotReady from err

    sense_devices_data = SenseDevicesData()
    try:
        sense_discovered_devices = await gateway.get_discovered_device_data()
        await gateway.update_realtime()
    except SENSE_TIMEOUT_EXCEPTIONS as err:
        raise ConfigEntryNotReady from err

    trends_coordinator = DataUpdateCoordinator(
        opp,
        _LOGGER,
        name=f"Sense Trends {email}",
        update_method=gateway.update_trend_data,
        update_interval=timedelta(seconds=300),
    )

    # This can take longer than 60s and we already know
    # sense is online since get_discovered_device_data was
    # successful so we do it later.
    asyncio.create_task(trends_coordinator.async_request_refresh())

    opp.data.setdefault(DOMAIN, {})[entry.entry_id] = {
        SENSE_DATA: gateway,
        SENSE_DEVICES_DATA: sense_devices_data,
        SENSE_TRENDS_COORDINATOR: trends_coordinator,
        SENSE_DISCOVERED_DEVICES_DATA: sense_discovered_devices,
    }

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    async def async_sense_update(_):
        """Retrieve latest state."""
        try:
            await gateway.update_realtime()
        except SenseAPITimeoutException:
            _LOGGER.error("Timeout retrieving data")

        data = gateway.get_realtime()
        if "devices" in data:
            sense_devices_data.set_devices_data(data["devices"])
        async_dispatcher_send(opp, f"{SENSE_DEVICE_UPDATE}-{gateway.sense_monitor_id}")

    remove_update_callback = async_track_time_interval(
        opp, async_sense_update, timedelta(seconds=ACTIVE_UPDATE_RATE)
    )

    @callback
    def _remove_update_callback_at_stop(event):
        remove_update_callback()

    entry.async_on_unload(remove_update_callback)
    entry.async_on_unload(
        opp.bus.async_listen_once(
            EVENT_OPENPEERPOWER_STOP, _remove_update_callback_at_stop
        )
    )

    return True
Esempio n. 19
0
async def async_setup_entry(
    opp: OpenPeerPower,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up Sonos from a config entry."""
    platform = entity_platform.async_get_current_platform()

    @callback
    def async_create_entities(speaker: SonosSpeaker) -> None:
        """Handle device discovery and create entities."""
        async_add_entities([SonosMediaPlayerEntity(speaker)])

    @service.verify_domain_control(opp, SONOS_DOMAIN)
    async def async_service_handle(service_call: ServiceCall) -> None:
        """Handle dispatched services."""
        assert platform is not None
        entities = await platform.async_extract_from_service(service_call)

        if not entities:
            return

        speakers = []
        for entity in entities:
            assert isinstance(entity, SonosMediaPlayerEntity)
            speakers.append(entity.speaker)

        if service_call.service == SERVICE_JOIN:
            master = platform.entities.get(service_call.data[ATTR_MASTER])
            if master:
                await SonosSpeaker.join_multi(opp, master.speaker, speakers
                                              )  # type: ignore[arg-type]
            else:
                _LOGGER.error(
                    "Invalid master specified for join service: %s",
                    service_call.data[ATTR_MASTER],
                )
        elif service_call.service == SERVICE_UNJOIN:
            await SonosSpeaker.unjoin_multi(opp,
                                            speakers)  # type: ignore[arg-type]
        elif service_call.service == SERVICE_SNAPSHOT:
            await SonosSpeaker.snapshot_multi(
                opp,
                speakers,
                service_call.data[ATTR_WITH_GROUP]  # type: ignore[arg-type]
            )
        elif service_call.service == SERVICE_RESTORE:
            await SonosSpeaker.restore_multi(
                opp,
                speakers,
                service_call.data[ATTR_WITH_GROUP]  # type: ignore[arg-type]
            )

    config_entry.async_on_unload(
        async_dispatcher_connect(opp, SONOS_CREATE_MEDIA_PLAYER,
                                 async_create_entities))

    opp.services.async_register(
        SONOS_DOMAIN,
        SERVICE_JOIN,
        async_service_handle,
        cv.make_entity_service_schema(
            {vol.Required(ATTR_MASTER): cv.entity_id}),
    )

    opp.services.async_register(
        SONOS_DOMAIN,
        SERVICE_UNJOIN,
        async_service_handle,
        cv.make_entity_service_schema({}),
    )

    join_unjoin_schema = cv.make_entity_service_schema(
        {vol.Optional(ATTR_WITH_GROUP, default=True): cv.boolean})

    opp.services.async_register(SONOS_DOMAIN, SERVICE_SNAPSHOT,
                                async_service_handle, join_unjoin_schema)

    opp.services.async_register(SONOS_DOMAIN, SERVICE_RESTORE,
                                async_service_handle, join_unjoin_schema)

    platform.async_register_entity_service(  # type: ignore
        SERVICE_SET_TIMER,
        {
            vol.Required(ATTR_SLEEP_TIME): vol.All(
                vol.Coerce(int), vol.Range(min=0, max=86399)
            )
        },
        "set_sleep_timer",
    )

    platform.async_register_entity_service(SERVICE_CLEAR_TIMER, {},
                                           "clear_sleep_timer")  # type: ignore

    platform.async_register_entity_service(  # type: ignore
        SERVICE_UPDATE_ALARM,
        {
            vol.Required(ATTR_ALARM_ID): cv.positive_int,
            vol.Optional(ATTR_TIME): cv.time,
            vol.Optional(ATTR_VOLUME): cv.small_float,
            vol.Optional(ATTR_ENABLED): cv.boolean,
            vol.Optional(ATTR_INCLUDE_LINKED_ZONES): cv.boolean,
        },
        "set_alarm",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_SET_OPTION,
        {
            vol.Optional(ATTR_BUTTONS_ENABLED): cv.boolean,
            vol.Optional(ATTR_NIGHT_SOUND): cv.boolean,
            vol.Optional(ATTR_SPEECH_ENHANCE): cv.boolean,
            vol.Optional(ATTR_STATUS_LIGHT): cv.boolean,
        },
        "set_option",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_PLAY_QUEUE,
        {vol.Optional(ATTR_QUEUE_POSITION): cv.positive_int},
        "play_queue",
    )

    platform.async_register_entity_service(  # type: ignore
        SERVICE_REMOVE_FROM_QUEUE,
        {vol.Optional(ATTR_QUEUE_POSITION): cv.positive_int},
        "remove_from_queue",
    )
Esempio n. 20
0
async def async_setup_entry(opp: OpenPeerPower, config_entry: ConfigEntry) -> bool:
    """Set up Huawei LTE component from config entry."""
    url = config_entry.data[CONF_URL]

    # Override settings from YAML config, but only if they're changed in it
    # Old values are stored as *_from_yaml in the config entry
    yaml_config = opp.data[DOMAIN].config.get(url)
    if yaml_config:
        # Config values
        new_data = {}
        for key in CONF_USERNAME, CONF_PASSWORD:
            if key in yaml_config:
                value = yaml_config[key]
                if value != config_entry.data.get(f"{key}_from_yaml"):
                    new_data[f"{key}_from_yaml"] = value
                    new_data[key] = value
        # Options
        new_options = {}
        yaml_recipient = yaml_config.get(NOTIFY_DOMAIN, {}).get(CONF_RECIPIENT)
        if yaml_recipient is not None and yaml_recipient != config_entry.options.get(
            f"{CONF_RECIPIENT}_from_yaml"
        ):
            new_options[f"{CONF_RECIPIENT}_from_yaml"] = yaml_recipient
            new_options[CONF_RECIPIENT] = yaml_recipient
        yaml_notify_name = yaml_config.get(NOTIFY_DOMAIN, {}).get(CONF_NAME)
        if (
            yaml_notify_name is not None
            and yaml_notify_name != config_entry.options.get(f"{CONF_NAME}_from_yaml")
        ):
            new_options[f"{CONF_NAME}_from_yaml"] = yaml_notify_name
            new_options[CONF_NAME] = yaml_notify_name
        # Update entry if overrides were found
        if new_data or new_options:
            opp.config_entries.async_update_entry(
                config_entry,
                data={**config_entry.data, **new_data},
                options={**config_entry.options, **new_options},
            )

    # Get MAC address for use in unique ids. Being able to use something
    # from the API would be nice, but all of that seems to be available only
    # through authenticated calls (e.g. device_information.SerialNumber), and
    # we want this available and the same when unauthenticated too.
    host = urlparse(url).hostname
    try:
        if ipaddress.ip_address(host).version == 6:
            mode = "ip6"
        else:
            mode = "ip"
    except ValueError:
        mode = "hostname"
    mac = await opp.async_add_executor_job(partial(get_mac_address, **{mode: host}))

    def get_connection() -> Connection:
        """
        Set up a connection.

        Authorized one if username/pass specified (even if empty), unauthorized one otherwise.
        """
        username = config_entry.data.get(CONF_USERNAME)
        password = config_entry.data.get(CONF_PASSWORD)
        if username or password:
            connection: Connection = AuthorizedConnection(
                url, username=username, password=password, timeout=CONNECTION_TIMEOUT
            )
        else:
            connection = Connection(url, timeout=CONNECTION_TIMEOUT)
        return connection

    def signal_update() -> None:
        """Signal updates to data."""
        dispatcher_send(opp, UPDATE_SIGNAL, url)

    try:
        connection = await opp.async_add_executor_job(get_connection)
    except Timeout as ex:
        raise ConfigEntryNotReady from ex

    # Set up router and store reference to it
    router = Router(config_entry, connection, url, mac, signal_update)
    opp.data[DOMAIN].routers[url] = router

    # Do initial data update
    await opp.async_add_executor_job(router.update)

    # Clear all subscriptions, enabled entities will push back theirs
    router.subscriptions.clear()

    # Set up device registry
    if router.device_identifiers or router.device_connections:
        device_data = {}
        sw_version = None
        if router.data.get(KEY_DEVICE_INFORMATION):
            device_info = router.data[KEY_DEVICE_INFORMATION]
            sw_version = device_info.get("SoftwareVersion")
            if device_info.get("DeviceName"):
                device_data["model"] = device_info["DeviceName"]
        if not sw_version and router.data.get(KEY_DEVICE_BASIC_INFORMATION):
            sw_version = router.data[KEY_DEVICE_BASIC_INFORMATION].get(
                "SoftwareVersion"
            )
        if sw_version:
            device_data["sw_version"] = sw_version
        device_registry = await dr.async_get_registry(opp)
        device_registry.async_get_or_create(
            config_entry_id=config_entry.entry_id,
            connections=router.device_connections,
            identifiers=router.device_identifiers,
            name=router.device_name,
            manufacturer="Huawei",
            **device_data,
        )

    # Forward config entry setup to platforms
    opp.config_entries.async_setup_platforms(config_entry, CONFIG_ENTRY_PLATFORMS)

    # Notify doesn't support config entry setup yet, load with discovery for now
    await discovery.async_load_platform(
        opp,
        NOTIFY_DOMAIN,
        DOMAIN,
        {
            CONF_URL: url,
            CONF_NAME: config_entry.options.get(CONF_NAME, DEFAULT_NOTIFY_SERVICE_NAME),
            CONF_RECIPIENT: config_entry.options.get(CONF_RECIPIENT),
        },
        opp.data[DOMAIN].opp_config,
    )

    def _update_router(*_: Any) -> None:
        """
        Update router data.

        Separate passthrough function because lambdas don't work with track_time_interval.
        """
        router.update()

    # Set up periodic update
    config_entry.async_on_unload(
        async_track_time_interval(opp, _update_router, SCAN_INTERVAL)
    )

    # Clean up at end
    config_entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, router.cleanup)
    )

    return True
Esempio n. 21
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry) -> bool:
    """Set up the AVM FRITZ!SmartHome platforms."""
    fritz = Fritzhome(
        host=entry.data[CONF_HOST],
        user=entry.data[CONF_USERNAME],
        password=entry.data[CONF_PASSWORD],
    )

    try:
        await opp.async_add_executor_job(fritz.login)
    except LoginError as err:
        raise ConfigEntryAuthFailed from err

    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.entry_id] = {
        CONF_CONNECTIONS: fritz,
    }

    def _update_fritz_devices() -> dict[str, FritzhomeDevice]:
        """Update all fritzbox device data."""
        try:
            devices = fritz.get_devices()
        except requests.exceptions.HTTPError:
            # If the device rebooted, login again
            try:
                fritz.login()
            except requests.exceptions.HTTPError as ex:
                raise ConfigEntryAuthFailed from ex
            devices = fritz.get_devices()

        data = {}
        for device in devices:
            device.update()
            data[device.ain] = device
        return data

    async def async_update_coordinator() -> dict[str, FritzhomeDevice]:
        """Fetch all device data."""
        return await opp.async_add_executor_job(_update_fritz_devices)

    opp.data[DOMAIN][entry.entry_id][
        CONF_COORDINATOR] = coordinator = DataUpdateCoordinator(
            opp,
            LOGGER,
            name=f"{entry.entry_id}",
            update_method=async_update_coordinator,
            update_interval=timedelta(seconds=30),
        )

    await coordinator.async_config_entry_first_refresh()

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    def logout_fritzbox(event: Event) -> None:
        """Close connections to this fritzbox."""
        fritz.logout()

    entry.async_on_unload(
        opp.bus.async_listen_once(EVENT_OPENPEERPOWER_STOP, logout_fritzbox))

    return True