You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.2 KiB
199 lines
7.2 KiB
5 years ago
|
"""
|
||
|
Custom element manager for community created elements.
|
||
|
|
||
|
For more details about this integration, please refer to the documentation at
|
||
|
https://hacs.xyz/
|
||
|
"""
|
||
|
import voluptuous as vol
|
||
|
from aiogithubapi import AIOGitHub
|
||
|
from homeassistant import config_entries
|
||
|
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||
|
from homeassistant.const import __version__ as HAVERSION
|
||
|
from homeassistant.components.lovelace import system_health_info
|
||
|
from homeassistant.exceptions import ConfigEntryNotReady, ServiceNotFound
|
||
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||
|
from homeassistant.helpers.event import async_call_later
|
||
|
|
||
|
from .configuration_schema import hacs_base_config_schema, hacs_config_option_schema
|
||
|
from .const import DOMAIN, ELEMENT_TYPES, STARTUP, VERSION
|
||
|
from .constrains import check_constans
|
||
|
from .hacsbase import Hacs
|
||
|
from .hacsbase.configuration import Configuration
|
||
|
from .hacsbase.data import HacsData
|
||
|
from .setup import add_sensor, load_hacs_repository, setup_frontend, setup_extra_stores
|
||
|
|
||
|
SCHEMA = hacs_base_config_schema()
|
||
|
SCHEMA[vol.Optional("options")] = hacs_config_option_schema()
|
||
|
CONFIG_SCHEMA = vol.Schema({DOMAIN: SCHEMA}, extra=vol.ALLOW_EXTRA)
|
||
|
|
||
|
|
||
|
async def async_setup(hass, config):
|
||
|
"""Set up this integration using yaml."""
|
||
|
if DOMAIN not in config:
|
||
|
return True
|
||
|
hass.data[DOMAIN] = config
|
||
|
Hacs.hass = hass
|
||
|
Hacs.configuration = Configuration.from_dict(
|
||
|
config[DOMAIN], config[DOMAIN].get("options")
|
||
|
)
|
||
|
Hacs.configuration.config_type = "yaml"
|
||
|
await startup_wrapper_for_yaml(Hacs)
|
||
|
hass.async_create_task(
|
||
|
hass.config_entries.flow.async_init(
|
||
|
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data={}
|
||
|
)
|
||
|
)
|
||
|
return True
|
||
|
|
||
|
|
||
|
async def async_setup_entry(hass, config_entry):
|
||
|
"""Set up this integration using UI."""
|
||
|
conf = hass.data.get(DOMAIN)
|
||
|
if config_entry.source == config_entries.SOURCE_IMPORT:
|
||
|
if conf is None:
|
||
|
hass.async_create_task(
|
||
|
hass.config_entries.async_remove(config_entry.entry_id)
|
||
|
)
|
||
|
return False
|
||
|
Hacs.hass = hass
|
||
|
Hacs.configuration = Configuration.from_dict(
|
||
|
config_entry.data, config_entry.options
|
||
|
)
|
||
|
Hacs.configuration.config_type = "flow"
|
||
|
Hacs.configuration.config_entry = config_entry
|
||
|
config_entry.add_update_listener(reload_hacs)
|
||
|
startup_result = await hacs_startup(Hacs)
|
||
|
if not startup_result:
|
||
|
Hacs.system.disabled = True
|
||
|
raise ConfigEntryNotReady
|
||
|
Hacs.system.disabled = False
|
||
|
return startup_result
|
||
|
|
||
|
|
||
|
async def startup_wrapper_for_yaml(hacs):
|
||
|
"""Startup wrapper for yaml config."""
|
||
|
startup_result = await hacs_startup(hacs)
|
||
|
if not startup_result:
|
||
|
hacs.system.disabled = True
|
||
|
hacs.hass.components.frontend.async_remove_panel(
|
||
|
hacs.configuration.sidepanel_title.lower()
|
||
|
.replace(" ", "_")
|
||
|
.replace("-", "_")
|
||
|
)
|
||
|
hacs.logger.info("Could not setup HACS, trying again in 15 min")
|
||
|
async_call_later(hacs.hass, 900, startup_wrapper_for_yaml(hacs))
|
||
|
return
|
||
|
hacs.system.disabled = False
|
||
|
|
||
|
|
||
|
async def hacs_startup(hacs):
|
||
|
"""HACS startup tasks."""
|
||
|
if hacs.configuration.debug:
|
||
|
try:
|
||
|
await hacs.hass.services.async_call(
|
||
|
"logger", "set_level", {"hacs": "debug"}
|
||
|
)
|
||
|
except ServiceNotFound:
|
||
|
hacs.logger.error(
|
||
|
"Could not set logging level to debug, logger is not enabled"
|
||
|
)
|
||
|
|
||
|
lovelace_info = await system_health_info(hacs.hass)
|
||
|
hacs.logger.debug(f"Configuration type: {hacs.configuration.config_type}")
|
||
|
hacs.version = VERSION
|
||
|
hacs.logger.info(STARTUP)
|
||
|
hacs.system.config_path = hacs.hass.config.path()
|
||
|
hacs.system.ha_version = HAVERSION
|
||
|
|
||
|
hacs.system.lovelace_mode = lovelace_info.get("mode", "yaml")
|
||
|
hacs.system.disabled = False
|
||
|
hacs.github = AIOGitHub(
|
||
|
hacs.configuration.token, async_create_clientsession(hacs.hass)
|
||
|
)
|
||
|
hacs.data = HacsData()
|
||
|
|
||
|
# Check HACS Constrains
|
||
|
if not await hacs.hass.async_add_executor_job(check_constans, hacs):
|
||
|
if hacs.configuration.config_type == "flow":
|
||
|
if hacs.configuration.config_entry is not None:
|
||
|
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||
|
return False
|
||
|
|
||
|
# Set up frontend
|
||
|
await setup_frontend(hacs)
|
||
|
|
||
|
# Set up sensor
|
||
|
await hacs.hass.async_add_executor_job(add_sensor, hacs)
|
||
|
|
||
|
# Load HACS
|
||
|
if not await load_hacs_repository(hacs):
|
||
|
if hacs.configuration.config_type == "flow":
|
||
|
if hacs.configuration.config_entry is not None:
|
||
|
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||
|
return False
|
||
|
|
||
|
# Restore from storefiles
|
||
|
if not await hacs.data.restore():
|
||
|
hacs_repo = hacs().get_by_name("hacs/integration")
|
||
|
hacs_repo.pending_restart = True
|
||
|
if hacs.configuration.config_type == "flow":
|
||
|
if hacs.configuration.config_entry is not None:
|
||
|
await async_remove_entry(hacs.hass, hacs.configuration.config_entry)
|
||
|
return False
|
||
|
|
||
|
# Add aditional categories
|
||
|
hacs.common.categories = ELEMENT_TYPES
|
||
|
if hacs.configuration.appdaemon:
|
||
|
hacs.common.categories.append("appdaemon")
|
||
|
if hacs.configuration.python_script:
|
||
|
hacs.configuration.python_script = False
|
||
|
if hacs.configuration.config_type == "yaml":
|
||
|
hacs.logger.warning(
|
||
|
"Configuration option 'python_script' is deprecated and you should remove it from your configuration, HACS will know if you use 'python_script' in your Home Assistant configuration, this option will be removed in a future release."
|
||
|
)
|
||
|
if hacs.configuration.theme:
|
||
|
hacs.configuration.theme = False
|
||
|
if hacs.configuration.config_type == "yaml":
|
||
|
hacs.logger.warning(
|
||
|
"Configuration option 'theme' is deprecated and you should remove it from your configuration, HACS will know if you use 'theme' in your Home Assistant configuration, this option will be removed in a future release."
|
||
|
)
|
||
|
|
||
|
await hacs.hass.async_add_executor_job(setup_extra_stores, hacs)
|
||
|
|
||
|
# Setup startup tasks
|
||
|
if hacs.configuration.config_type == "yaml":
|
||
|
hacs.hass.bus.async_listen_once(
|
||
|
EVENT_HOMEASSISTANT_START, hacs().startup_tasks()
|
||
|
)
|
||
|
else:
|
||
|
async_call_later(hacs.hass, 5, hacs().startup_tasks())
|
||
|
|
||
|
# Mischief managed!
|
||
|
return True
|
||
|
|
||
|
|
||
|
async def async_remove_entry(hass, config_entry):
|
||
|
"""Handle removal of an entry."""
|
||
|
Hacs().logger.info("Disabling HACS")
|
||
|
Hacs().logger.info("Removing recuring tasks")
|
||
|
for task in Hacs().recuring_tasks:
|
||
|
task()
|
||
|
Hacs().logger.info("Removing sensor")
|
||
|
try:
|
||
|
await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")
|
||
|
except ValueError:
|
||
|
pass
|
||
|
Hacs().logger.info("Removing sidepanel")
|
||
|
try:
|
||
|
hass.components.frontend.async_remove_panel("hacs")
|
||
|
except AttributeError:
|
||
|
pass
|
||
|
Hacs().system.disabled = True
|
||
|
Hacs().logger.info("HACS is now disabled")
|
||
|
|
||
|
|
||
|
async def reload_hacs(hass, config_entry):
|
||
|
"""Reload HACS."""
|
||
|
await async_remove_entry(hass, config_entry)
|
||
|
await async_setup_entry(hass, config_entry)
|