Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions homeassistant/components/device_tracker/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def type(self):

async def async_setup_legacy(self, hass, tracker, discovery_info=None):
"""Set up a legacy platform."""
LOGGER.info("Setting up %s.%s", DOMAIN, self.type)
LOGGER.info("Setting up %s.%s", DOMAIN, self.name)
try:
scanner = None
setup = None
Expand All @@ -248,18 +248,21 @@ async def async_setup_legacy(self, hass, tracker, discovery_info=None):
else:
raise HomeAssistantError("Invalid legacy device_tracker platform.")

if setup:
hass.config.components.add(f"{DOMAIN}.{self.name}")

if scanner:
async_setup_scanner_platform(
hass, self.config, scanner, tracker.async_see, self.type
)
return

if not setup:
LOGGER.error("Error setting up platform %s", self.type)
LOGGER.error("Error setting up platform %s %s", self.type, self.name)
return

except Exception: # pylint: disable=broad-except
LOGGER.exception("Error setting up platform %s", self.type)
LOGGER.exception("Error setting up platform %s %s", self.type, self.name)


async def async_extract_config(hass, config):
Expand Down
9 changes: 3 additions & 6 deletions homeassistant/components/websocket_api/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from homeassistant.helpers.event import TrackTemplate, async_track_template_result
from homeassistant.helpers.service import async_get_all_descriptions
from homeassistant.loader import IntegrationNotFound, async_get_integration
from homeassistant.setup import async_get_loaded_integrations

from . import const, decorators, messages

Expand Down Expand Up @@ -215,13 +216,9 @@ def handle_get_config(hass, connection, msg):
@decorators.async_response
async def handle_manifest_list(hass, connection, msg):
"""Handle integrations command."""
loaded_integrations = async_get_loaded_integrations(hass)
integrations = await asyncio.gather(
*[
async_get_integration(hass, domain)
for domain in hass.config.components
# Filter out platforms.
if "." not in domain
]
*[async_get_integration(hass, domain) for domain in loaded_integrations]
)
connection.send_result(
msg["id"], [integration.manifest for integration in integrations]
Expand Down
34 changes: 34 additions & 0 deletions homeassistant/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@

ATTR_COMPONENT = "component"

BASE_PLATFORMS = {
"alarm_control_panel",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

air_quality is missing and notify too even though it isn't an entity component.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit annoying that we need to remember to extend this list when we add a new base entity integration. Could we extend the manifest for this purpose? @balloob?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

air_quality is missing and notify too even though it isn't an entity component.

Good catch. Will add them.

"binary_sensor",
"climate",
"cover",
"device_tracker",
"fan",
"humidifier",
"image_processing",
"light",
"lock",
"media_player",
"remote",
"scene",
"sensor",
"switch",
"vacuum",
"water_heater",
}

DATA_SETUP_DONE = "setup_done"
DATA_SETUP_STARTED = "setup_started"
DATA_SETUP = "setup_tasks"
Expand Down Expand Up @@ -381,3 +401,17 @@ async def loaded_event(event: core.Event) -> None:
await when_setup()

unsub = hass.bus.async_listen(EVENT_COMPONENT_LOADED, loaded_event)


@core.callback
def async_get_loaded_integrations(hass: core.HomeAssistant) -> set:
"""Return the complete list of loaded integrations."""
integrations = set()
for component in hass.config.components:
if "." not in component:
integrations.add(component)
continue
domain, platform = component.split(".", 1)
if domain in BASE_PLATFORMS:
integrations.add(platform)
return integrations
19 changes: 2 additions & 17 deletions script/hassfest/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path

from homeassistant.requirements import DISCOVERY_INTEGRATIONS
from homeassistant.setup import BASE_PLATFORMS

from .model import Integration

Expand Down Expand Up @@ -107,7 +108,6 @@ def visit_Attribute(self, node):
"onboarding",
"persistent_notification",
"person",
"remote",
"script",
"shopping_list",
"sun",
Expand All @@ -118,22 +118,7 @@ def visit_Attribute(self, node):
"websocket_api",
"zone",
# Entity integrations with platforms
"alarm_control_panel",
"binary_sensor",
"climate",
"cover",
"device_tracker",
"fan",
"humidifier",
"image_processing",
"light",
"lock",
"media_player",
"scene",
"sensor",
"switch",
"vacuum",
"water_heater",
*BASE_PLATFORMS,
# Other
"mjpeg", # base class, has no reqs or component to load.
"stream", # Stream cannot install on all systems, can be imported without reqs.
Expand Down
18 changes: 18 additions & 0 deletions tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,21 @@ async def test_integration_disabled(hass, caplog):
result = await setup.async_setup_component(hass, "test_component1", {})
assert not result
assert disabled_reason in caplog.text


async def test_async_get_loaded_integrations(hass):
"""Test we can enumerate loaded integations."""
hass.config.components.add("notbase")
hass.config.components.add("switch")
hass.config.components.add("notbase.switch")
hass.config.components.add("myintegration")
hass.config.components.add("device_tracker")
hass.config.components.add("device_tracker.other")
hass.config.components.add("myintegration.light")
assert setup.async_get_loaded_integrations(hass) == {
"other",
"switch",
"notbase",
"myintegration",
"device_tracker",
}