Files
home-assistant-alt/hass/settings/custom_components/yandex_smart_home/http.py
T
2024-01-11 15:10:51 +03:00

123 lines
4.3 KiB
Python

"""Support for Yandex Smart Home."""
from __future__ import annotations
import logging
from typing import Any
from aiohttp.web import Request, Response
from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant, callback
from .const import CONFIG, DOMAIN
from .helpers import Config
from .smart_home import RequestData, async_devices, async_handle_message
_LOGGER = logging.getLogger(__name__)
@callback
def async_register_http(hass: HomeAssistant):
"""Register HTTP views for Yandex Smart Home."""
hass.http.register_view(YandexSmartHomeUnauthorizedView())
hass.http.register_view(YandexSmartHomePingView())
hass.http.register_view(YandexSmartHomeView())
class YandexSmartHomeView:
@staticmethod
def _get_config(request: Request) -> Config | None:
return request.app['hass'].data[DOMAIN][CONFIG]
def _is_direct_connection(self, request: Request) -> bool:
"""Check if integration configured to use direct connection."""
config = self._get_config(request)
if not config:
return False
return config.is_direct_connection
class YandexSmartHomeUnauthorizedView(HomeAssistantView, YandexSmartHomeView):
"""Handle Yandex Smart Home unauthorized requests."""
url = f'/api/{DOMAIN}/v1.0'
name = f'api:{DOMAIN}:unauthorized'
requires_auth = False
async def head(self, request: Request) -> Response:
"""Handle Yandex Smart Home HEAD requests."""
_LOGGER.debug('Request: %s (HEAD)' % request.url)
if not self._is_direct_connection(request):
_LOGGER.debug('Integration is not enabled or use cloud connection')
return Response(status=404)
return Response(status=200)
class YandexSmartHomePingView(HomeAssistantView, YandexSmartHomeView):
"""Handle Yandex Smart Home ping requests."""
url = f'/api/{DOMAIN}/v1.0/ping'
name = f'api:{DOMAIN}:unauthorized'
requires_auth = False
# noinspection PyMethodMayBeStatic
async def get(self, request: Request) -> Response:
"""Handle Yandex Smart Home Get requests."""
_LOGGER.debug('Request: %s (GET)' % request.url)
if not self._is_direct_connection(request):
return Response(text='Error: Integration is not enabled or use cloud connection', status=503)
data = RequestData(self._get_config(request), None, 'ping')
devices_sync_response = await async_devices(request.app['hass'], data, {})
device_count = len(devices_sync_response['devices'])
return Response(text=f'OK: {device_count}', status=200)
class YandexSmartHomeView(YandexSmartHomeUnauthorizedView, YandexSmartHomeView):
"""Handle Yandex Smart Home requests."""
url = f'/api/{DOMAIN}/v1.0'
extra_urls = [
url + '/user/unlink',
url + '/user/devices',
url + '/user/devices/query',
url + '/user/devices/action',
]
name = f'api:{DOMAIN}'
requires_auth = True
async def _async_handle_request(self, request: Request, message: dict[str, Any] | None = None) -> Response:
if not self._is_direct_connection(request):
_LOGGER.debug('Integration is not enabled or use cloud connection')
return Response(status=404)
data = RequestData(
config=self._get_config(request),
request_user_id=request['hass_user'].id,
request_id=request.headers.get('X-Request-Id'),
user_id=request['hass_user'].id,
)
action = request.path.replace(self.url, '', 1)
result = await async_handle_message(request.app['hass'], data, action, message or {})
response = self.json(result)
_LOGGER.debug(f'Response: {response.text}')
return response
async def post(self, request: Request) -> Response:
"""Handle Yandex Smart Home POST requests."""
_LOGGER.debug('Request: %s (POST data: %s)' % (request.url, await request.text()))
if str(request.url).endswith('/user/unlink'):
return await self._async_handle_request(request)
return await self._async_handle_request(request, await request.json())
async def get(self, request: Request) -> Response:
"""Handle Yandex Smart Home GET requests."""
_LOGGER.debug('Request: %s' % request.url)
return await self._async_handle_request(request)