79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
|
"""Connection session."""
|
||
|
import voluptuous as vol
|
||
|
|
||
|
from homeassistant.core import callback, Context
|
||
|
|
||
|
from . import const, messages
|
||
|
|
||
|
|
||
|
class ActiveConnection:
|
||
|
"""Handle an active websocket client connection."""
|
||
|
|
||
|
def __init__(self, logger, hass, send_message, user, refresh_token):
|
||
|
"""Initialize an active connection."""
|
||
|
self.logger = logger
|
||
|
self.hass = hass
|
||
|
self.send_message = send_message
|
||
|
self.user = user
|
||
|
if refresh_token:
|
||
|
self.refresh_token_id = refresh_token.id
|
||
|
else:
|
||
|
self.refresh_token_id = None
|
||
|
|
||
|
self.event_listeners = {}
|
||
|
self.last_id = 0
|
||
|
|
||
|
def context(self, msg):
|
||
|
"""Return a context."""
|
||
|
user = self.user
|
||
|
if user is None:
|
||
|
return Context()
|
||
|
return Context(user_id=user.id)
|
||
|
|
||
|
@callback
|
||
|
def async_handle(self, msg):
|
||
|
"""Handle a single incoming message."""
|
||
|
handlers = self.hass.data[const.DOMAIN]
|
||
|
|
||
|
try:
|
||
|
msg = messages.MINIMAL_MESSAGE_SCHEMA(msg)
|
||
|
cur_id = msg['id']
|
||
|
except vol.Invalid:
|
||
|
self.logger.error('Received invalid command', msg)
|
||
|
self.send_message(messages.error_message(
|
||
|
msg.get('id'), const.ERR_INVALID_FORMAT,
|
||
|
'Message incorrectly formatted.'))
|
||
|
return
|
||
|
|
||
|
if cur_id <= self.last_id:
|
||
|
self.send_message(messages.error_message(
|
||
|
cur_id, const.ERR_ID_REUSE,
|
||
|
'Identifier values have to increase.'))
|
||
|
return
|
||
|
|
||
|
if msg['type'] not in handlers:
|
||
|
self.logger.error(
|
||
|
'Received invalid command: {}'.format(msg['type']))
|
||
|
self.send_message(messages.error_message(
|
||
|
cur_id, const.ERR_UNKNOWN_COMMAND,
|
||
|
'Unknown command.'))
|
||
|
return
|
||
|
|
||
|
handler, schema = handlers[msg['type']]
|
||
|
|
||
|
try:
|
||
|
handler(self.hass, self, schema(msg))
|
||
|
except Exception: # pylint: disable=broad-except
|
||
|
self.logger.exception('Error handling message: %s', msg)
|
||
|
self.send_message(messages.error_message(
|
||
|
cur_id, const.ERR_UNKNOWN_ERROR,
|
||
|
'Unknown error.'))
|
||
|
|
||
|
self.last_id = cur_id
|
||
|
|
||
|
@callback
|
||
|
def async_close(self):
|
||
|
"""Close down connection."""
|
||
|
for unsub in self.event_listeners.values():
|
||
|
unsub()
|