Developing Home Assistant Core in a VSCode Devcontainer

Tags: #<Tag:0x00007f7399fc0080>

Developing Home Assistant Core in a VSCode DevContainer

While the official developer documentation makes some references to VSCode devcontainers, there does not appear to be a comprehensive guide for setting it up to develop and debug HA core. I started documenting the steps that worked well for me, then realized it would be best to share back with the community in a place where it wouldn’t get lost.

I’m suspect that some (much?) of this isn’t best practice or 100% accurate. But I hope that by sharing this, it will encourage others to contribute information about their workflows and we can continue to grow the developer community.

Developing Home Assistant Core in a VSCode Devcontainer

Setting Up the Local Repository

  1. Ensure that git installed on your development wokstation
  2. Visit the Home Assistant Core repository and click Fork.
  3. Open a terminal and set up your local repository
git clone https://github.com/YOUR_GIT_USERNAME/core.git
cd core
git remote add upstream https://github.com/home-assistant/core.git
  1. Create a new feature branch that tracks the dev branch in
git checkout -b my_dev_branch --track origin/dev
  1. Open the local repository in VSCode

Configuring HomeAssistant

By default, the devcontainer will create the config directory inside the container if it doesn’t already exist. Optionally, you can override this by bind mounting a config directory from your local filesystem, which can be helpful for long-term persistence or swapping in/out different configurations to support development.

To do this, include a list of mounts inside /.devcontainer/devcontainer.json:

  "mounts": [
    // Custom configuration directory
    "source=${localEnv:HOME}/path/to/config,target=${containerWorkspaceFolder}/config,type=bind",
  ]

If these mounts are modified, then the devcontainer must to be rebuilt

  • Press F1, and enter Remote-Containers: Rebuild Container

See https://code.visualstudio.com/docs/remote/containers-advanced#_adding-another-local-file-mount for more information.

Running HomeAssistant

  1. Open the the local repository in VSCode

  2. Accept the prompt to “Reopen in Container”

  3. Start HA in the container via the menu options:

    Terminal | Run Task... | Preview

  4. Open HA in a web browser at http://localhost:8123

Keeping Code Up To Date

This is adapted from https://developers.home-assistant.io/docs/development_catching_up

The following commands will keep your local feature branch up-to-date with HomeAssistant’s official dev branch.
Reminder: upstream is the official HA repository, origin is your remote repository that was forked from it

  • Switch to a local feature branch
  • Pull the latest commits from a HA’s upstream/dev branch
  • Replay the upstream commits to the local branch, then re-apply local changes
  • Push the combined commits back to the forked repository on GitHub
git checkout my_dev_branch
git fetch upstream dev
git rebase upstream/dev
git push origin --force

Debugging HomeAssistant

Set up HomeAssistant’s Remote Python Debugger

Add the following to /config/configuration.yaml:

debugpy:
  start: true
  wait: true

See https://www.home-assistant.io/integrations/debugpy/ for more information.

Configure the VSCode Debugger

Insert the following debug configurations into /.vscode/launch.json:

{
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            // Example of attaching to local devcontainer
            "name": "HomeAssistant: Attach to Local Devcontainer",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/workspaces/${workspaceFolderBasename}"
                }
            ],
        },
        {
            // For attaching to a remote Production server
            // Update host as needed
            // HA code is located at /usr/src/homeassistant in a Supervised install
            "name": "HomeAssistant: Attach to Remote",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "homeassistant.local",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/usr/src/homeassistant"
                }
            ],
        }
    ]
}

Start Debugging

  1. Ensure that the HA devcontainer is running (Terminal | Run Task... | Preview)
  2. Switch to the VSCode Debugger view
  3. Select the appropriate debug configuration from the dropdown
  4. Start the debugger

Debugging Custom Components and Libraries

When developing custom components or libraries that exist in other local respoitories on your development machine, the easiest way to incorporate these into HomeAssistant is to bind mount those repositories into HA’s config directory.

To do this, include a list of mounts inside /.devcontainer/devcontainer.json, similar to this example:

  "mounts": [
    // Custom configuration directory
    "source=${localEnv:HOME}/path/to/config,target=${containerWorkspaceFolder}/config,type=bind",
    // Custom component
    "source=${localEnv:HOME}/path/to/custom_repo/custom_components/component_name,target=${containerWorkspaceFolder}/config/custom_components/component_name,type=bind",
    // Custom library
    "source=${localEnv:HOME}/path/to/custom_repo/custom_libraries/library_name,target=${containerWorkspaceFolder}/config/custom_libraries/library_name,type=bind",
  ]

Add more bind mounts as needed for your use case.

If these mounts are modified, then the devcontainer must to be rebuilt

  • Press F1, and enter Remote-Containers: Rebuild Container

Custom Components

Custom components are mounted in the container under config/custom_components, which is a HomeAssistant standard.

Custom Libraries

Custom libraries are mounted under config/custom_libraries. Note that custom_libraries is a personal naming preference, and is not prescribed in the HomeAssistant docs.

In order to develop a custom library, HA needs to be started with a custom variant of the Preview task, which invokes the --skip-pip argument as described here: https://developers.home-assistant.io/docs/api_lib_index

Add the following to .vscode/tasks.json

    // This task should be used when developing in custom_libraries.
    // Any time the container is rebuilt, first run the regular Preview task,
    // which installs all HA dependencies.  Then, swap in the custom_requirements
    // by running the following in the terminal:
    // `pip uninstall library_name
    // `pip install -e ./config/custom_libraries/library_name`
    {
      "label": "Preview with Custom Libraries",
      "type": "shell",
      "command": "hass --skip-pip -c ./config",
      "group": {
        "kind": "test",
        "isDefault": true
      },
      "presentation": {
        "reveal": "always",
        "panel": "new"
      },
      "problemMatcher": []
    },

Before starting HA with this modified Preview task, run the normal Preview task, which will install any libraries the via the normal HA boot process.

Terminal | Run Task... | Preview

If overriding a built-in library, go to the terminal and uninstall the built-in one:

pip uninstall library_name

To then enable a custom library, have pip install it from the filesystem. This should be accessible via the bind mount(s) created above.

pip install -e ./config/custom_libraries/library_name

Finally, to ensure that the custom library is used and not automatically overwritten by HomeAssistant at the next boot, stop the ‘normal’ Preview.

Terminal | Terminate Task... then select Preview

Now, to start HomeAssistant with custom libraries enabled, start the custom preview command created above:

Terminal | Run Task... | Preview with Custom Libraries

4 Likes