mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 00:48:19 +01:00
Add custom component mechanism
This commit is contained in:
parent
b7afb8c887
commit
db0dd6af09
1 changed files with 42 additions and 3 deletions
|
@ -7,6 +7,7 @@ import re
|
|||
import os.path
|
||||
|
||||
# pylint: disable=unused-import, wrong-import-order
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -17,7 +18,7 @@ from esphome.components.substitutions import CONF_SUBSTITUTIONS
|
|||
from esphome.const import CONF_ESPHOME, CONF_PLATFORM, ESP_PLATFORMS
|
||||
from esphome.core import CORE, EsphomeError # noqa
|
||||
from esphome.helpers import color, indent
|
||||
from esphome.py_compat import text_type
|
||||
from esphome.py_compat import text_type, IS_PY2
|
||||
from esphome.util import safe_print, OrderedDict
|
||||
|
||||
from typing import List, Optional, Tuple, Union # noqa
|
||||
|
@ -106,15 +107,53 @@ class ComponentManifest(object):
|
|||
|
||||
|
||||
CORE_COMPONENTS_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 'components'))
|
||||
_UNDEF = object()
|
||||
CUSTOM_COMPONENTS_PATH = _UNDEF
|
||||
|
||||
|
||||
def _mount_config_dir():
|
||||
global CUSTOM_COMPONENTS_PATH
|
||||
if CUSTOM_COMPONENTS_PATH is not _UNDEF:
|
||||
return
|
||||
custom_path = os.path.abspath(os.path.join(CORE.config_dir, 'custom_components'))
|
||||
if not os.path.isdir(custom_path):
|
||||
CUSTOM_COMPONENTS_PATH = None
|
||||
return
|
||||
init_path = os.path.join(custom_path, '__init__.py')
|
||||
if IS_PY2 and not os.path.isfile(init_path):
|
||||
_LOGGER.warning("Found 'custom_components' folder, but file __init__.py was not found. "
|
||||
"ESPHome will automatically create it now....")
|
||||
with open(init_path, 'w') as f:
|
||||
f.write('\n')
|
||||
if CORE.config_dir not in sys.path:
|
||||
sys.path.insert(0, CORE.config_dir)
|
||||
CUSTOM_COMPONENTS_PATH = custom_path
|
||||
|
||||
|
||||
def _lookup_module(domain, is_platform):
|
||||
if domain in _COMPONENT_CACHE:
|
||||
return _COMPONENT_CACHE[domain]
|
||||
|
||||
path = 'esphome.components.{}'.format(domain)
|
||||
_mount_config_dir()
|
||||
# First look for custom_components
|
||||
try:
|
||||
module = importlib.import_module(path)
|
||||
module = importlib.import_module('custom_components.{}'.format(domain))
|
||||
except ImportError as e:
|
||||
# ImportError when no such module
|
||||
if 'No module named' not in str(e):
|
||||
_LOGGER.warn("Unable to import custom component %s:", domain, exc_info=True)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# Other error means component has an issue
|
||||
_LOGGER.error("Unable to load custom component %s:", domain, exc_info=True)
|
||||
return None
|
||||
else:
|
||||
# Found in custom components
|
||||
manif = ComponentManifest(module, CUSTOM_COMPONENTS_PATH, is_platform=is_platform)
|
||||
_COMPONENT_CACHE[domain] = manif
|
||||
return manif
|
||||
|
||||
try:
|
||||
module = importlib.import_module('esphome.components.{}'.format(domain))
|
||||
except ImportError as e:
|
||||
if 'No module named' in str(e):
|
||||
_LOGGER.error("Unable to import component %s:", domain)
|
||||
|
|
Loading…
Reference in a new issue