Example #1
0
    async def async_setup_platform(
        self,
        platform_type: str,
        platform_config: ConfigType,
        discovery_info: DiscoveryInfoType | None = None,
    ) -> None:
        """Set up a platform for this component."""
        if self.config is None:
            raise RuntimeError("async_setup needs to be called first")

        platform = await async_prepare_setup_platform(self.opp, self.config,
                                                      self.domain,
                                                      platform_type)

        if platform is None:
            return

        # Use config scan interval, fallback to platform if none set
        scan_interval = platform_config.get(
            CONF_SCAN_INTERVAL, getattr(platform, "SCAN_INTERVAL", None))
        entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE)

        key = (platform_type, scan_interval, entity_namespace)

        if key not in self._platforms:
            self._platforms[key] = self._async_init_entity_platform(
                platform_type, platform, scan_interval, entity_namespace)

        await self._platforms[key].async_setup(platform_config, discovery_info)
Example #2
0
async def async_setup_platform(opp: OpenPeerPower,
                               config: ConfigType,
                               async_add_entities,
                               discovery_info=None):
    """Set up the WUnderground sensor."""
    latitude = config.get(CONF_LATITUDE, opp.config.latitude)
    longitude = config.get(CONF_LONGITUDE, opp.config.longitude)
    pws_id = config.get(CONF_PWS_ID)

    rest = WUndergroundData(
        opp,
        config.get(CONF_API_KEY),
        pws_id,
        config.get(CONF_LANG),
        latitude,
        longitude,
    )

    if pws_id is None:
        unique_id_base = f"@{longitude:06f},{latitude:06f}"
    else:
        # Manually specified weather station, use that for unique_id
        unique_id_base = pws_id
    sensors = []
    for variable in config[CONF_MONITORED_CONDITIONS]:
        sensors.append(WUndergroundSensor(opp, rest, variable, unique_id_base))

    await rest.async_update()
    if not rest.data:
        raise PlatformNotReady

    async_add_entities(sensors, True)
Example #3
0
    def __init__(self, opp: OpenPeerPower, config: ConfigType) -> None:
        """Set all the config values if they exist and get initial state."""

        value_template: Template | None = config.get(CONF_VALUE_TEMPLATE)
        if value_template is not None:
            value_template.opp = opp

        self._opp = opp
        self._config: TcpSensorConfig = {
            CONF_NAME: config[CONF_NAME],
            CONF_HOST: config[CONF_HOST],
            CONF_PORT: config[CONF_PORT],
            CONF_TIMEOUT: config[CONF_TIMEOUT],
            CONF_PAYLOAD: config[CONF_PAYLOAD],
            CONF_UNIT_OF_MEASUREMENT: config.get(CONF_UNIT_OF_MEASUREMENT),
            CONF_VALUE_TEMPLATE: value_template,
            CONF_VALUE_ON: config.get(CONF_VALUE_ON),
            CONF_BUFFER_SIZE: config[CONF_BUFFER_SIZE],
            CONF_SSL: config[CONF_SSL],
            CONF_VERIFY_SSL: config[CONF_VERIFY_SSL],
        }

        self._ssl_context: ssl.SSLContext | None = None
        if self._config[CONF_SSL]:
            self._ssl_context = ssl.create_default_context()
            if not self._config[CONF_VERIFY_SSL]:
                self._ssl_context.check_hostname = False
                self._ssl_context.verify_mode = ssl.CERT_NONE

        self._state: str | None = None
        self.update()
Example #4
0
def validate_device_has_at_least_one_identifier(
        value: ConfigType) -> ConfigType:
    """Validate that a device info entry has at least one identifying value."""
    if not value.get(CONF_IDENTIFIERS) and not value.get(CONF_CONNECTIONS):
        raise vol.Invalid("Device must have at least one identifying value in "
                          "'identifiers' and/or 'connections'")
    return value
Example #5
0
def setup_platform(
    opp: OpenPeerPower,
    config: ConfigType,
    add_entities: Callable[[list], None],
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the GTFS sensor."""
    gtfs_dir = opp.config.path(DEFAULT_PATH)
    data = config[CONF_DATA]
    origin = config.get(CONF_ORIGIN)
    destination = config.get(CONF_DESTINATION)
    name = config.get(CONF_NAME)
    offset = config.get(CONF_OFFSET)
    include_tomorrow = config[CONF_TOMORROW]

    if not os.path.exists(gtfs_dir):
        os.makedirs(gtfs_dir)

    if not os.path.exists(os.path.join(gtfs_dir, data)):
        _LOGGER.error("The given GTFS data file/folder was not found")
        return

    (gtfs_root, _) = os.path.splitext(data)

    sqlite_file = f"{gtfs_root}.sqlite?check_same_thread=False"
    joined_path = os.path.join(gtfs_dir, sqlite_file)
    gtfs = pygtfs.Schedule(joined_path)

    # pylint: disable=no-member
    if not gtfs.feeds:
        pygtfs.append_feed(gtfs, os.path.join(gtfs_dir, data))

    add_entities(
        [GTFSDepartureSensor(gtfs, name, origin, destination, offset, include_tomorrow)]
    )
Example #6
0
async def async_get_service(
    opp: OpenPeerPower,
    config: ConfigType,
    discovery_info: DiscoveryInfoType | None = None,
) -> SlackNotificationService | None:
    """Set up the Slack notification service."""
    session = aiohttp_client.async_get_clientsession(opp)
    client = WebClient(token=config[CONF_API_KEY],
                       run_async=True,
                       session=session)

    try:
        await client.auth_test()
    except SlackApiError as err:
        _LOGGER.error("Error while setting up integration: %r", err)
        return None
    except ClientError as err:
        _LOGGER.warning(
            "Error testing connection to slack: %r "
            "Continuing setup anyway, but notify service might not work",
            err,
        )

    return SlackNotificationService(
        opp,
        client,
        config[CONF_DEFAULT_CHANNEL],
        username=config.get(CONF_USERNAME),
        icon=config.get(CONF_ICON),
    )
Example #7
0
async def async_from_config(
        opp: OpenPeerPower,
        config: ConfigType,
        config_validation: bool = True) -> ConditionCheckerType:
    """Turn a condition configuration into a method.

    Should be run on the event loop.
    """
    for fmt in (ASYNC_FROM_CONFIG_FORMAT, FROM_CONFIG_FORMAT):
        factory = getattr(sys.modules[__name__],
                          fmt.format(config.get(CONF_CONDITION)), None)

        if factory:
            break

    if factory is None:
        raise OpenPeerPowerError('Invalid condition "{}" specified {}'.format(
            config.get(CONF_CONDITION), config))

    # Check for partials to properly determine if coroutine function
    check_factory = factory
    while isinstance(check_factory, ft.partial):
        check_factory = check_factory.func

    if asyncio.iscoroutinefunction(check_factory):
        return cast(ConditionCheckerType, await
                    factory(opp, config, config_validation))
    return cast(ConditionCheckerType, factory(config, config_validation))
Example #8
0
def get_engine(
    opp: OpenPeerPower,
    config: ConfigType,
    discovery_info: DiscoveryInfoType | None = None,
) -> Provider | None:
    """Set up Amazon Polly speech component."""
    output_format = config[CONF_OUTPUT_FORMAT]
    sample_rate = config.get(CONF_SAMPLE_RATE,
                             DEFAULT_SAMPLE_RATES[output_format])
    if sample_rate not in SUPPORTED_SAMPLE_RATES_MAP[output_format]:
        _LOGGER.error("%s is not a valid sample rate for %s", sample_rate,
                      output_format)
        return None

    config[CONF_SAMPLE_RATE] = sample_rate

    profile: str | None = config.get(CONF_PROFILE_NAME)

    if profile is not None:
        boto3.setup_default_session(profile_name=profile)

    aws_config = {
        CONF_REGION:
        config[CONF_REGION],
        CONF_ACCESS_KEY_ID:
        config.get(CONF_ACCESS_KEY_ID),
        CONF_SECRET_ACCESS_KEY:
        config.get(CONF_SECRET_ACCESS_KEY),
        "config":
        botocore.config.Config(
            connect_timeout=AWS_CONF_CONNECT_TIMEOUT,
            read_timeout=AWS_CONF_READ_TIMEOUT,
            max_pool_connections=AWS_CONF_MAX_POOL_CONNECTIONS,
        ),
    }

    del config[CONF_REGION]
    del config[CONF_ACCESS_KEY_ID]
    del config[CONF_SECRET_ACCESS_KEY]

    polly_client = boto3.client("polly", **aws_config)

    supported_languages: list[str] = []

    all_voices: dict[str, dict[str, str]] = {}

    all_voices_req = polly_client.describe_voices()

    for voice in all_voices_req.get("Voices", []):
        voice_id: str | None = voice.get("Id")
        if voice_id is None:
            continue
        all_voices[voice_id] = voice
        language_code: str | None = voice.get("LanguageCode")
        if language_code is not None and language_code not in supported_languages:
            supported_languages.append(language_code)

    return AmazonPollyProvider(polly_client, config, supported_languages,
                               all_voices)
Example #9
0
async def async_attach_trigger(
    opp: OpenPeerPower,
    config: ConfigType,
    action: AutomationActionType,
    automation_info: dict,
) -> CALLBACK_TYPE:
    """Attach a trigger."""
    if config[CONF_TYPE] in STATE_TRIGGER_TYPES:
        if config[CONF_TYPE] == "opened":
            to_state = STATE_OPEN
        elif config[CONF_TYPE] == "closed":
            to_state = STATE_CLOSED
        elif config[CONF_TYPE] == "opening":
            to_state = STATE_OPENING
        elif config[CONF_TYPE] == "closing":
            to_state = STATE_CLOSING

        state_config = {
            CONF_PLATFORM: "state",
            CONF_ENTITY_ID: config[CONF_ENTITY_ID],
            state_trigger.CONF_TO: to_state,
        }
        if CONF_FOR in config:
            state_config[CONF_FOR] = config[CONF_FOR]
        state_config = state_trigger.TRIGGER_SCHEMA(state_config)
        return await state_trigger.async_attach_trigger(opp,
                                                        state_config,
                                                        action,
                                                        automation_info,
                                                        platform_type="device")

    if config[CONF_TYPE] == "position":
        position = "current_position"
    if config[CONF_TYPE] == "tilt_position":
        position = "current_tilt_position"
    min_pos = config.get(CONF_ABOVE, -1)
    max_pos = config.get(CONF_BELOW, 101)
    value_template = f"{{{{ state.attributes.{position} }}}}"

    numeric_state_config = {
        CONF_PLATFORM: "numeric_state",
        CONF_ENTITY_ID: config[CONF_ENTITY_ID],
        CONF_BELOW: max_pos,
        CONF_ABOVE: min_pos,
        CONF_VALUE_TEMPLATE: value_template,
    }
    numeric_state_config = numeric_state_trigger.TRIGGER_SCHEMA(
        numeric_state_config)
    return await numeric_state_trigger.async_attach_trigger(
        opp,
        numeric_state_config,
        action,
        automation_info,
        platform_type="device")
Example #10
0
def zone_from_config(config: ConfigType,
                     config_validation: bool = True) -> ConditionCheckerType:
    """Wrap action method with zone based condition."""
    if config_validation:
        config = cv.ZONE_CONDITION_SCHEMA(config)
    entity_id = config.get(CONF_ENTITY_ID)
    zone_entity_id = config.get(CONF_ZONE)

    def if_in_zone(opp: OpenPeerPower,
                   variables: TemplateVarsType = None) -> bool:
        """Test if condition."""
        return zone(opp, zone_entity_id, entity_id)

    return if_in_zone
Example #11
0
def state_from_config(config: ConfigType,
                      config_validation: bool = True) -> ConditionCheckerType:
    """Wrap action method with state based condition."""
    if config_validation:
        config = cv.STATE_CONDITION_SCHEMA(config)
    entity_id = config.get(CONF_ENTITY_ID)
    req_state = cast(str, config.get(CONF_STATE))
    for_period = config.get("for")

    def if_state(opp: OpenPeerPower,
                 variables: TemplateVarsType = None) -> bool:
        """Test if condition."""
        return state(opp, entity_id, req_state, for_period)

    return if_state
Example #12
0
def time_from_config(config: ConfigType,
                     config_validation: bool = True) -> ConditionCheckerType:
    """Wrap action method with time based condition."""
    if config_validation:
        config = cv.TIME_CONDITION_SCHEMA(config)
    before = config.get(CONF_BEFORE)
    after = config.get(CONF_AFTER)
    weekday = config.get(CONF_WEEKDAY)

    def time_if(opp: OpenPeerPower,
                variables: TemplateVarsType = None) -> bool:
        """Validate time based if-condition."""
        return time(before, after, weekday)

    return time_if
Example #13
0
def _try_update_unique_id(
    opp: OpenPeerPower, config: ConfigType, camera_config: ConfigType
) -> None:
    dimension = camera_config.get(CONF_DIMENSION, DEFAULT_DIMENSION)
    country = camera_config.get(CONF_COUNTRY, DEFAULT_COUNTRY)

    registry = entity_registry.async_get(opp)
    entity_id = registry.async_get_entity_id("camera", DOMAIN, f"{dimension}_{country}")

    if entity_id is not None:
        latitude = config[CONF_LATITUDE]
        longitude = config[CONF_LONGITUDE]

        new_unique_id = f"{latitude:2.6f}{longitude:2.6f}"
        registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
Example #14
0
def async_numeric_state_from_config(
    config: ConfigType, config_validation: bool = True
) -> ConditionCheckerType:
    """Wrap action method with state based condition."""
    if config_validation:
        config = cv.NUMERIC_STATE_CONDITION_SCHEMA(config)
    entity_ids = config.get(CONF_ENTITY_ID, [])
    attribute = config.get(CONF_ATTRIBUTE)
    below = config.get(CONF_BELOW)
    above = config.get(CONF_ABOVE)
    value_template = config.get(CONF_VALUE_TEMPLATE)

    @trace_condition_function
    def if_numeric_state(
        opp: OpenPeerPower, variables: TemplateVarsType = None
    ) -> bool:
        """Test numeric state condition."""
        if value_template is not None:
            value_template.opp = opp

        errors = []
        for index, entity_id in enumerate(entity_ids):
            try:
                with trace_path(["entity_id", str(index)]), trace_condition(variables):
                    if not async_numeric_state(
                        opp,
                        entity_id,
                        below,
                        above,
                        value_template,
                        variables,
                        attribute,
                    ):
                        return False
            except ConditionError as ex:
                errors.append(
                    ConditionErrorIndex(
                        "numeric_state", index=index, total=len(entity_ids), error=ex
                    )
                )

        # Raise the errors if no check was false
        if errors:
            raise ConditionErrorContainer("numeric_state", errors=errors)

        return True

    return if_numeric_state
Example #15
0
async def async_setup_platform(
    opp: OpenPeerPowerType, config: ConfigType, async_add_entities, discovery_info=None
) -> None:
    """Initialize light.group platform."""
    async_add_entities(
        [LightGroup(cast(str, config.get(CONF_NAME)), config[CONF_ENTITIES])]
    )
Example #16
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up UpCloud component."""
    domain_config = config.get(DOMAIN)
    if not domain_config:
        return True

    _LOGGER.warning(
        "Loading upcloud via top level config is deprecated and no longer "
        "necessary as of 0.117; Please remove it from your YAML configuration"
    )
    opp.async_create_task(
        opp.config_entries.flow.async_init(
            DOMAIN,
            context={"source": SOURCE_IMPORT},
            data={
                CONF_USERNAME: domain_config[CONF_USERNAME],
                CONF_PASSWORD: domain_config[CONF_PASSWORD],
            },
        )
    )

    if domain_config[CONF_SCAN_INTERVAL]:
        opp.data[DATA_UPCLOUD] = UpCloudHassData()
        opp.data[DATA_UPCLOUD].scan_interval_migrations[
            domain_config[CONF_USERNAME]
        ] = domain_config[CONF_SCAN_INTERVAL]

    return True
Example #17
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Start the MQTT protocol service."""
    conf: ConfigType | None = config.get(DOMAIN)

    websocket_api.async_register_command(opp, websocket_subscribe)
    websocket_api.async_register_command(opp, websocket_remove_device)
    websocket_api.async_register_command(opp, websocket_mqtt_info)

    if conf is None:
        # If we have a config entry, setup is done by that config entry.
        # If there is no config entry, this should fail.
        return bool(opp.config_entries.async_entries(DOMAIN))

    conf = dict(conf)

    opp.data[DATA_MQTT_CONFIG] = conf

    # Only import if we haven't before.
    if not opp.config_entries.async_entries(DOMAIN):
        opp.async_create_task(
            opp.config_entries.flow.async_init(
                DOMAIN,
                context={"source": config_entries.SOURCE_IMPORT},
                data={}))

    return True
Example #18
0
def sun_from_config(config: ConfigType,
                    config_validation: bool = True) -> ConditionCheckerType:
    """Wrap action method with sun based condition."""
    if config_validation:
        config = cv.SUN_CONDITION_SCHEMA(config)
    before = config.get("before")
    after = config.get("after")
    before_offset = config.get("before_offset")
    after_offset = config.get("after_offset")

    def time_if(opp: OpenPeerPower,
                variables: TemplateVarsType = None) -> bool:
        """Validate time based if-condition."""
        return sun(opp, before, after, before_offset, after_offset)

    return time_if
Example #19
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up an input slider."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    id_manager = collection.IDManager()

    yaml_collection = collection.YamlCollection(
        logging.getLogger(f"{__name__}.yaml_collection"), id_manager)
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     yaml_collection, InputNumber.from_yaml)

    storage_collection = NumberStorageCollection(
        Store(opp, STORAGE_VERSION, STORAGE_KEY),
        logging.getLogger(f"{__name__}.storage_collection"),
        id_manager,
    )
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     storage_collection, InputNumber)

    await yaml_collection.async_load([{
        CONF_ID: id_,
        **(conf or {})
    } for id_, conf in config.get(DOMAIN, {}).items()])
    await storage_collection.async_load()

    collection.StorageCollectionWebsocket(storage_collection, DOMAIN, DOMAIN,
                                          CREATE_FIELDS,
                                          UPDATE_FIELDS).async_setup(opp)

    async def reload_service_handler(service_call: ServiceCall) -> None:
        """Reload yaml entities."""
        conf = await component.async_prepare_reload(skip_reset=True)
        if conf is None:
            conf = {DOMAIN: {}}
        await yaml_collection.async_load([{
            CONF_ID: id_,
            **conf
        } for id_, conf in conf.get(DOMAIN, {}).items()])

    openpeerpower.helpers.service.async_register_admin_service(
        opp,
        DOMAIN,
        SERVICE_RELOAD,
        reload_service_handler,
        schema=RELOAD_SERVICE_SCHEMA,
    )

    component.async_register_entity_service(
        SERVICE_SET_VALUE,
        {vol.Required(ATTR_VALUE): vol.Coerce(float)},
        "async_set_value",
    )

    component.async_register_entity_service(SERVICE_INCREMENT, {},
                                            "async_increment")

    component.async_register_entity_service(SERVICE_DECREMENT, {},
                                            "async_decrement")

    return True
Example #20
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up an input select."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    id_manager = collection.IDManager()

    yaml_collection = collection.YamlCollection(
        logging.getLogger(f"{__name__}.yaml_collection"), id_manager)
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     yaml_collection, Timer.from_yaml)

    storage_collection = TimerStorageCollection(
        Store(opp, STORAGE_VERSION, STORAGE_KEY),
        logging.getLogger(f"{__name__}.storage_collection"),
        id_manager,
    )
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     storage_collection, Timer)

    await yaml_collection.async_load([{
        CONF_ID: id_,
        **cfg
    } for id_, cfg in config.get(DOMAIN, {}).items()])
    await storage_collection.async_load()

    collection.StorageCollectionWebsocket(storage_collection, DOMAIN, DOMAIN,
                                          CREATE_FIELDS,
                                          UPDATE_FIELDS).async_setup(opp)

    async def reload_service_handler(service_call: ServiceCall) -> None:
        """Reload yaml entities."""
        conf = await component.async_prepare_reload(skip_reset=True)
        if conf is None:
            conf = {DOMAIN: {}}
        await yaml_collection.async_load([{
            CONF_ID: id_,
            **cfg
        } for id_, cfg in conf.get(DOMAIN, {}).items()])

    openpeerpower.helpers.service.async_register_admin_service(
        opp,
        DOMAIN,
        SERVICE_RELOAD,
        reload_service_handler,
        schema=RELOAD_SERVICE_SCHEMA,
    )
    component.async_register_entity_service(
        SERVICE_START,
        {
            vol.Optional(ATTR_DURATION, default=DEFAULT_DURATION):
            cv.time_period
        },
        "async_start",
    )
    component.async_register_entity_service(SERVICE_PAUSE, {}, "async_pause")
    component.async_register_entity_service(SERVICE_CANCEL, {}, "async_cancel")
    component.async_register_entity_service(SERVICE_FINISH, {}, "async_finish")

    return True
Example #21
0
async def async_setup(opp: OpenPeerPowerType, config: ConfigType) -> bool:
    """Set up an input text."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    id_manager = collection.IDManager()

    yaml_collection = collection.YamlCollection(
        logging.getLogger(f"{__name__}.yaml_collection"), id_manager)
    collection.attach_entity_component_collection(component, yaml_collection,
                                                  InputText.from_yaml)

    storage_collection = InputTextStorageCollection(
        Store(opp, STORAGE_VERSION, STORAGE_KEY),
        logging.getLogger(f"{__name__}.storage_collection"),
        id_manager,
    )
    collection.attach_entity_component_collection(component,
                                                  storage_collection,
                                                  InputText)

    await yaml_collection.async_load([{
        CONF_ID: id_,
        **(conf or {})
    } for id_, conf in config.get(DOMAIN, {}).items()])
    await storage_collection.async_load()

    collection.StorageCollectionWebsocket(storage_collection, DOMAIN, DOMAIN,
                                          CREATE_FIELDS,
                                          UPDATE_FIELDS).async_setup(opp)

    collection.attach_entity_registry_cleaner(opp, DOMAIN, DOMAIN,
                                              yaml_collection)
    collection.attach_entity_registry_cleaner(opp, DOMAIN, DOMAIN,
                                              storage_collection)

    async def reload_service_handler(service_call: ServiceCallType) -> None:
        """Reload yaml entities."""
        conf = await component.async_prepare_reload(skip_reset=True)
        if conf is None:
            conf = {DOMAIN: {}}
        await yaml_collection.async_load([{
            CONF_ID: id_,
            **(cfg or {})
        } for id_, cfg in conf.get(DOMAIN, {}).items()])

    openpeerpower.helpers.service.async_register_admin_service(
        opp,
        DOMAIN,
        SERVICE_RELOAD,
        reload_service_handler,
        schema=RELOAD_SERVICE_SCHEMA,
    )

    component.async_register_entity_service(
        SERVICE_SET_VALUE, {vol.Required(ATTR_VALUE): cv.string},
        "async_set_value")

    return True
Example #22
0
async def async_setup(opp: OpenPeerPowerType, config: ConfigType):
    """Set up the person component."""
    entity_component = EntityComponent(_LOGGER, DOMAIN, opp)
    id_manager = collection.IDManager()
    yaml_collection = collection.YamlCollection(
        logging.getLogger(f"{__name__}.yaml_collection"), id_manager)
    storage_collection = PersonStorageCollection(
        PersonStore(opp, STORAGE_VERSION, STORAGE_KEY),
        logging.getLogger(f"{__name__}.storage_collection"),
        id_manager,
        yaml_collection,
    )

    collection.attach_entity_component_collection(
        entity_component, yaml_collection, lambda conf: Person(conf, False))
    collection.attach_entity_component_collection(
        entity_component, storage_collection, lambda conf: Person(conf, True))
    collection.attach_entity_registry_cleaner(opp, DOMAIN, DOMAIN,
                                              yaml_collection)
    collection.attach_entity_registry_cleaner(opp, DOMAIN, DOMAIN,
                                              storage_collection)

    await yaml_collection.async_load(await
                                     filter_yaml_data(opp,
                                                      config.get(DOMAIN, [])))
    await storage_collection.async_load()

    opp.data[DOMAIN] = (yaml_collection, storage_collection)

    collection.StorageCollectionWebsocket(
        storage_collection, DOMAIN, DOMAIN, CREATE_FIELDS,
        UPDATE_FIELDS).async_setup(opp, create_list=False)

    websocket_api.async_register_command(opp, ws_list_person)

    async def _handle_user_removed(event: Event) -> None:
        """Handle a user being removed."""
        user_id = event.data[ATTR_USER_ID]
        for person in storage_collection.async_items():
            if person[CONF_USER_ID] == user_id:
                await storage_collection.async_update_item(
                    person[CONF_ID], {CONF_USER_ID: None})

    opp.bus.async_listen(EVENT_USER_REMOVED, _handle_user_removed)

    async def async_reload_yaml(call: ServiceCall):
        """Reload YAML."""
        conf = await entity_component.async_prepare_reload(skip_reset=True)
        if conf is None:
            return
        await yaml_collection.async_load(await filter_yaml_data(
            opp, conf.get(DOMAIN, [])))

    service.async_register_admin_service(opp, DOMAIN, SERVICE_RELOAD,
                                         async_reload_yaml)

    return True
Example #23
0
async def async_from_config_dict(
        config: ConfigType,
        opp: core.OpenPeerPower) -> core.OpenPeerPower | None:
    """Try to configure Open Peer Power from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = monotonic()

    opp.config_entries = config_entries.ConfigEntries(opp, config)
    await opp.config_entries.async_initialize()

    # Set up core.
    _LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)

    if not all(await
               asyncio.gather(*(async_setup_component(opp, domain, config)
                                for domain in CORE_INTEGRATIONS))):
        _LOGGER.error("Open Peer Power core failed to initialize. ")
        return None

    _LOGGER.debug("Open Peer Power core initialized")

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_op_core_config(opp, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "openpeerpower", core_config,
                                      opp)
        return None
    except OpenPeerPowerError:
        _LOGGER.error("Open Peer Power core failed to initialize. "
                      "Further initialization aborted")
        return None

    await _async_set_up_integrations(opp, config)

    stop = monotonic()
    _LOGGER.info("Open Peer Power initialized in %.2fs", stop - start)

    if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:
                                                      3] < REQUIRED_NEXT_PYTHON_VER:
        msg = (
            "Support for the running Python version "
            f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
            f"be removed in the first release after {REQUIRED_NEXT_PYTHON_DATE}. "
            "Please upgrade Python to "
            f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER)} or "
            "higher.")
        _LOGGER.warning(msg)
        opp.components.persistent_notification.async_create(
            msg, "Python version", "python_version")

    return opp
Example #24
0
async def async_setup_platform(
    opp: OpenPeerPowerType,
    config: ConfigType,
    async_add_entities: Callable[[Sequence[Entity], bool], None],
    discovery_info: Optional[Dict] = None,
) -> None:
    """Initialize Light Switch platform."""
    async_add_entities(
        [LightSwitch(cast(str, config.get(CONF_NAME)), config[CONF_ENTITY_ID])], True
    )
Example #25
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up an input boolean."""
    component = EntityComponent(_LOGGER, DOMAIN, opp)
    id_manager = collection.IDManager()

    yaml_collection = collection.YamlCollection(
        logging.getLogger(f"{__name__}.yaml_collection"), id_manager)
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     yaml_collection, InputBoolean.from_yaml)

    storage_collection = InputBooleanStorageCollection(
        Store(opp, STORAGE_VERSION, STORAGE_KEY),
        logging.getLogger(f"{__name__}.storage_collection"),
        id_manager,
    )
    collection.sync_entity_lifecycle(opp, DOMAIN, DOMAIN, component,
                                     storage_collection, InputBoolean)

    await yaml_collection.async_load([{
        CONF_ID: id_,
        **(conf or {})
    } for id_, conf in config.get(DOMAIN, {}).items()])
    await storage_collection.async_load()

    collection.StorageCollectionWebsocket(storage_collection, DOMAIN, DOMAIN,
                                          CREATE_FIELDS,
                                          UPDATE_FIELDS).async_setup(opp)

    async def reload_service_handler(service_call: ServiceCall) -> None:
        """Remove all input booleans and load new ones from config."""
        conf = await component.async_prepare_reload(skip_reset=True)
        if conf is None:
            return
        await yaml_collection.async_load([{
            CONF_ID: id_,
            **(conf or {})
        } for id_, conf in conf.get(DOMAIN, {}).items()])

    openpeerpower.helpers.service.async_register_admin_service(
        opp,
        DOMAIN,
        SERVICE_RELOAD,
        reload_service_handler,
        schema=RELOAD_SERVICE_SCHEMA,
    )

    component.async_register_entity_service(SERVICE_TURN_ON, {},
                                            "async_turn_on")

    component.async_register_entity_service(SERVICE_TURN_OFF, {},
                                            "async_turn_off")

    component.async_register_entity_service(SERVICE_TOGGLE, {}, "async_toggle")

    return True
Example #26
0
def async_numeric_state_from_config(
        config: ConfigType,
        config_validation: bool = True) -> ConditionCheckerType:
    """Wrap action method with state based condition."""
    if config_validation:
        config = cv.NUMERIC_STATE_CONDITION_SCHEMA(config)
    entity_id = config.get(CONF_ENTITY_ID)
    below = config.get(CONF_BELOW)
    above = config.get(CONF_ABOVE)
    value_template = config.get(CONF_VALUE_TEMPLATE)

    def if_numeric_state(opp: OpenPeerPower,
                         variables: TemplateVarsType = None) -> bool:
        """Test numeric state condition."""
        if value_template is not None:
            value_template.opp = opp

        return async_numeric_state(opp, entity_id, below, above,
                                   value_template, variables)

    return if_numeric_state
Example #27
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up Meteo-France from legacy config file."""
    conf = config.get(DOMAIN)
    if not conf:
        return True

    for city_conf in conf:
        opp.async_create_task(
            opp.config_entries.flow.async_init(
                DOMAIN, context={"source": SOURCE_IMPORT}, data=city_conf))

    return True
Example #28
0
def zone_from_config(
    config: ConfigType, config_validation: bool = True
) -> ConditionCheckerType:
    """Wrap action method with zone based condition."""
    if config_validation:
        config = cv.ZONE_CONDITION_SCHEMA(config)
    entity_ids = config.get(CONF_ENTITY_ID, [])
    zone_entity_ids = config.get(CONF_ZONE, [])

    @trace_condition_function
    def if_in_zone(opp: OpenPeerPower, variables: TemplateVarsType = None) -> bool:
        """Test if condition."""
        errors = []

        all_ok = True
        for entity_id in entity_ids:
            entity_ok = False
            for zone_entity_id in zone_entity_ids:
                try:
                    if zone(opp, zone_entity_id, entity_id):
                        entity_ok = True
                except ConditionErrorMessage as ex:
                    errors.append(
                        ConditionErrorMessage(
                            "zone",
                            f"error matching {entity_id} with {zone_entity_id}: {ex.message}",
                        )
                    )

            if not entity_ok:
                all_ok = False

        # Raise the errors only if no definitive result was found
        if errors and not all_ok:
            raise ConditionErrorContainer("zone", errors=errors)

        return all_ok

    return if_in_zone
Example #29
0
def validate_input(opp: OpenPeerPower, data: ConfigType) -> bool:
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    # constructor does login call
    Api(
        data[CONF_USERNAME],
        data[CONF_PASSWORD],
        data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT),
    )

    return True
Example #30
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Set up iCloud from legacy config file."""

    conf = config.get(DOMAIN)
    if conf is None:
        return True

    for account_conf in conf:
        opp.async_create_task(
            opp.config_entries.flow.async_init(
                DOMAIN, context={"source": SOURCE_IMPORT}, data=account_conf))

    return True