Ejemplo n.º 1
0
async def test_load_application_credentials(
    hass: HomeAssistant,
    component_setup: ComponentSetup,
    mock_calendars_yaml: None,
    mock_calendars_list: ApiResult,
    test_api_calendar: dict[str, Any],
    mock_events_list: ApiResult,
    setup_config_entry: MockConfigEntry,
) -> None:
    """Test loading an application credentials and a config entry."""
    assert await async_setup_component(hass, "application_credentials", {})
    await async_import_client_credential(
        hass, DOMAIN, ClientCredential("client-id", "client-secret"),
        "device_auth")

    mock_calendars_list({"items": [test_api_calendar]})
    mock_events_list({})
    assert await component_setup()

    state = hass.states.get(TEST_API_ENTITY)
    assert state
    assert state.name == TEST_API_ENTITY_NAME
    assert state.state == STATE_OFF

    # No yaml config loaded that overwrites the entity name
    assert not hass.states.get(TEST_YAML_ENTITY)
Ejemplo n.º 2
0
async def mock_impl(hass):
    """Mock implementation."""
    await async_setup_component(hass, DOMAIN, {})
    await hass.async_block_till_done()

    await async_import_client_credential(
        hass, DOMAIN, ClientCredential(CLIENT_ID, CLIENT_SECRET), "cred")
Ejemplo n.º 3
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Netatmo component."""
    hass.data[DOMAIN] = {
        DATA_PERSONS: {},
        DATA_DEVICE_IDS: {},
        DATA_SCHEDULES: {},
        DATA_HOMES: {},
        DATA_EVENTS: {},
        DATA_CAMERAS: {},
    }

    if DOMAIN not in config:
        return True

    await async_import_client_credential(
        hass,
        DOMAIN,
        ClientCredential(
            config[DOMAIN][CONF_CLIENT_ID],
            config[DOMAIN][CONF_CLIENT_SECRET],
        ),
    )
    _LOGGER.warning(
        "Configuration of Netatmo integration in YAML is deprecated and "
        "will be removed in a future release; Your existing configuration "
        "(including OAuth Application Credentials) have been imported into "
        "the UI automatically and can be safely removed from your "
        "configuration.yaml file"
    )

    return True
Ejemplo n.º 4
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Honeywell Lyric component."""
    hass.data[DOMAIN] = {}

    if DOMAIN not in config:
        return True

    await async_import_client_credential(
        hass,
        DOMAIN,
        ClientCredential(
            config[DOMAIN][CONF_CLIENT_ID],
            config[DOMAIN][CONF_CLIENT_SECRET],
        ),
    )

    _LOGGER.warning(
        "Configuration of Honeywell Lyric integration in YAML is deprecated "
        "and will be removed in a future release; Your existing OAuth "
        "Application Credentials have been imported into the UI "
        "automatically and can be safely removed from your "
        "configuration.yaml file"
    )

    return True
Ejemplo n.º 5
0
async def setup_credentials(hass: HomeAssistant) -> None:
    """Fixture to setup credentials."""
    assert await async_setup_component(hass, "application_credentials", {})
    await async_import_client_credential(
        hass,
        DOMAIN,
        ClientCredential(CLIENT_ID, CLIENT_SECRET),
    )
Ejemplo n.º 6
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Google component."""
    if DOMAIN not in config:
        return True

    conf = config.get(DOMAIN, {})
    hass.data[DOMAIN] = {DATA_CONFIG: conf}

    if CONF_CLIENT_ID in conf and CONF_CLIENT_SECRET in conf:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                conf[CONF_CLIENT_ID],
                conf[CONF_CLIENT_SECRET],
            ),
            DEVICE_AUTH_IMPL,
        )

    # Import credentials from the old token file into the new way as
    # a ConfigEntry managed by home assistant.
    storage = Storage(hass.config.path(TOKEN_FILE))
    creds = await hass.async_add_executor_job(storage.get)
    if creds and get_feature_access(hass).scope in creds.scopes:
        _LOGGER.debug("Importing configuration entry with credentials")
        hass.async_create_task(
            hass.config_entries.flow.async_init(
                DOMAIN,
                context={"source": config_entries.SOURCE_IMPORT},
                data={
                    "creds": creds,
                },
            ))
    async_create_issue(
        hass,
        DOMAIN,
        "deprecated_yaml",
        breaks_in_ha_version="2022.9.0",  # Warning first added in 2022.6.0
        is_fixable=False,
        severity=IssueSeverity.WARNING,
        translation_key="deprecated_yaml",
    )
    if conf.get(CONF_TRACK_NEW) is False:
        # The track_new as False would previously result in new entries
        # in google_calendars.yaml with track set to False which is
        # handled at calendar entity creation time.
        async_create_issue(
            hass,
            DOMAIN,
            "removed_track_new_yaml",
            breaks_in_ha_version="2022.6.0",
            is_fixable=False,
            severity=IssueSeverity.WARNING,
            translation_key="removed_track_new_yaml",
        )
    return True
Ejemplo n.º 7
0
async def component_setup(hass: HomeAssistant) -> None:
    """Fixture for setting up the integration."""
    result = await async_setup_component(hass, DOMAIN, {})
    await hass.async_block_till_done()

    await async_import_client_credential(hass, DOMAIN,
                                         ClientCredential("client", "secret"),
                                         "cred")

    assert result
Ejemplo n.º 8
0
async def test_full_flow_application_creds(
    hass: HomeAssistant,
    mock_code_flow: Mock,
    mock_exchange: Mock,
    config: dict[str, Any],
    component_setup: ComponentSetup,
) -> None:
    """Test successful creds setup."""
    assert await component_setup()

    await async_import_client_credential(
        hass, DOMAIN, ClientCredential(CLIENT_ID, CLIENT_SECRET),
        "imported-cred")

    result = await hass.config_entries.flow.async_init(
        DOMAIN, context={"source": config_entries.SOURCE_USER})
    assert result.get("type") == "progress"
    assert result.get("step_id") == "auth"
    assert "description_placeholders" in result
    assert "url" in result["description_placeholders"]

    with patch("homeassistant.components.google.async_setup_entry",
               return_value=True) as mock_setup:
        # Run one tick to invoke the credential exchange check
        now = utcnow()
        await fire_alarm(hass, now + CODE_CHECK_ALARM_TIMEDELTA)
        await hass.async_block_till_done()
        result = await hass.config_entries.flow.async_configure(
            flow_id=result["flow_id"])

    assert result.get("type") == "create_entry"
    assert result.get("title") == EMAIL_ADDRESS
    assert "data" in result
    data = result["data"]
    assert "token" in data
    assert 0 < data["token"]["expires_in"] < 8 * 86400
    assert (datetime.datetime.now().timestamp() <= data["token"]["expires_at"]
            <
            (datetime.datetime.now() + datetime.timedelta(days=8)).timestamp())
    data["token"].pop("expires_at")
    data["token"].pop("expires_in")
    assert data == {
        "auth_implementation": "imported-cred",
        "token": {
            "access_token": "ACCESS_TOKEN",
            "refresh_token": "REFRESH_TOKEN",
            "scope": "https://www.googleapis.com/auth/calendar",
            "token_type": "Bearer",
        },
    }
    assert result.get("options") == {"calendar_access": "read_write"}

    assert len(mock_setup.mock_calls) == 1
    entries = hass.config_entries.async_entries(DOMAIN)
    assert len(entries) == 1
Ejemplo n.º 9
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Google component."""
    if DOMAIN not in config:
        return True

    conf = config.get(DOMAIN, {})
    hass.data[DOMAIN] = {DATA_CONFIG: conf}

    if CONF_CLIENT_ID in conf and CONF_CLIENT_SECRET in conf:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                conf[CONF_CLIENT_ID],
                conf[CONF_CLIENT_SECRET],
            ),
            DEVICE_AUTH_IMPL,
        )

    # Import credentials from the old token file into the new way as
    # a ConfigEntry managed by home assistant.
    storage = Storage(hass.config.path(TOKEN_FILE))
    creds = await hass.async_add_executor_job(storage.get)
    if creds and get_feature_access(hass).scope in creds.scopes:
        _LOGGER.debug("Importing configuration entry with credentials")
        hass.async_create_task(
            hass.config_entries.flow.async_init(
                DOMAIN,
                context={"source": config_entries.SOURCE_IMPORT},
                data={
                    "creds": creds,
                },
            )
        )

    _LOGGER.warning(
        "Configuration of Google Calendar in YAML in configuration.yaml is "
        "is deprecated and will be removed in a future release; Your existing "
        "OAuth Application Credentials and access settings have been imported "
        "into the UI automatically and can be safely removed from your "
        "configuration.yaml file"
    )
    if conf.get(CONF_TRACK_NEW) is False:
        # The track_new as False would previously result in new entries
        # in google_calendars.yaml with track set to Fasle which is
        # handled at calendar entity creation time.
        _LOGGER.warning(
            "You must manually set the integration System Options in the "
            "UI to disable newly discovered entities going forward"
        )
    return True
Ejemplo n.º 10
0
async def test_full_flow(
    hass: HomeAssistant,
    hass_client_no_auth,
    aioclient_mock,
    current_request_with_host,
) -> None:
    """Check full flow."""
    await async_setup_component(hass, DOMAIN, {})
    await hass.async_block_till_done()

    await async_import_client_credential(
        hass, DOMAIN, ClientCredential(CLIENT_ID, CLIENT_SECRET), "cred")

    result = await hass.config_entries.flow.async_init(
        "senz", context={"source": config_entries.SOURCE_USER})
    state = config_entry_oauth2_flow._encode_jwt(
        hass,
        {
            "flow_id": result["flow_id"],
            "redirect_uri": "https://example.com/auth/external/callback",
        },
    )

    assert result["url"] == (
        f"{AUTHORIZATION_ENDPOINT}?response_type=code&client_id={CLIENT_ID}"
        "&redirect_uri=https://example.com/auth/external/callback"
        f"&state={state}&scope=restapi+offline_access")

    client = await hass_client_no_auth()
    resp = await client.get(f"/auth/external/callback?code=abcd&state={state}")
    assert resp.status == 200
    assert resp.headers["content-type"] == "text/html; charset=utf-8"

    aioclient_mock.post(
        TOKEN_ENDPOINT,
        json={
            "refresh_token": "mock-refresh-token",
            "access_token": "mock-access-token",
            "type": "Bearer",
            "expires_in": 60,
        },
    )

    with patch("homeassistant.components.senz.async_setup_entry",
               return_value=True) as mock_setup:
        await hass.config_entries.flow.async_configure(result["flow_id"])

    assert len(hass.config_entries.async_entries(DOMAIN)) == 1
    assert len(mock_setup.mock_calls) == 1
Ejemplo n.º 11
0
async def test_multiple_config_entries(
    hass: HomeAssistant,
    mock_code_flow: Mock,
    mock_exchange: Mock,
    config: dict[str, Any],
    config_entry: MockConfigEntry,
    component_setup: ComponentSetup,
) -> None:
    """Test that multiple config entries can be set at once."""
    assert await component_setup()
    await async_import_client_credential(
        hass, DOMAIN, ClientCredential(CLIENT_ID, CLIENT_SECRET),
        "imported-cred")

    # Load a config entry
    config_entry.add_to_hass(hass)
    with patch("homeassistant.components.google.async_setup_entry",
               return_value=True) as mock_setup:
        await hass.config_entries.async_setup(config_entry.entry_id)
        await hass.async_block_till_done()
        assert len(mock_setup.mock_calls) == 1

    entries = hass.config_entries.async_entries(DOMAIN)
    assert len(entries) == 1

    # Start a new config flow
    result = await hass.config_entries.flow.async_init(
        DOMAIN, context={"source": config_entries.SOURCE_USER})
    assert result.get("type") == "progress"
    assert result.get("step_id") == "auth"
    assert "description_placeholders" in result
    assert "url" in result["description_placeholders"]

    with patch("homeassistant.components.google.async_setup_entry",
               return_value=True) as mock_setup:
        # Run one tick to invoke the credential exchange check
        now = utcnow()
        await fire_alarm(hass, now + CODE_CHECK_ALARM_TIMEDELTA)
        await hass.async_block_till_done()
        result = await hass.config_entries.flow.async_configure(
            flow_id=result["flow_id"])
    assert result.get("type") == "create_entry"
    assert result.get("title") == "*****@*****.**"
    assert len(mock_setup.mock_calls) == 1

    entries = hass.config_entries.async_entries(DOMAIN)
    assert len(entries) == 2
Ejemplo n.º 12
0
async def async_import_config(hass: HomeAssistant, entry: ConfigEntry) -> None:
    """Attempt to import configuration.yaml settings."""
    config = hass.data[DOMAIN][DATA_NEST_CONFIG]
    new_data = {
        CONF_PROJECT_ID: config[CONF_PROJECT_ID],
        **entry.data,
    }
    if CONF_SUBSCRIBER_ID not in entry.data:
        if CONF_SUBSCRIBER_ID not in config:
            raise ValueError("Configuration option 'subscriber_id' missing")
        new_data.update(
            {
                CONF_SUBSCRIBER_ID: config[CONF_SUBSCRIBER_ID],
                CONF_SUBSCRIBER_ID_IMPORTED: True,  # Don't delete user managed subscriber
            }
        )
    hass.config_entries.async_update_entry(
        entry, data=new_data, unique_id=new_data[CONF_PROJECT_ID]
    )

    if entry.data["auth_implementation"] == INSTALLED_AUTH_DOMAIN:
        # App Auth credentials have been deprecated and must be re-created
        # by the user in the config flow
        raise ConfigEntryAuthFailed(
            "Google has deprecated App Auth credentials, and the integration "
            "must be reconfigured in the UI to restore access to Nest Devices."
        )

    if entry.data["auth_implementation"] == WEB_AUTH_DOMAIN:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                config[CONF_CLIENT_ID],
                config[CONF_CLIENT_SECRET],
            ),
            WEB_AUTH_DOMAIN,
        )

    _LOGGER.warning(
        "Configuration of Nest integration in YAML is deprecated and "
        "will be removed in a future release; Your existing configuration "
        "(including OAuth Application Credentials) has been imported into "
        "the UI automatically and can be safely removed from your "
        "configuration.yaml file"
    )
Ejemplo n.º 13
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Google component."""
    if DOMAIN not in config:
        return True

    conf = config.get(DOMAIN, {})
    hass.data[DOMAIN] = {DATA_CONFIG: conf}

    if CONF_CLIENT_ID in conf and CONF_CLIENT_SECRET in conf:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                conf[CONF_CLIENT_ID],
                conf[CONF_CLIENT_SECRET],
            ),
            DEVICE_AUTH_IMPL,
        )

    # Import credentials from the old token file into the new way as
    # a ConfigEntry managed by home assistant.
    storage = Storage(hass.config.path(TOKEN_FILE))
    creds = await hass.async_add_executor_job(storage.get)
    if creds and get_feature_access(hass).scope in creds.scopes:
        _LOGGER.debug("Importing configuration entry with credentials")
        hass.async_create_task(
            hass.config_entries.flow.async_init(
                DOMAIN,
                context={"source": config_entries.SOURCE_IMPORT},
                data={
                    "creds": creds,
                },
            )
        )

    _LOGGER.warning(
        "Configuration of Google Calendar in YAML in configuration.yaml is "
        "is deprecated and will be removed in a future release; Your existing "
        "OAuth Application Credentials and other settings have been imported "
        "into the UI automatically and can be safely removed from your "
        "configuration.yaml file"
    )

    return True
Ejemplo n.º 14
0
    """Set up the Withings component."""
    if not (conf := config.get(DOMAIN)):
        # Apply the defaults.
        conf = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
        hass.data[DOMAIN] = {const.CONFIG: conf}
        return True

    hass.data[DOMAIN] = {const.CONFIG: conf}

    # Setup the oauth2 config flow.
    if CONF_CLIENT_ID in conf:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                conf[CONF_CLIENT_ID],
                conf[CONF_CLIENT_SECRET],
            ),
        )
        _LOGGER.warning(
            "Configuration of Withings integration OAuth2 credentials in YAML "
            "is deprecated and will be removed in a future release; Your "
            "existing OAuth Application Credentials have been imported into "
            "the UI automatically and can be safely removed from your "
            "configuration.yaml file")

    return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Withings from a config entry."""
    config_updates = {}
Ejemplo n.º 15
0
        "subscriber_id": SUBSCRIBER_ID,
    },
)
TEST_CONFIGFLOW_HYBRID = NestTestConfig(TEST_CONFIG_HYBRID.config)

# Exercises mode where all configuration is from the config flow
TEST_CONFIG_APP_CREDS = NestTestConfig(
    config_entry_data={
        "sdm": {},
        "token": create_token_entry(),
        "project_id": PROJECT_ID,
        "cloud_project_id": CLOUD_PROJECT_ID,
        "subscriber_id": SUBSCRIBER_ID,
    },
    auth_implementation="imported-cred",
    credential=ClientCredential(CLIENT_ID, CLIENT_SECRET),
)
TEST_CONFIGFLOW_APP_CREDS = NestTestConfig(
    config=TEST_CONFIG_APP_CREDS.config,
    auth_implementation="imported-cred",
    credential=ClientCredential(CLIENT_ID, CLIENT_SECRET),
)

TEST_CONFIG_LEGACY = NestTestConfig(
    config={
        "nest": {
            "client_id": "some-client-id",
            "client_secret": "some-client-secret",
        },
    },
    config_entry_data={
Ejemplo n.º 16
0
    CONF_AUTH_DOMAIN,
    DOMAIN,
    AuthorizationServer,
    ClientCredential,
    async_import_client_credential,
)
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_entry_oauth2_flow
from homeassistant.setup import async_setup_component

from tests.common import mock_platform

CLIENT_ID = "some-client-id"
CLIENT_SECRET = "some-client-secret"
DEVELOPER_CREDENTIAL = ClientCredential(CLIENT_ID, CLIENT_SECRET)
ID = "fake_integration_some_client_id"
AUTHORIZE_URL = "https://example.com/auth"
TOKEN_URL = "https://example.com/oauth2/v4/token"
REFRESH_TOKEN = "mock-refresh-token"
ACCESS_TOKEN = "mock-access-token"

TEST_DOMAIN = "fake_integration"


@pytest.fixture
async def authorization_server() -> AuthorizationServer:
    """Fixture AuthorizationServer for mock application_credentials integration."""
    return AuthorizationServer(AUTHORIZE_URL, TOKEN_URL)

Ejemplo n.º 17
0
)
from homeassistant.const import (
    CONF_CLIENT_ID,
    CONF_CLIENT_SECRET,
    CONF_DOMAIN,
    CONF_NAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_entry_oauth2_flow
from homeassistant.setup import async_setup_component

from tests.common import mock_platform

CLIENT_ID = "some-client-id"
CLIENT_SECRET = "some-client-secret"
DEVELOPER_CREDENTIAL = ClientCredential(CLIENT_ID, CLIENT_SECRET)
NAMED_CREDENTIAL = ClientCredential(CLIENT_ID, CLIENT_SECRET, "Name")
ID = "fake_integration_some_client_id"
AUTHORIZE_URL = "https://example.com/auth"
TOKEN_URL = "https://example.com/oauth2/v4/token"
REFRESH_TOKEN = "mock-refresh-token"
ACCESS_TOKEN = "mock-access-token"
NAME = "Name"

TEST_DOMAIN = "fake_integration"


@pytest.fixture
async def authorization_server() -> AuthorizationServer:
    """Fixture AuthorizationServer for mock application_credentials integration."""
    return AuthorizationServer(AUTHORIZE_URL, TOKEN_URL)
Ejemplo n.º 18
0
async def setup_credentials(hass: HomeAssistant) -> None:
    """Fixture to setup credentials."""
    assert await async_setup_component(hass, "application_credentials", {})
    await async_import_client_credential(hass, DOMAIN,
                                         ClientCredential("client", "secret"),
                                         "credentials")
Ejemplo n.º 19
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up Home Connect component."""
    hass.data[DOMAIN] = {}

    if DOMAIN in config:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                config[DOMAIN][CONF_CLIENT_ID],
                config[DOMAIN][CONF_CLIENT_SECRET],
            ),
        )
        _LOGGER.warning(
            "Configuration of Home Connect integration in YAML is deprecated and "
            "will be removed in a future release; Your existing OAuth "
            "Application Credentials have been imported into the UI "
            "automatically and can be safely removed from your "
            "configuration.yaml file")

    async def _async_service_program(call, method):
        """Execute calls to services taking a program."""
        program = call.data[ATTR_PROGRAM]
        device_id = call.data[ATTR_DEVICE_ID]

        options = []

        option_key = call.data.get(ATTR_KEY)
        if option_key is not None:
            option = {ATTR_KEY: option_key, ATTR_VALUE: call.data[ATTR_VALUE]}

            option_unit = call.data.get(ATTR_UNIT)
            if option_unit is not None:
                option[ATTR_UNIT] = option_unit

            options.append(option)

        appliance = _get_appliance_by_device_id(hass, device_id)
        await hass.async_add_executor_job(getattr(appliance, method), program,
                                          options)

    async def _async_service_command(call, command):
        """Execute calls to services executing a command."""
        device_id = call.data[ATTR_DEVICE_ID]

        appliance = _get_appliance_by_device_id(hass, device_id)
        await hass.async_add_executor_job(appliance.execute_command, command)

    async def _async_service_key_value(call, method):
        """Execute calls to services taking a key and value."""
        key = call.data[ATTR_KEY]
        value = call.data[ATTR_VALUE]
        unit = call.data.get(ATTR_UNIT)
        device_id = call.data[ATTR_DEVICE_ID]

        appliance = _get_appliance_by_device_id(hass, device_id)
        if unit is not None:
            await hass.async_add_executor_job(
                getattr(appliance, method),
                key,
                value,
                unit,
            )
        else:
            await hass.async_add_executor_job(
                getattr(appliance, method),
                key,
                value,
            )

    async def async_service_option_active(call):
        """Service for setting an option for an active program."""
        await _async_service_key_value(call, "set_options_active_program")

    async def async_service_option_selected(call):
        """Service for setting an option for a selected program."""
        await _async_service_key_value(call, "set_options_selected_program")

    async def async_service_setting(call):
        """Service for changing a setting."""
        await _async_service_key_value(call, "set_setting")

    async def async_service_pause_program(call):
        """Service for pausing a program."""
        await _async_service_command(call, BSH_PAUSE)

    async def async_service_resume_program(call):
        """Service for resuming a paused program."""
        await _async_service_command(call, BSH_RESUME)

    async def async_service_select_program(call):
        """Service for selecting a program."""
        await _async_service_program(call, "select_program")

    async def async_service_start_program(call):
        """Service for starting a program."""
        await _async_service_program(call, "start_program")

    hass.services.async_register(
        DOMAIN,
        SERVICE_OPTION_ACTIVE,
        async_service_option_active,
        schema=SERVICE_OPTION_SCHEMA,
    )
    hass.services.async_register(
        DOMAIN,
        SERVICE_OPTION_SELECTED,
        async_service_option_selected,
        schema=SERVICE_OPTION_SCHEMA,
    )
    hass.services.async_register(DOMAIN,
                                 SERVICE_SETTING,
                                 async_service_setting,
                                 schema=SERVICE_SETTING_SCHEMA)
    hass.services.async_register(
        DOMAIN,
        SERVICE_PAUSE_PROGRAM,
        async_service_pause_program,
        schema=SERVICE_COMMAND_SCHEMA,
    )
    hass.services.async_register(
        DOMAIN,
        SERVICE_RESUME_PROGRAM,
        async_service_resume_program,
        schema=SERVICE_COMMAND_SCHEMA,
    )
    hass.services.async_register(
        DOMAIN,
        SERVICE_SELECT_PROGRAM,
        async_service_select_program,
        schema=SERVICE_PROGRAM_SCHEMA,
    )
    hass.services.async_register(
        DOMAIN,
        SERVICE_START_PROGRAM,
        async_service_start_program,
        schema=SERVICE_PROGRAM_SCHEMA,
    )

    return True
Ejemplo n.º 20
0
async def async_import_config(hass: HomeAssistant, entry: ConfigEntry) -> None:
    """Attempt to import configuration.yaml settings."""
    config = hass.data[DOMAIN][DATA_NEST_CONFIG]
    new_data = {
        CONF_PROJECT_ID: config[CONF_PROJECT_ID],
        **entry.data,
    }
    if CONF_SUBSCRIBER_ID not in entry.data:
        if CONF_SUBSCRIBER_ID not in config:
            raise ValueError("Configuration option 'subscriber_id' missing")
        new_data.update({
            CONF_SUBSCRIBER_ID: config[CONF_SUBSCRIBER_ID],
            CONF_SUBSCRIBER_ID_IMPORTED:
            True,  # Don't delete user managed subscriber
        })
    hass.config_entries.async_update_entry(entry,
                                           data=new_data,
                                           unique_id=new_data[CONF_PROJECT_ID])

    if entry.data["auth_implementation"] == INSTALLED_AUTH_DOMAIN:
        # App Auth credentials have been deprecated and must be re-created
        # by the user in the config flow
        async_create_issue(
            hass,
            DOMAIN,
            "removed_app_auth",
            is_fixable=False,
            severity=IssueSeverity.ERROR,
            translation_key="removed_app_auth",
            translation_placeholders={
                "more_info_url":
                "https://www.home-assistant.io/more-info/nest-auth-deprecation",
                "documentation_url":
                "https://www.home-assistant.io/integrations/nest/",
            },
        )
        raise ConfigEntryAuthFailed(
            "Google has deprecated App Auth credentials, and the integration "
            "must be reconfigured in the UI to restore access to Nest Devices."
        )

    if entry.data["auth_implementation"] == WEB_AUTH_DOMAIN:
        await async_import_client_credential(
            hass,
            DOMAIN,
            ClientCredential(
                config[CONF_CLIENT_ID],
                config[CONF_CLIENT_SECRET],
            ),
            WEB_AUTH_DOMAIN,
        )

    async_create_issue(
        hass,
        DOMAIN,
        "deprecated_yaml",
        breaks_in_ha_version="2022.10.0",
        is_fixable=False,
        severity=IssueSeverity.WARNING,
        translation_key="deprecated_yaml",
    )