async def update_entity():
        """Get entity from registry."""
        registry = await async_get_registry(hass)

        if msg['entity_id'] not in registry.entities:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], websocket_api.ERR_NOT_FOUND, 'Entity not found'))
            return

        changes = {}

        if 'name' in msg:
            changes['name'] = msg['name']

        if 'new_entity_id' in msg:
            changes['new_entity_id'] = msg['new_entity_id']

        try:
            if changes:
                entry = registry.async_update_entity(
                    msg['entity_id'], **changes)
        except ValueError as err:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'invalid_info', str(err)
            ))
        else:
            connection.send_message_outside(websocket_api.result_message(
                msg['id'], _entry_dict(entry)
            ))
    async def create_creds():
        """Create credentials."""
        provider = _get_provider(hass)
        await provider.async_initialize()

        user = await hass.auth.async_get_user(msg['user_id'])

        if user is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'not_found', 'User not found'))
            return

        if user.system_generated:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'system_generated',
                'Cannot add credentials to a system generated user.'))
            return

        try:
            await hass.async_add_executor_job(
                provider.data.add_auth, msg['username'], msg['password'])
        except auth_ha.InvalidUser:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'username_exists', 'Username already exists'))
            return

        credentials = await provider.async_get_or_create_credentials({
            'username': msg['username']
        })
        await hass.auth.async_link_user(user, credentials)

        await provider.data.async_save()
        connection.to_write.put_nowait(websocket_api.result_message(msg['id']))
Exemple #3
0
async def websocket_handle_thumbnail(hass, connection, msg):
    """Handle get media player cover command.

    Async friendly.
    """
    component = hass.data[DOMAIN]
    player = component.get_entity(msg['entity_id'])

    if player is None:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'entity_not_found', 'Entity not found'))
        return

    data, content_type = await player.async_get_media_image()

    if data is None:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'thumbnail_fetch_failed',
            'Failed to fetch thumbnail'))
        return

    connection.send_message(websocket_api.result_message(
        msg['id'], {
            'content_type': content_type,
            'content': base64.b64encode(data).decode('utf-8')
        }))
Exemple #4
0
async def websocket_subscription(hass, connection, msg):
    """Handle request for account info."""
    cloud = hass.data[DOMAIN]

    if not cloud.is_logged_in:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'not_logged_in',
            'You need to be logged in to the cloud.'))
        return

    with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
        response = await cloud.fetch_subscription_info()

    if response.status != 200:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'request_failed', 'Failed to request subscription'))

    data = await response.json()

    # Check if a user is subscribed but local info is outdated
    # In that case, let's refresh and reconnect
    if data.get('provider') and cloud.iot.state != STATE_CONNECTED:
        _LOGGER.debug(
            "Found disconnected account with valid subscriotion, connecting")
        await hass.async_add_executor_job(
            auth_api.renew_access_token, cloud)

        # Cancel reconnect in progress
        if cloud.iot.state != STATE_DISCONNECTED:
            await cloud.iot.disconnect()

        hass.async_create_task(cloud.iot.connect())

    connection.send_message(websocket_api.result_message(msg['id'], data))
async def websocket_update_entity(hass, connection, msg):
    """Handle get camera thumbnail websocket command.

    Async friendly.
    """
    registry = await async_get_registry(hass)

    if msg['entity_id'] not in registry.entities:
        connection.send_message(websocket_api.error_message(
            msg['id'], ERR_NOT_FOUND, 'Entity not found'))
        return

    changes = {}

    if 'name' in msg:
        changes['name'] = msg['name']

    if 'new_entity_id' in msg:
        changes['new_entity_id'] = msg['new_entity_id']

    try:
        if changes:
            entry = registry.async_update_entity(
                msg['entity_id'], **changes)
    except ValueError as err:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'invalid_info', str(err)
        ))
    else:
        connection.send_message(websocket_api.result_message(
            msg['id'], _entry_dict(entry)
        ))
Exemple #6
0
 async def with_error_handling(hass, connection, msg):
     """Handle aiohttp errors."""
     try:
         await handler(hass, connection, msg)
     except asyncio.TimeoutError:
         connection.send_message(websocket_api.error_message(
             msg['id'], 'timeout', 'Command timed out.'))
     except aiohttp.ClientError:
         connection.send_message(websocket_api.error_message(
             msg['id'], 'unknown', 'Error making request.'))
    async def async_setup_flow(msg):
        """Return a setup flow for mfa auth module."""
        flow_manager = hass.data[DATA_SETUP_FLOW_MGR]

        flow_id = msg.get('flow_id')
        if flow_id is not None:
            result = await flow_manager.async_configure(
                flow_id, msg.get('user_input'))
            connection.send_message_outside(
                websocket_api.result_message(
                    msg['id'], _prepare_result_json(result)))
            return

        mfa_module_id = msg.get('mfa_module_id')
        mfa_module = hass.auth.get_auth_mfa_module(mfa_module_id)
        if mfa_module is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'no_module',
                'MFA module {} is not found'.format(mfa_module_id)))
            return

        result = await flow_manager.async_init(
            mfa_module_id, data={'user_id': connection.user.id})

        connection.send_message_outside(
            websocket_api.result_message(
                msg['id'], _prepare_result_json(result)))
    async def delete_creds():
        """Delete user credentials."""
        provider = _get_provider(hass)
        await provider.async_initialize()

        credentials = await provider.async_get_or_create_credentials({
            'username': msg['username']
        })

        # if not new, an existing credential exists.
        # Removing the credential will also remove the auth.
        if not credentials.is_new:
            await hass.auth.async_remove_credentials(credentials)

            connection.to_write.put_nowait(
                websocket_api.result_message(msg['id']))
            return

        try:
            provider.data.async_remove_auth(msg['username'])
            await provider.data.async_save()
        except auth_ha.InvalidUser:
            connection.to_write.put_nowait(websocket_api.error_message(
                msg['id'], 'auth_not_found', 'Given username was not found.'))
            return

        connection.to_write.put_nowait(
            websocket_api.result_message(msg['id']))
Exemple #9
0
async def websocket_delete(hass, connection, msg):
    """Delete a user."""
    if msg['user_id'] == connection.user.id:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'no_delete_self',
            'Unable to delete your own account'))
        return

    user = await hass.auth.async_get_user(msg['user_id'])

    if not user:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'not_found', 'User not found'))
        return

    await hass.auth.async_remove_user(user)

    connection.send_message(
        websocket_api.result_message(msg['id']))
Exemple #10
0
    async def delete_user():
        """Delete user."""
        if msg['user_id'] == connection.request.get('hass_user').id:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'no_delete_self',
                'Unable to delete your own account'))
            return

        user = await hass.auth.async_get_user(msg['user_id'])

        if not user:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'not_found', 'User not found'))
            return

        await hass.auth.async_remove_user(user)

        connection.send_message_outside(
            websocket_api.result_message(msg['id']))
Exemple #11
0
async def websocket_subscription(hass, connection, msg):
    """Handle request for account info."""
    cloud = hass.data[DOMAIN]

    if not cloud.is_logged_in:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'not_logged_in',
            'You need to be logged in to the cloud.'))
        return

    with async_timeout.timeout(REQUEST_TIMEOUT, loop=hass.loop):
        response = await cloud.fetch_subscription_info()

    if response.status == 200:
        connection.send_message(websocket_api.result_message(
            msg['id'], await response.json()))
    else:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'request_failed', 'Failed to request subscription'))
Exemple #12
0
    def with_cloud_auth(hass, connection, msg):
        """Require to be logged into the cloud."""
        cloud = hass.data[DOMAIN]
        if not cloud.is_logged_in:
            connection.send_message(websocket_api.error_message(
                msg['id'], 'not_logged_in',
                'You need to be logged in to the cloud.'))
            return

        handler(hass, connection, msg)
async def websocket_delete_registration(hass: HomeAssistantType,
                                        connection: ActiveConnection,
                                        msg: dict) -> None:
    """Delete the registration for the given webhook_id."""
    user = connection.user

    webhook_id = msg.get(CONF_WEBHOOK_ID)
    if webhook_id is None:
        connection.send_error(msg['id'], ERR_INVALID_FORMAT,
                              "Webhook ID not provided")
        return

    config_entry = hass.data[DOMAIN][DATA_CONFIG_ENTRIES][webhook_id]

    registration = config_entry.data

    if registration is None:
        connection.send_error(msg['id'], ERR_NOT_FOUND,
                              "Webhook ID not found in storage")
        return

    if registration[CONF_USER_ID] != user.id and not user.is_admin:
        return error_message(
            msg['id'], ERR_UNAUTHORIZED, 'User is not registration owner')

    await hass.config_entries.async_remove(config_entry.entry_id)

    hass.data[DOMAIN][DATA_DELETED_IDS].append(webhook_id)

    store = hass.data[DOMAIN][DATA_STORE]

    try:
        await store.async_save(savable_state(hass))
    except HomeAssistantError:
        return error_message(
            msg['id'], 'internal_error', 'Error deleting registration')

    if (CONF_CLOUDHOOK_URL in registration and
            "cloud" in hass.config.components):
        await async_delete_cloudhook(hass, webhook_id)

    connection.send_message(result_message(msg['id'], 'ok'))
Exemple #14
0
    async def async_delete_refresh_token(user, refresh_token_id):
        """Delete a refresh token."""
        refresh_token = connection.user.refresh_tokens.get(refresh_token_id)

        if refresh_token is None:
            return websocket_api.error_message(
                msg['id'], 'invalid_token_id', 'Received invalid token')

        await hass.auth.async_remove_refresh_token(refresh_token)

        connection.send_message(
            websocket_api.result_message(msg['id'], {}))
    async def retrieve_entity():
        """Get entity from registry."""
        registry = await async_get_registry(hass)
        entry = registry.entities.get(msg['entity_id'])

        if entry is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], websocket_api.ERR_NOT_FOUND, 'Entity not found'))
            return

        connection.send_message_outside(websocket_api.result_message(
            msg['id'], _entry_dict(entry)
        ))
async def websocket_delete_refresh_token(
        hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
    """Handle a delete refresh token request."""
    refresh_token = connection.user.refresh_tokens.get(msg['refresh_token_id'])

    if refresh_token is None:
        return websocket_api.error_message(
            msg['id'], 'invalid_token_id', 'Received invalid token')

    await hass.auth.async_remove_refresh_token(refresh_token)

    connection.send_message(
        websocket_api.result_message(msg['id'], {}))
async def websocket_create_area(hass, connection, msg):
    """Create area command."""
    registry = await async_get_registry(hass)
    try:
        entry = registry.async_create(msg['name'])
    except ValueError as err:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'invalid_info', str(err)
        ))
    else:
        connection.send_message(websocket_api.result_message(
            msg['id'], _entry_dict(entry)
        ))
Exemple #18
0
 async def send_camera_still():
     """Send a camera still."""
     try:
         image = await async_get_image(hass, msg['entity_id'])
         connection.send_message_outside(websocket_api.result_message(
             msg['id'], {
                 'content_type': image.content_type,
                 'content': base64.b64encode(image.content).decode('utf-8')
             }
         ))
     except HomeAssistantError:
         connection.send_message_outside(websocket_api.error_message(
             msg['id'], 'image_fetch_failed', 'Unable to fetch image'))
Exemple #19
0
def websocket_current_user(hass, connection, msg):
    """Return the current user."""
    user = connection.request.get('hass_user')

    if user is None:
        connection.to_write.put_nowait(websocket_api.error_message(
            msg['id'], 'no_user', 'Not authenticated as a user'))
        return

    connection.to_write.put_nowait(websocket_api.result_message(msg['id'], {
        'id': user.id,
        'name': user.name,
        'is_owner': user.is_owner,
    }))
    async def update_entity():
        """Get entity from registry."""
        registry = await async_get_registry(hass)

        if msg['entity_id'] not in registry.entities:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], websocket_api.ERR_NOT_FOUND, 'Entity not found'))
            return

        entry = registry.async_update_entity(
            msg['entity_id'], name=msg['name'])
        connection.send_message_outside(websocket_api.result_message(
            msg['id'], _entry_dict(entry)
        ))
async def websocket_remove_entity(hass, connection, msg):
    """Handle remove entity websocket command.

    Async friendly.
    """
    registry = await async_get_registry(hass)

    if msg['entity_id'] not in registry.entities:
        connection.send_message(websocket_api.error_message(
            msg['id'], ERR_NOT_FOUND, 'Entity not found'))
        return

    registry.async_remove(msg['entity_id'])
    connection.send_message(websocket_api.result_message(msg['id']))
async def websocket_delete_area(hass, connection, msg):
    """Delete area command."""
    registry = await async_get_registry(hass)

    try:
        await registry.async_delete(msg['area_id'])
    except KeyError:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'invalid_info', "Area ID doesn't exist"
        ))
    else:
        connection.send_message(websocket_api.result_message(
            msg['id'], 'success'
        ))
Exemple #23
0
async def websocket_handle_update(hass, connection, msg):
    """Handle update shopping_list item."""
    msg_id = msg.pop('id')
    item_id = msg.pop('item_id')
    msg.pop('type')
    data = msg

    try:
        item = hass.data[DOMAIN].async_update(item_id, data)
        hass.bus.async_fire(EVENT)
        connection.send_message(websocket_api.result_message(
            msg_id, item))
    except KeyError:
        connection.send_message(websocket_api.error_message(
            msg_id, 'item_not_found', 'Item not found'))
    async def change_password():
        """Change user password."""
        user = connection.request.get('hass_user')
        if user is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'user_not_found', 'User not found'))
            return

        provider = _get_provider(hass)
        await provider.async_initialize()

        username = None
        for credential in user.credentials:
            if credential.auth_provider_type == provider.type:
                username = credential.data['username']
                break

        if username is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'credentials_not_found', 'Credentials not found'))
            return

        try:
            await provider.async_validate_login(
                username, msg['current_password'])
        except auth_ha.InvalidAuth:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'invalid_password', 'Invalid password'))
            return

        await hass.async_add_executor_job(
            provider.data.change_password, username, msg['new_password'])
        await provider.data.async_save()

        connection.send_message_outside(
            websocket_api.result_message(msg['id']))
Exemple #25
0
async def websocket_update(hass, connection, msg):
    """Update a user."""
    user = await hass.auth.async_get_user(msg.pop('user_id'))

    if not user:
        connection.send_message(websocket_api.error_message(
            msg['id'], websocket_api.const.ERR_NOT_FOUND, 'User not found'))
        return

    if user.system_generated:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'cannot_modify_system_generated',
            'Unable to update system generated users.'))
        return

    msg.pop('type')
    msg_id = msg.pop('id')

    await hass.auth.async_update_user(user, **msg)

    connection.send_message(
        websocket_api.result_message(msg_id, {
            'user': _user_info(user),
        }))
    async def send_image():
        """Send image."""
        data, content_type = await player.async_get_media_image()

        if data is None:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'thumbnail_fetch_failed',
                'Failed to fetch thumbnail'))
            return

        connection.send_message_outside(websocket_api.result_message(
            msg['id'], {
                'content_type': content_type,
                'content': base64.b64encode(data).decode('utf-8')
            }))
Exemple #27
0
    async def send_with_error_handling(hass, connection, msg):
        error = None
        try:
            result = await func(hass, connection, msg)
            message = websocket_api.result_message(
                msg['id'], result
            )
        except ConfigNotFound:
            error = 'config_not_found', 'No config found.'
        except HomeAssistantError as err:
            error = 'error', str(err)

        if error is not None:
            message = websocket_api.error_message(msg['id'], *error)

        connection.send_message(message)
async def websocket_get_entity(hass, connection, msg):
    """Handle get entity registry entry command.

    Async friendly.
    """
    registry = await async_get_registry(hass)
    entry = registry.entities.get(msg['entity_id'])

    if entry is None:
        connection.send_message(websocket_api.error_message(
            msg['id'], ERR_NOT_FOUND, 'Entity not found'))
        return

    connection.send_message(websocket_api.result_message(
        msg['id'], _entry_dict(entry)
    ))
Exemple #29
0
async def websocket_camera_thumbnail(hass, connection, msg):
    """Handle get camera thumbnail websocket command.

    Async friendly.
    """
    try:
        image = await async_get_image(hass, msg['entity_id'])
        connection.send_message(websocket_api.result_message(
            msg['id'], {
                'content_type': image.content_type,
                'content': base64.b64encode(image.content).decode('utf-8')
            }
        ))
    except HomeAssistantError:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'image_fetch_failed', 'Unable to fetch image'))
    async def async_depose(msg):
        """Remove user from mfa auth module."""
        mfa_module_id = msg['mfa_module_id']
        try:
            await hass.auth.async_disable_user_mfa(
                connection.user, msg['mfa_module_id'])
        except ValueError as err:
            connection.send_message_outside(websocket_api.error_message(
                msg['id'], 'disable_failed',
                'Cannot disable MFA Module {}: {}'.format(
                    mfa_module_id, err)))
            return

        connection.send_message_outside(
            websocket_api.result_message(
                msg['id'], 'done'))
Exemple #31
0
async def websocket_video_data(hass, connection, msg):
    camera = get_entity_from_domain(hass, DOMAIN, msg['entity_id'])
    _LOGGER.debug('video_data for ' + str(camera.unique_id))

    try:
        video = await camera.async_get_video()
        connection.send_message(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': 'video/mp4',
                    'content': base64.b64encode(video).decode('utf-8')
                }))

    except HomeAssistantError:
        connection.send_message(
            websocket_api.error_message(msg['id'], 'video_fetch_failed',
                                        'Unable to fetch video'))
Exemple #32
0
async def websocket_get_entity(hass, connection, msg):
    """Handle get entity registry entry command.

    Async friendly.
    """
    registry = await async_get_registry(hass)
    entry = registry.entities.get(msg["entity_id"])

    if entry is None:
        connection.send_message(
            websocket_api.error_message(msg["id"], ERR_NOT_FOUND, "Entity not found")
        )
        return

    connection.send_message(
        websocket_api.result_message(msg["id"], _entry_ext_dict(entry))
    )
Exemple #33
0
async def websocket_snapshot_image(hass, connection, msg):
    camera = _get_camera_from_entity_id(hass, msg['entity_id'])
    _LOGGER.debug('snapshot_image for ' + str(camera.unique_id))

    try:
        image = await camera.async_get_snapshot()
        connection.send_message(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': camera.content_type,
                    'content': base64.b64encode(image).decode('utf-8')
                }))

    except HomeAssistantError:
        connection.send_message(
            websocket_api.error_message(msg['id'], 'image_fetch_failed',
                                        'Unable to fetch image'))
Exemple #34
0
    async def async_depose(msg):
        """Remove user from mfa auth module."""
        mfa_module_id = msg["mfa_module_id"]
        try:
            await hass.auth.async_disable_user_mfa(connection.user,
                                                   msg["mfa_module_id"])
        except ValueError as err:
            connection.send_message(
                websocket_api.error_message(
                    msg["id"],
                    "disable_failed",
                    f"Cannot disable MFA Module {mfa_module_id}: {err}",
                ))
            return

        connection.send_message(websocket_api.result_message(
            msg["id"], "done"))
Exemple #35
0
async def websocket_siren_off(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("stop_activity for " + str(camera.unique_id))

        await camera.async_siren_off()
        connection.send_message(
            websocket_api.result_message(msg["id"], {"siren": "off"}))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "siren_off_ws",
                "Unable to turn siren off ({})".format(str(error)),
            ))
        _LOGGER.warning("{} siren off websocket failed".format(
            msg["entity_id"]))
Exemple #36
0
async def websocket_stream_url(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("stream_url for " + str(camera.unique_id))

        stream = await camera.async_stream_source()
        connection.send_message(
            websocket_api.result_message(msg["id"], {"url": stream}))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "stream_url_ws",
                "Unable to fetch stream ({})".format(str(error)),
            ))
        _LOGGER.warning("{} stream url websocket failed".format(
            msg["entity_id"]))
Exemple #37
0
    async def send_image():
        """Send image."""
        data, content_type = await player.async_get_media_image()

        if data is None:
            connection.send_message_outside(
                websocket_api.error_message(msg['id'],
                                            'thumbnail_fetch_failed',
                                            'Failed to fetch thumbnail'))
            return

        connection.send_message_outside(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': content_type,
                    'content': base64.b64encode(data).decode('utf-8')
                }))
Exemple #38
0
async def websocket_camera_thumbnail(hass, connection, msg):
    """Handle get camera thumbnail websocket command.

    Async friendly.
    """
    try:
        image = await async_get_image(hass, msg['entity_id'])
        connection.send_message(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': image.content_type,
                    'content': base64.b64encode(image.content).decode('utf-8')
                }))
    except HomeAssistantError:
        connection.send_message(
            websocket_api.error_message(msg['id'], 'image_fetch_failed',
                                        'Unable to fetch image'))
Exemple #39
0
async def websocket_request_snapshot(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("request_snapshot_image for " + str(camera.unique_id))

        await camera.async_request_snapshot()
        connection.send_message(
            websocket_api.result_message(msg["id"], {"snapshot requested"}))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "requst_snapshot_ws",
                "Unable to request snapshot ({})".format(str(error)),
            ))
        _LOGGER.warning("{} snapshot request websocket failed".format(
            msg["entity_id"]))
Exemple #40
0
async def websocket_get_device(hass, connection, msg):
    """Get ZHA devices."""
    zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
    ha_device_registry = await async_get_registry(hass)
    ieee = msg[ATTR_IEEE]
    device = None
    if ieee in zha_gateway.devices:
        device = async_get_device_info(hass,
                                       zha_gateway.devices[ieee],
                                       ha_device_registry=ha_device_registry)
    if not device:
        connection.send_message(
            websocket_api.error_message(msg[ID],
                                        websocket_api.const.ERR_NOT_FOUND,
                                        "ZHA Device not found"))
        return
    connection.send_result(msg[ID], device)
Exemple #41
0
    async def send_exp_config():
        """Send lovelace frontend config."""
        error = None
        try:
            config = await hass.async_add_job(
                load_yaml, hass.config.path('ui-lovelace.yaml'))
            message = websocket_api.result_message(msg['id'], config)
        except FileNotFoundError:
            error = ('file_not_found',
                     'Could not find ui-lovelace.yaml in your config dir.')
        except HomeAssistantError as err:
            error = 'load_error', str(err)

        if error is not None:
            message = websocket_api.error_message(msg['id'], *error)

        connection.send_message_outside(message)
Exemple #42
0
async def websocket_update_prefs(hass, connection, msg):
    """Handle request for account info."""
    cloud = hass.data[DOMAIN]

    if not cloud.is_logged_in:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'not_logged_in',
            'You need to be logged in to the cloud.'))
        return

    changes = dict(msg)
    changes.pop('id')
    changes.pop('type')
    await cloud.update_preferences(**changes)

    connection.send_message(websocket_api.result_message(
        msg['id'], {'success': True}))
Exemple #43
0
async def websocket_library(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        videos = []
        _LOGGER.debug("library+" + str(msg["at_most"]))
        for v in camera.last_n_videos(msg["at_most"]):
            videos.append({
                "created_at":
                v.created_at,
                "created_at_pretty":
                v.created_at_pretty(camera.last_capture_date_format),
                "duration":
                v.media_duration_seconds,
                "url":
                v.video_url,
                "url_type":
                v.content_type,
                "thumbnail":
                v.thumbnail_url,
                "thumbnail_type":
                "image/jpeg",
                "object":
                v.object_type,
                "object_region":
                v.object_region,
                "trigger":
                v.object_type,
                "trigger_region":
                v.object_region,
            })
        connection.send_message(
            websocket_api.result_message(
                msg["id"],
                {
                    "videos": videos,
                },
            ))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "library_ws",
                "Unable to fetch library ({})".format(str(error)),
            ))
        _LOGGER.warning("{} library websocket failed".format(msg["entity_id"]))
Exemple #44
0
async def websocket_camera_thumbnail(hass, connection, msg):
    """Handle get camera thumbnail websocket command.

    Async friendly.
    """
    try:
        image = await async_get_image(hass, msg["entity_id"])
        await connection.send_big_result(
            msg["id"],
            {
                "content_type": image.content_type,
                "content": base64.b64encode(image.content).decode("utf-8"),
            },
        )
    except HomeAssistantError:
        connection.send_message(
            websocket_api.error_message(msg["id"], "image_fetch_failed",
                                        "Unable to fetch image"))
Exemple #45
0
async def websocket_remove_group_members(hass, connection, msg):
    """Remove members from a ZHA group."""
    zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
    group_id = msg[GROUP_ID]
    members = msg[ATTR_MEMBERS]
    zha_group = None

    if group_id in zha_gateway.groups:
        zha_group = zha_gateway.groups.get(group_id)
        await zha_group.async_remove_members(members)
    if not zha_group:
        connection.send_message(
            websocket_api.error_message(msg[ID],
                                        websocket_api.const.ERR_NOT_FOUND,
                                        "ZHA Group not found"))
        return
    ret_group = zha_group.async_get_info()
    connection.send_result(msg[ID], ret_group)
Exemple #46
0
async def websocket_stream_url(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("stream_url for " + str(camera.unique_id))

        # start stream and force user agent to linux, this will return a `mpeg dash`
        # stream we can use directly from the Lovelace card
        stream = await camera.async_stream_source(user_agent="linux")
        connection.send_message(
            websocket_api.result_message(msg["id"], {"url": stream}))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "stream_url_ws",
                "Unable to fetch stream ({})".format(str(error)),
            ))
        _LOGGER.warning("{} stream url websocket failed".format(
            msg["entity_id"]))
Exemple #47
0
async def websocket_lovelace_migrate_config(hass, connection, msg):
    """Migrate lovelace UI config."""
    error = None
    try:
        config = await hass.async_add_executor_job(
            migrate_config, hass.config.path(LOVELACE_CONFIG_FILE))
        message = websocket_api.result_message(msg['id'], config)
    except FileNotFoundError:
        error = ('file_not_found',
                 'Could not find ui-lovelace.yaml in your config dir.')
    except UnsupportedYamlError as err:
        error = 'unsupported_error', str(err)
    except HomeAssistantError as err:
        error = 'load_error', str(err)

    if error is not None:
        message = websocket_api.error_message(msg['id'], *error)

    connection.send_message(message)
Exemple #48
0
async def websocket_create_long_lived_access_token(
        hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg):
    """Create or a long-lived access token."""
    refresh_token = await hass.auth.async_create_refresh_token(
        connection.user,
        client_name=msg["client_name"],
        client_icon=msg.get("client_icon"),
        token_type=TOKEN_TYPE_LONG_LIVED_ACCESS_TOKEN,
        access_token_expiration=timedelta(days=msg["lifespan"]),
    )

    try:
        access_token = hass.auth.async_create_access_token(refresh_token)
    except InvalidAuthError as exc:
        return websocket_api.error_message(
            msg["id"], websocket_api.const.ERR_UNAUTHORIZED, str(exc))

    connection.send_message(
        websocket_api.result_message(msg["id"], access_token))
Exemple #49
0
async def websocket_video_url(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg['entity_id'])
        video = camera.last_video
        url = video.video_url if video is not None else None
        url_type = video.content_type if video is not None else None
        thumbnail = video.thumbnail_url if video is not None else None
        connection.send_message(websocket_api.result_message(
            msg['id'], {
                'url': url,
                'url_type': url_type,
                'thumbnail': thumbnail,
                'thumbnail_type': 'image/jpeg',
            }
        ))
    except HomeAssistantError as error:
        connection.send_message(websocket_api.error_message(
            msg['id'], 'video_url_ws', "Unable to fetch url ({})".format(str(error))))
        _LOGGER.warning("{} video url websocket failed".format(msg['entity_id']))
Exemple #50
0
async def websocket_snapshot_image(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg['entity_id'])
        _LOGGER.debug('snapshot_image for ' + str(camera.unique_id))

        image = await camera.async_get_snapshot()
        connection.send_message(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': camera.content_type,
                    'content': base64.b64encode(image).decode('utf-8')
                }))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg['id'], 'snapshot_image_ws',
                "Unable to take snapshot ({})".format(str(error))))
        _LOGGER.warning("{} snapshot image websocket failed".format(
            msg['entity_id']))
Exemple #51
0
async def websocket_video_data(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg['entity_id'])
        _LOGGER.debug('video_data for ' + str(camera.unique_id))

        video = await camera.async_get_video()
        connection.send_message(
            websocket_api.result_message(
                msg['id'], {
                    'content_type': 'video/mp4',
                    'content': base64.b64encode(video).decode('utf-8')
                }))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg['id'], 'video_data_ws',
                "Unable to get video data ({})".format(str(error))))
        _LOGGER.warning("{} video data websocket failed".format(
            msg['entity_id']))
Exemple #52
0
def websocket_node_metadata(hass, connection, msg):
    """Get the metadata for a Z-Wave node."""
    manager = hass.data[DOMAIN][MANAGER]
    node = manager.get_instance(msg[OZW_INSTANCE]).get_node(msg[NODE_ID])

    if not node:
        connection.send_message(
            websocket_api.error_message(msg[ID],
                                        websocket_api.const.ERR_NOT_FOUND,
                                        "OZW Node not found"))
        return

    connection.send_result(
        msg[ID],
        {
            "metadata": node.meta_data,
            NODE_ID: node.node_id,
            OZW_INSTANCE: msg[OZW_INSTANCE],
        },
    )
Exemple #53
0
async def websocket_get_group(hass, connection, msg):
    """Get ZHA group."""
    zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
    ha_device_registry = await async_get_registry(hass)
    group_id = msg[GROUP_ID]
    group = None

    if group_id in zha_gateway.application_controller.groups:
        group = async_get_group_info(
            hass,
            zha_gateway,
            zha_gateway.application_controller.groups[group_id],
            ha_device_registry,
        )
    if not group:
        connection.send_message(
            websocket_api.error_message(msg[ID],
                                        websocket_api.const.ERR_NOT_FOUND,
                                        "ZHA Group not found"))
        return
    connection.send_result(msg[ID], group)
Exemple #54
0
async def websocket_lovelace_update_card(hass, connection, msg):
    """Receive lovelace card config over websocket and save."""
    error = None
    try:
        await hass.async_add_executor_job(
            update_card, hass.config.path(LOVELACE_CONFIG_FILE),
            msg['card_id'], msg['card_config'], msg.get('format', FORMAT_YAML))
        message = websocket_api.result_message(msg['id'], True)
    except FileNotFoundError:
        error = ('file_not_found',
                 'Could not find ui-lovelace.yaml in your config dir.')
    except UnsupportedYamlError as err:
        error = 'unsupported_error', str(err)
    except CardNotFoundError as err:
        error = 'card_not_found', str(err)
    except HomeAssistantError as err:
        error = 'save_error', str(err)

    if error is not None:
        message = websocket_api.error_message(msg['id'], *error)

    connection.send_message(message)
Exemple #55
0
async def websocket_camera_thumbnail(hass: HomeAssistant,
                                     connection: ActiveConnection,
                                     msg: dict) -> None:
    """Handle get camera thumbnail websocket command.

    Async friendly.
    """
    _LOGGER.warning(
        "The websocket command 'camera_thumbnail' has been deprecated")
    try:
        image = await async_get_image(hass, msg["entity_id"])
        await connection.send_big_result(
            msg["id"],
            {
                "content_type": image.content_type,
                "content": base64.b64encode(image.content).decode("utf-8"),
            },
        )
    except HomeAssistantError:
        connection.send_message(
            websocket_api.error_message(msg["id"], "image_fetch_failed",
                                        "Unable to fetch image"))
Exemple #56
0
async def websocket_load_properties(
    hass: HomeAssistant,
    connection: websocket_api.connection.ActiveConnection,
    msg: dict,
) -> None:
    """Add the default All-Link Database records for an Insteon device."""
    device = devices[msg[DEVICE_ADDRESS]]
    if not device:
        notify_device_not_found(connection, msg, INSTEON_DEVICE_NOT_FOUND)
        return

    result1 = await device.async_read_op_flags()
    result2 = await device.async_read_ext_properties()
    await devices.async_save(workdir=hass.config.config_dir)
    if result1 != ResponseStatus.SUCCESS or result2 != ResponseStatus.SUCCESS:
        connection.send_message(
            websocket_api.error_message(
                msg[ID], "load_failed", "properties not loaded from device"
            )
        )
        return
    connection.send_result(msg[ID])
Exemple #57
0
async def websocket_library(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg['entity_id'])
        videos = []
        _LOGGER.debug('library+' + str(msg['at_most']))
        for v in camera.last_n_videos(msg['at_most']):
            videos.append({
                'created_at':
                v.created_at,
                'created_at_pretty':
                v.created_at_pretty(camera.last_capture_date_format),
                'url':
                v.video_url,
                'url_type':
                v.content_type,
                'thumbnail':
                v.thumbnail_url,
                'thumbnail_type':
                'image/jpeg',
                'object':
                v.object_type,
                'object_region':
                v.object_region,
                'trigger':
                v.object_type,
                'trigger_region':
                v.object_region,
            })
        connection.send_message(
            websocket_api.result_message(msg['id'], {
                'videos': videos,
            }))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg['id'], 'library_ws',
                "Unable to fetch library ({})".format(str(error))))
        _LOGGER.warning("{} library websocket failed".format(msg['entity_id']))
Exemple #58
0
async def websocket_snapshot_image(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("snapshot_image for " + str(camera.unique_id))

        image = await camera.async_get_snapshot()
        connection.send_message(
            websocket_api.result_message(
                msg["id"],
                {
                    "content_type": camera.content_type,
                    "content": base64.b64encode(image).decode("utf-8"),
                },
            ))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "snapshot_image_ws",
                "Unable to take snapshot ({})".format(str(error)),
            ))
        _LOGGER.warning("{} snapshot image websocket failed".format(
            msg["entity_id"]))
Exemple #59
0
async def websocket_video_data(hass, connection, msg):
    try:
        camera = get_entity_from_domain(hass, DOMAIN, msg["entity_id"])
        _LOGGER.debug("video_data for " + str(camera.unique_id))

        video = await camera.async_get_video()
        connection.send_message(
            websocket_api.result_message(
                msg["id"],
                {
                    "content_type": "video/mp4",
                    "content": base64.b64encode(video).decode("utf-8"),
                },
            ))
    except HomeAssistantError as error:
        connection.send_message(
            websocket_api.error_message(
                msg["id"],
                "video_data_ws",
                "Unable to get video data ({})".format(str(error)),
            ))
        _LOGGER.warning("{} video data websocket failed".format(
            msg["entity_id"]))
Exemple #60
0
async def websocket_remove_group_members(hass, connection, msg):
    """Remove members from a ZHA group."""
    zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
    ha_device_registry = await async_get_registry(hass)
    group_id = msg[GROUP_ID]
    members = msg[ATTR_MEMBERS]
    zigpy_group = None

    if group_id in zha_gateway.application_controller.groups:
        zigpy_group = zha_gateway.application_controller.groups[group_id]
        tasks = []
        for ieee in members:
            tasks.append(zha_gateway.devices[ieee].async_remove_from_group(group_id))
        await asyncio.gather(*tasks)
    if not zigpy_group:
        connection.send_message(
            websocket_api.error_message(
                msg[ID], websocket_api.const.ERR_NOT_FOUND, "ZHA Group not found"
            )
        )
        return
    ret_group = async_get_group_info(hass, zha_gateway, zigpy_group, ha_device_registry)
    connection.send_result(msg[ID], ret_group)