Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
36 changes: 36 additions & 0 deletions homeassistant/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@

ATTR_COMPONENT = "component"

BASE_PLATFORMS = {
"air_quality",
"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",
"notify",
"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 +403,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",
}