148 lines
4.3 KiB
Python
148 lines
4.3 KiB
Python
"""Component to integrate the Home Assistant cloud."""
|
|
import asyncio
|
|
import json
|
|
import logging
|
|
import os
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.const import (
|
|
EVENT_HOMEASSISTANT_START, CONF_REGION, CONF_MODE)
|
|
|
|
from . import http_api, iot
|
|
from .const import CONFIG_DIR, DOMAIN, SERVERS
|
|
|
|
REQUIREMENTS = ['warrant==0.5.0']
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
CONF_COGNITO_CLIENT_ID = 'cognito_client_id'
|
|
CONF_RELAYER = 'relayer'
|
|
CONF_USER_POOL_ID = 'user_pool_id'
|
|
|
|
MODE_DEV = 'development'
|
|
DEFAULT_MODE = MODE_DEV
|
|
DEPENDENCIES = ['http']
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
DOMAIN: vol.Schema({
|
|
vol.Optional(CONF_MODE, default=DEFAULT_MODE):
|
|
vol.In([MODE_DEV] + list(SERVERS)),
|
|
# Change to optional when we include real servers
|
|
vol.Required(CONF_COGNITO_CLIENT_ID): str,
|
|
vol.Required(CONF_USER_POOL_ID): str,
|
|
vol.Required(CONF_REGION): str,
|
|
vol.Required(CONF_RELAYER): str,
|
|
}),
|
|
}, extra=vol.ALLOW_EXTRA)
|
|
|
|
|
|
@asyncio.coroutine
|
|
def async_setup(hass, config):
|
|
"""Initialize the Home Assistant cloud."""
|
|
if DOMAIN in config:
|
|
kwargs = config[DOMAIN]
|
|
else:
|
|
kwargs = {CONF_MODE: DEFAULT_MODE}
|
|
|
|
cloud = hass.data[DOMAIN] = Cloud(hass, **kwargs)
|
|
|
|
@asyncio.coroutine
|
|
def init_cloud(event):
|
|
"""Initialize connection."""
|
|
yield from cloud.initialize()
|
|
|
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, init_cloud)
|
|
|
|
yield from http_api.async_setup(hass)
|
|
return True
|
|
|
|
|
|
class Cloud:
|
|
"""Store the configuration of the cloud connection."""
|
|
|
|
def __init__(self, hass, mode, cognito_client_id=None, user_pool_id=None,
|
|
region=None, relayer=None):
|
|
"""Create an instance of Cloud."""
|
|
self.hass = hass
|
|
self.mode = mode
|
|
self.email = None
|
|
self.id_token = None
|
|
self.access_token = None
|
|
self.refresh_token = None
|
|
self.iot = iot.CloudIoT(self)
|
|
|
|
if mode == MODE_DEV:
|
|
self.cognito_client_id = cognito_client_id
|
|
self.user_pool_id = user_pool_id
|
|
self.region = region
|
|
self.relayer = relayer
|
|
|
|
else:
|
|
info = SERVERS[mode]
|
|
|
|
self.cognito_client_id = info['cognito_client_id']
|
|
self.user_pool_id = info['user_pool_id']
|
|
self.region = info['region']
|
|
self.relayer = info['relayer']
|
|
|
|
@property
|
|
def is_logged_in(self):
|
|
"""Get if cloud is logged in."""
|
|
return self.email is not None
|
|
|
|
@property
|
|
def user_info_path(self):
|
|
"""Get path to the stored auth."""
|
|
return self.path('{}_auth.json'.format(self.mode))
|
|
|
|
@asyncio.coroutine
|
|
def initialize(self):
|
|
"""Initialize and load cloud info."""
|
|
def load_config():
|
|
"""Load the configuration."""
|
|
# Ensure config dir exists
|
|
path = self.hass.config.path(CONFIG_DIR)
|
|
if not os.path.isdir(path):
|
|
os.mkdir(path)
|
|
|
|
user_info = self.user_info_path
|
|
if os.path.isfile(user_info):
|
|
with open(user_info, 'rt') as file:
|
|
info = json.loads(file.read())
|
|
self.email = info['email']
|
|
self.id_token = info['id_token']
|
|
self.access_token = info['access_token']
|
|
self.refresh_token = info['refresh_token']
|
|
|
|
yield from self.hass.async_add_job(load_config)
|
|
|
|
if self.email is not None:
|
|
yield from self.iot.connect()
|
|
|
|
def path(self, *parts):
|
|
"""Get config path inside cloud dir."""
|
|
return self.hass.config.path(CONFIG_DIR, *parts)
|
|
|
|
@asyncio.coroutine
|
|
def logout(self):
|
|
"""Close connection and remove all credentials."""
|
|
yield from self.iot.disconnect()
|
|
|
|
self.email = None
|
|
self.id_token = None
|
|
self.access_token = None
|
|
self.refresh_token = None
|
|
|
|
yield from self.hass.async_add_job(
|
|
lambda: os.remove(self.user_info_path))
|
|
|
|
def write_user_info(self):
|
|
"""Write user info to a file."""
|
|
with open(self.user_info_path, 'wt') as file:
|
|
file.write(json.dumps({
|
|
'email': self.email,
|
|
'id_token': self.id_token,
|
|
'access_token': self.access_token,
|
|
'refresh_token': self.refresh_token,
|
|
}, indent=4))
|