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']))
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') }))
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) ))
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']))
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']))
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']))
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'))
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'))
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) ))
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'))
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' ))
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']))
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') }))
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) ))
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'))
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'))
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)) )
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'))
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"))
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"]))
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"]))
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') }))
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 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"]))
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)
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)
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}))
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"]))
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"))
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)
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"]))
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)
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))
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']))
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']))
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']))
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], }, )
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)
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)
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"))
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])
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']))
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"]))
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"]))
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)