Limit dependencies of HA core (#2762)
parent
915b9cb3eb
commit
640a8b5a7f
|
@ -11,7 +11,6 @@ import itertools as it
|
|||
import logging
|
||||
|
||||
import homeassistant.core as ha
|
||||
from homeassistant.helpers.entity import split_entity_id
|
||||
from homeassistant.helpers.service import extract_entity_ids
|
||||
from homeassistant.loader import get_component
|
||||
from homeassistant.const import (
|
||||
|
@ -35,7 +34,7 @@ def is_on(hass, entity_id=None):
|
|||
entity_ids = hass.states.entity_ids()
|
||||
|
||||
for entity_id in entity_ids:
|
||||
domain = split_entity_id(entity_id)[0]
|
||||
domain = ha.split_entity_id(entity_id)[0]
|
||||
|
||||
module = get_component(domain)
|
||||
|
||||
|
@ -95,7 +94,7 @@ def setup(hass, config):
|
|||
|
||||
# Group entity_ids by domain. groupby requires sorted data.
|
||||
by_domain = it.groupby(sorted(entity_ids),
|
||||
lambda item: split_entity_id(item)[0])
|
||||
lambda item: ha.split_entity_id(item)[0])
|
||||
|
||||
for domain, ent_ids in by_domain:
|
||||
# We want to block for all calls and only return when all calls
|
||||
|
|
|
@ -14,8 +14,7 @@ from homeassistant.const import (
|
|||
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, STATE_CLOSED, STATE_HOME,
|
||||
STATE_NOT_HOME, STATE_OFF, STATE_ON, STATE_OPEN, STATE_LOCKED,
|
||||
STATE_UNLOCKED, STATE_UNKNOWN, ATTR_ASSUMED_STATE)
|
||||
from homeassistant.helpers.entity import (
|
||||
Entity, generate_entity_id, split_entity_id)
|
||||
from homeassistant.helpers.entity import Entity, generate_entity_id
|
||||
from homeassistant.helpers.event import track_state_change
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
@ -101,7 +100,7 @@ def expand_entity_ids(hass, entity_ids):
|
|||
|
||||
try:
|
||||
# If entity_id points at a group, expand it
|
||||
domain, _ = split_entity_id(entity_id)
|
||||
domain, _ = ha.split_entity_id(entity_id)
|
||||
|
||||
if domain == DOMAIN:
|
||||
found_ids.extend(
|
||||
|
|
|
@ -20,7 +20,7 @@ from homeassistant.const import (
|
|||
HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||
HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_CORS_HEADERS,
|
||||
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START)
|
||||
from homeassistant.helpers.entity import split_entity_id
|
||||
from homeassistant.core import split_entity_id
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
|
|
@ -18,10 +18,8 @@ from homeassistant.components.http import HomeAssistantView
|
|||
from homeassistant.const import (EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP, EVENT_STATE_CHANGED,
|
||||
STATE_NOT_HOME, STATE_OFF, STATE_ON)
|
||||
from homeassistant.core import DOMAIN as HA_DOMAIN
|
||||
from homeassistant.core import State
|
||||
from homeassistant.core import State, split_entity_id, DOMAIN as HA_DOMAIN
|
||||
from homeassistant.helpers import template
|
||||
from homeassistant.helpers.entity import split_entity_id
|
||||
|
||||
DOMAIN = "logbook"
|
||||
DEPENDENCIES = ['recorder', 'frontend']
|
||||
|
|
|
@ -9,9 +9,8 @@ from sqlalchemy import (Boolean, Column, DateTime, ForeignKey, Index, Integer,
|
|||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.core import Event, EventOrigin, State
|
||||
from homeassistant.core import Event, EventOrigin, State, split_entity_id
|
||||
from homeassistant.remote import JSONEncoder
|
||||
from homeassistant.helpers.entity import split_entity_id
|
||||
|
||||
# SQLAlchemy Schema
|
||||
# pylint: disable=invalid-name
|
||||
|
|
|
@ -14,7 +14,8 @@ import voluptuous as vol
|
|||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON,
|
||||
SERVICE_TOGGLE, STATE_ON, CONF_ALIAS)
|
||||
from homeassistant.helpers.entity import ToggleEntity, split_entity_id
|
||||
from homeassistant.core import split_entity_id
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@ from homeassistant.const import (
|
|||
CONF_TIME_ZONE, CONF_CUSTOMIZE, CONF_ELEVATION, CONF_UNIT_SYSTEM_METRIC,
|
||||
CONF_UNIT_SYSTEM_IMPERIAL, CONF_TEMPERATURE_UNIT, TEMP_CELSIUS,
|
||||
__version__)
|
||||
from homeassistant.core import valid_entity_id
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.util.yaml import load_yaml
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.unit_system import (IMPERIAL_SYSTEM, METRIC_SYSTEM)
|
||||
from homeassistant.helpers.entity import valid_entity_id, set_customize
|
||||
from homeassistant.helpers.entity import set_customize
|
||||
from homeassistant.util import dt as date_util, location as loc_util
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
|
|
@ -9,22 +9,17 @@ import enum
|
|||
import functools as ft
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import threading
|
||||
import time
|
||||
from types import MappingProxyType
|
||||
|
||||
# pylint: disable=unused-import
|
||||
from typing import Optional, Any, Callable # NOQA
|
||||
from typing import Optional, Any, Callable, List # NOQA
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.helpers.typing import UnitSystemType # NOQA
|
||||
|
||||
import homeassistant.util as util
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.util.location as location
|
||||
from homeassistant.config import get_default_config_dir
|
||||
from homeassistant.const import (
|
||||
ATTR_DOMAIN, ATTR_FRIENDLY_NAME, ATTR_NOW, ATTR_SERVICE,
|
||||
ATTR_SERVICE_CALL_ID, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE,
|
||||
|
@ -34,10 +29,11 @@ from homeassistant.const import (
|
|||
SERVICE_HOMEASSISTANT_RESTART, SERVICE_HOMEASSISTANT_STOP, __version__)
|
||||
from homeassistant.exceptions import (
|
||||
HomeAssistantError, InvalidEntityFormatError)
|
||||
from homeassistant.helpers.entity import split_entity_id, valid_entity_id
|
||||
from homeassistant.helpers.unit_system import (
|
||||
METRIC_SYSTEM,
|
||||
)
|
||||
from homeassistant.helpers.typing import UnitSystemType # NOQA
|
||||
from homeassistant.helpers.unit_system import METRIC_SYSTEM
|
||||
import homeassistant.util as util
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.util.location as location
|
||||
|
||||
DOMAIN = "homeassistant"
|
||||
|
||||
|
@ -52,9 +48,22 @@ SERVICE_CALL_LIMIT = 10 # seconds
|
|||
# will be added for each component that polls devices.
|
||||
MIN_WORKER_THREAD = 2
|
||||
|
||||
# Pattern for validating entity IDs (format: <domain>.<entity>)
|
||||
ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def split_entity_id(entity_id: str) -> List[str]:
|
||||
"""Split a state entity_id into domain, object_id."""
|
||||
return entity_id.split(".", 1)
|
||||
|
||||
|
||||
def valid_entity_id(entity_id: str) -> bool:
|
||||
"""Test if an entity ID is a valid format."""
|
||||
return ENTITY_ID_PATTERN.match(entity_id) is not None
|
||||
|
||||
|
||||
class CoreState(enum.Enum):
|
||||
"""Represent the current state of Home Assistant."""
|
||||
|
||||
|
@ -734,7 +743,7 @@ class Config(object):
|
|||
self.api = None
|
||||
|
||||
# Directory that holds the configuration
|
||||
self.config_dir = get_default_config_dir()
|
||||
self.config_dir = None
|
||||
|
||||
def distance(self: object, lat: float, lon: float) -> float:
|
||||
"""Calculate distance from Home Assistant."""
|
||||
|
@ -743,6 +752,8 @@ class Config(object):
|
|||
|
||||
def path(self, *path):
|
||||
"""Generate path to the file within the config dir."""
|
||||
if self.config_dir is None:
|
||||
raise HomeAssistantError("config_dir is not set")
|
||||
return os.path.join(self.config_dir, *path)
|
||||
|
||||
def as_dict(self):
|
||||
|
|
|
@ -12,7 +12,7 @@ from homeassistant.const import (
|
|||
CONF_ALIAS, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, WEEKDAYS,
|
||||
CONF_CONDITION, CONF_BELOW, CONF_ABOVE, SUN_EVENT_SUNSET,
|
||||
SUN_EVENT_SUNRISE, CONF_UNIT_SYSTEM_IMPERIAL, CONF_UNIT_SYSTEM_METRIC)
|
||||
from homeassistant.helpers.entity import valid_entity_id
|
||||
from homeassistant.core import valid_entity_id
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.util import slugify
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""An abstract class for entities."""
|
||||
import logging
|
||||
import re
|
||||
|
||||
from typing import Any, Optional, List, Dict
|
||||
|
||||
|
@ -19,9 +18,6 @@ _OVERWRITE = {} # type: Dict[str, Any]
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# Pattern for validating entity IDs (format: <domain>.<entity>)
|
||||
ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
|
||||
|
||||
|
||||
def generate_entity_id(entity_id_format: str, name: Optional[str],
|
||||
current_ids: Optional[List[str]]=None,
|
||||
|
@ -45,16 +41,6 @@ def set_customize(customize: Dict[str, Any]) -> None:
|
|||
_OVERWRITE = {key.lower(): val for key, val in customize.items()}
|
||||
|
||||
|
||||
def split_entity_id(entity_id: str) -> List[str]:
|
||||
"""Split a state entity_id into domain, object_id."""
|
||||
return entity_id.split(".", 1)
|
||||
|
||||
|
||||
def valid_entity_id(entity_id: str) -> bool:
|
||||
"""Test if an entity ID is a valid format."""
|
||||
return ENTITY_ID_PATTERN.match(entity_id) is not None
|
||||
|
||||
|
||||
class Entity(object):
|
||||
"""An abstract class for Home Assistant entities."""
|
||||
|
||||
|
|
|
@ -37,11 +37,6 @@ class TestHelpersEntity(unittest.TestCase):
|
|||
state = self.hass.states.get(self.entity.entity_id)
|
||||
self.assertTrue(state.attributes.get(ATTR_HIDDEN))
|
||||
|
||||
def test_split_entity_id(self):
|
||||
"""Test split_entity_id."""
|
||||
self.assertEqual(['domain', 'object_id'],
|
||||
entity.split_entity_id('domain.object_id'))
|
||||
|
||||
def test_generate_entity_id_requires_hass_or_ids(self):
|
||||
"""Ensure we require at least hass or current ids."""
|
||||
fmt = 'test.{}'
|
||||
|
|
|
@ -25,6 +25,15 @@ from tests.common import get_test_home_assistant
|
|||
PST = pytz.timezone('America/Los_Angeles')
|
||||
|
||||
|
||||
class TestMethods(unittest.TestCase):
|
||||
"""Test the Home Assistant helper methods."""
|
||||
|
||||
def test_split_entity_id(self):
|
||||
"""Test split_entity_id."""
|
||||
self.assertEqual(['domain', 'object_id'],
|
||||
ha.split_entity_id('domain.object_id'))
|
||||
|
||||
|
||||
class TestHomeAssistant(unittest.TestCase):
|
||||
"""Test the Home Assistant core classes."""
|
||||
|
||||
|
@ -442,28 +451,19 @@ class TestConfig(unittest.TestCase):
|
|||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.config = ha.Config()
|
||||
|
||||
def test_config_dir_set_correct(self):
|
||||
"""Test config dir set correct."""
|
||||
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||
else os.path.expanduser('~')
|
||||
self.assertEqual(os.path.join(data_dir, ".homeassistant"),
|
||||
self.config.config_dir)
|
||||
self.assertIsNone(self.config.config_dir)
|
||||
|
||||
def test_path_with_file(self):
|
||||
"""Test get_config_path method."""
|
||||
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||
else os.path.expanduser('~')
|
||||
self.assertEqual(os.path.join(data_dir, ".homeassistant", "test.conf"),
|
||||
self.config.config_dir = '/tmp/ha-config'
|
||||
self.assertEqual("/tmp/ha-config/test.conf",
|
||||
self.config.path("test.conf"))
|
||||
|
||||
def test_path_with_dir_and_file(self):
|
||||
"""Test get_config_path method."""
|
||||
data_dir = os.getenv('APPDATA') if os.name == "nt" \
|
||||
else os.path.expanduser('~')
|
||||
self.assertEqual(
|
||||
os.path.join(data_dir, ".homeassistant", "dir", "test.conf"),
|
||||
self.config.path("dir", "test.conf"))
|
||||
self.config.config_dir = '/tmp/ha-config'
|
||||
self.assertEqual("/tmp/ha-config/dir/test.conf",
|
||||
self.config.path("dir", "test.conf"))
|
||||
|
||||
def test_as_dict(self):
|
||||
"""Test as dict."""
|
||||
|
|
|
@ -10,7 +10,8 @@ import homeassistant.components.http as http
|
|||
from homeassistant.const import HTTP_HEADER_HA_AUTH, EVENT_STATE_CHANGED
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from tests.common import get_test_instance_port, get_test_home_assistant
|
||||
from tests.common import (
|
||||
get_test_instance_port, get_test_home_assistant, get_test_config_dir)
|
||||
|
||||
API_PASSWORD = "test1234"
|
||||
MASTER_PORT = get_test_instance_port()
|
||||
|
@ -52,6 +53,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
|
||||
# Start slave
|
||||
slave = remote.HomeAssistant(master_api)
|
||||
slave.config.config_dir = get_test_config_dir()
|
||||
bootstrap.setup_component(
|
||||
slave, http.DOMAIN,
|
||||
{http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD,
|
||||
|
|
Loading…
Reference in New Issue