Dev Integration not appearing in Core

I am trying to develop an custom integration for HA. I have followed the developer docs to setup the dev container env and “Creating your first integration”. I have a blank integration created by the scaffold integration task but am unable to get the integration to appear in the core when i run the “Run Home Assistant Core” task. It does not appear in the cofig/home-assistant.log file however I do see a translation being generated for it.

My apologies if this is answered elsewhere on this form but I have scoured for answers with no success.

post your code, integrations are loaded through the setup methods inside each init and each platform.

I’m not sure what you want to see but here are the init.py and the config_flow.py files. All other files (like manifest.json) are the default from the scaffold auto gen. I just want to be able to see and test my integration before I start making changes. If you would like me to share files differently let me know, I am new to these forms.

Code:

init.py:

The only thing changed from the scaffold is commenting out the New_NameConfigEntry, and replacing the entry with type ConfigEntry.


from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant

# TODO List the platforms that you want to support.
# For your initial PR, limit it to 1 platform.
_PLATFORMS: list[Platform] = [Platform.LIGHT]

# TODO Create ConfigEntry type alias with API object
# TODO Rename type alias and update all entry annotations
# type New_NameConfigEntry = ConfigEntry["MyApi"]  # noqa: F821


# TODO Update entry annotation
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up myintegration from a config entry."""

    # TODO 1. Create API instance
    # TODO 2. Validate the API connection (and authentication)
    # TODO 3. Store an API object for your platforms to access
    # entry.runtime_data = MyAPI(...)

    await hass.config_entries.async_forward_entry_setups(entry, _PLATFORMS)

    return True


# TODO Update entry annotation
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Unload a config entry."""
    return await hass.config_entries.async_unload_platforms(entry, _PLATFORMS)

Config_flow.py

Nothing modified here auto generated by the “Create new integration” task.

"""Config flow for the myitegration integration."""

from __future__ import annotations

import logging
from typing import Any

import voluptuous as vol

from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError

from .const import DOMAIN

_LOGGER = logging.getLogger(__name__)

# TODO adjust the data schema to the data that you need
STEP_USER_DATA_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_HOST): str,
        vol.Required(CONF_USERNAME): str,
        vol.Required(CONF_PASSWORD): str,
    }
)


class PlaceholderHub:
    """Placeholder class to make tests pass.

    TODO Remove this placeholder class and replace with things from your PyPI package.
    """

    def __init__(self, host: str) -> None:
        """Initialize."""
        self.host = host

    async def authenticate(self, username: str, password: str) -> bool:
        """Test if we can authenticate with the host."""
        return True


async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]:
    """Validate the user input allows us to connect.

    Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.
    """
    # TODO validate the data can be used to set up a connection.

    # If your PyPI package is not built with async, pass your methods
    # to the executor:
    # await hass.async_add_executor_job(
    #     your_validate_func, data[CONF_USERNAME], data[CONF_PASSWORD]
    # )

    hub = PlaceholderHub(data[CONF_HOST])

    if not await hub.authenticate(data[CONF_USERNAME], data[CONF_PASSWORD]):
        raise InvalidAuth

    # If you cannot connect:
    # throw CannotConnect
    # If the authentication is wrong:
    # InvalidAuth

    # Return info that you want to store in the config entry.
    return {"title": "Name of the device"}


class ConfigFlow(ConfigFlow, domain=DOMAIN):
    """Handle a config flow for myitegration."""

    VERSION = 1
    MINOR_VERSION = 1

    async def async_step_user(
        self, user_input: dict[str, Any] | None = None
    ) -> ConfigFlowResult:
        """Handle the initial step."""
        errors: dict[str, str] = {}
        if user_input is not None:
            try:
                info = await validate_input(self.hass, user_input)
            except CannotConnect:
                errors["base"] = "cannot_connect"
            except InvalidAuth:
                errors["base"] = "invalid_auth"
            except Exception:
                _LOGGER.exception("Unexpected exception")
                errors["base"] = "unknown"
            else:
                return self.async_create_entry(title=info["title"], data=user_input)

        return self.async_show_form(
            step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
        )


class CannotConnect(HomeAssistantError):
    """Error to indicate we cannot connect."""


class InvalidAuth(HomeAssistantError):
    """Error to indicate there is invalid auth."""

I’m running into a similar issue.

First of all, I made sure I added my integration domain to configuration.yaml. My integration setup started showing up in logs. However, integration still doesn’t show up if I use “+ Add Integration” UI. Is there an a fixed reference list of these integrations?

Run python3 -m script.hassfest.

It will read your manifest.json file and insert your integration into /homeassistant/generated/integrations.json.

2 Likes

I found this post for similar reason of OP.

After creating the integration, my patience was gradually killed by the tons of required-to-fix TODOs before my integration could run in HA.

Maybe an alternative template integration that just works would make beginners’ life a lot easier. We can fix the TODOs later and realize if a step was wrong immediately if the integration stopped working after change.

Just a humble suggestion after my half day struggling.

The dev environment is designed around adding core integrations, which makes sense for people working on core who were also the people who wrote the developer docs and made the tooling. Having a relatively high bar makes sense to land something in core. If you’re developing for your own purposes it’s probably not going into core, or even if you intend it to eventually, you’ll probably want to first start with it as a custom_component.

What I just did to get started was this(hopefully others find it helpful):

  1. Setup dev environment as described in the docs, I’m not sure that forking is necessary you could probably get away with just doing the main repo, but I had already forked so I used it.

  2. Setup a repo just for your integration, I found this guide very helpful, but it is 5 years old and some things have changed.

  • The most important is you’ll want to use pytest-homeassistant-custom-component instead of pytest-homeassistant in requirements_test.txt
  • hacs.json format has changed as well, so read the latest hacs docs and update accordingly
  • if you want the pre-commit tasks I’d use whatever is the latest in ha_core as a starter but this is totally optional.
  1. Once you’ve setup your integration repo clone your integration repo somewhere to your local disk, and setup your integration dev venv for running unit tests. Note: you’ll want to use whatever version of python is currently supported by HA. As of today that’s 3.13 and 3.14 I think, you’ll probably need to install these see here

    python3.x -m venv .venv
    source .venv/bin/activate
    python -m pip install --upgrade pip
    python -m pip install -r requirements_test.txt
    
  2. Then from the ha_core dev environment modify .devcontainer/devcontainer.json to add a mount within the dev environment to your custom integration something like below(modifying the source path as needed based on where you put the code):

    "mounts": [
        "source=${localEnv:HOME}/[YOUR PROJECT]/custom_components,target=/workspaces/ha_core/config/custom_components,type=bind"
      ],
    
  3. vscode will prompt you to rebuild the container, but if it doesn’t or you closed the prompt make sure you saved the change then goto the command pallete and run Dev Container: Rebuild Container manually.

  4. If everything went right you should see your integration code in /workspaces/ha_core/config/custom_components just use the command pallete to Run Task: Run Home Assistant Core as described in the dev docs, and you should be good to go. You’ll know it worked because you’ll see a warning like

    WARNING: We found a custom integration [your integration] which has not been tested by Home Assistant...
    

If you want to run unit tests you’ll do that from the .venv you created on your local disk. If you used the scaffold script described in the dev docs(as I did) you’ll need to make a few changes to the tests to get them to work:

  • In conftest.py you’ll need to add
    @pytest.fixture(autouse=True)
    def auto_enable_custom_integrations(enable_custom_integrations):
        """Dunno what this is for but it's required."""
        return
    
  • You’ll need to replace any references to components with custom_components
  • And replace any imports from tests.common to pytest_homeassistant_custom_component.common

When you’re ready to actually start using it on your real instance then you can just install it with HACS.