From fbb18f12dbf2158b126fe6223a9beecd5420ee84 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 13 May 2020 03:57:01 -0700 Subject: [PATCH] Add some supervisor improvements (#522) * Add some supervisor improvements * Clarify title --- docs/supervisor.md | 47 +++++++++--------- docs/supervisor/developing.md | 38 +++++++------- .../en/architecture/ha_architecture_2020.png | Bin 0 -> 18651 bytes 3 files changed, 45 insertions(+), 40 deletions(-) create mode 100644 static/img/en/architecture/ha_architecture_2020.png diff --git a/docs/supervisor.md b/docs/supervisor.md index eeec4c08..0594167c 100644 --- a/docs/supervisor.md +++ b/docs/supervisor.md @@ -3,29 +3,30 @@ title: Home Assistant Supervisor sidebar_label: Introduction --- -Architecture Overview of Home Assistant -## Host Control (HC) + -This is a daemon running on the host machine that allows the supervisor to control certain aspects of the host OS: - -- Power cycle (restart, turn off) -- Manage network settings -- Local updates - -## Host - -Our pre-build images are based on [Home Assistant Operating System] which is based on [BuildRoot]. Any Linux machine can be turned into a Home Assistant host by running [the installer][linux]. - -## Supervisor - -The supervisor offers an API to manage the host and running the Docker containers. - -## Configuration panel - -The configuration panel lives inside the supervisor but is accessible via the Home Assistant user interface. The configuration panel allows the user to manage the installation. - -[HassOS]: https://github.com/home-assistant/operating-system -[BuildRoot]: https://buildroot.org/ -[linux]: https://www.home-assistant.io/hassio/installation/#alternative-install-on-generic-linux-server +- **Home Assistant Core**: home automation platform +- **Add-ons**: extra applications that the user wants to run on their server +- **DNS**: allows core and add-ons to communicate among one another +- **Audio**: allows core and add-ons to play audio +- **mDNS**: help discover and connect to devices and services in the network +- **Supervisor**: manages all parts of the system and keeps it up to date +- **Docker**: container service to run applications. +- **Operating System**: Linux based operating system +- **D-Bus**: communication system to control parts of the operating system like the network manager diff --git a/docs/supervisor/developing.md b/docs/supervisor/developing.md index 03bb61f1..be03f56a 100644 --- a/docs/supervisor/developing.md +++ b/docs/supervisor/developing.md @@ -1,50 +1,54 @@ --- -title: "Home Assistant Supervisor <> Core/Frontend development" +title: "Develop Supervisor integration in Core & Frontend" sidebar_label: "Developing" --- -These steps will help you connect your local Home Assistant to a remote Supervisor instance. You can then make changes locally to either the Hass.io integration or the frontend and test it out against a real instance. +These instructions are for setting up Home Assistant Core to interact with a development or remote supervisor. This allows you to develop the `hassio` integration and the Supervisor frontend with a real/development Supervisor instance. -For this guide, we're going to assume that you have an Home Assistant instance up and running. If you don't, you can use the generic installation method to install it inside a [virtual machine](https://github.com/home-assistant/hassio-build/tree/master/install#install-hassio). +For this guide, we're going to assume that you have a [Home Assistant Core development environment](development_environment.md) set up. -## API Access +## Supervisor API Access -To develop for the frontend, we're going to need API access to the supervisor. +To develop for the frontend, we're going to need API access to the supervisor. This API is protected by a token that we can extract using a special add-on. - Add our developer Add-on repository: - Install the Add-on "Remote API proxy" +- Click Start +- The token will be printed in the logs -For some API commands you need explicit the Home Assistant API token, but 99% of the functionality work with `Remote API proxy`. This token change sometimes but you can read the current legal token on host system with: +The add-on needs to keep running to allow Home Assistant Core to connect. + +The Remote API proxy token has slightly less privileges than Home Assistant Core has in production. To get the actual token with full privileges, you need to SSH into the host system and run: ```shell docker inspect homeassistant | grep HASSIO_TOKEN ``` -## Having Home Assistant connect to remote Supervisor +Note that either token can change after a reboot or update of OS/container. - The connection with the supervisor is hidden inside the host and is only accessible from applications running on the host. So to make it accessible for our Home Assistant instance we will need to route the connection to our computer running Home Assistant. We're going to do this by forwarding the API with "Remote API proxy" add-on. +## Setting up Home Assistant Core -First, make sure Home Assistant will load the Hass.io integration by adding `hassio:` to your `configuration.yaml` file. Next, we will need to tell the local Home Assistant instance how to connect to the remote Supervisor instance. We do this by setting the `HASSIO` and `HASSIO_TOKEN` environment variables when starting Home Assistant. Note that the `HASSIO` value is not the same as the one that we saw above and the `HASSIO_TOKEN` is available inside log output of "Remote API Add-on" (This changes every restart of the add-on!). +To configure Home Assistant Core to connect to a remote supervisor, set the following environment variables when starting Home Assistant: + +- `HASSIO`: Set to the IP of the machine running Home Assnstaint and port 80 (the API proxy add-on) +- `HASSIO_TOKEN`: Set this to the token that you exracted in the previous step ```shell -HASSIO=:80 HASSIO_TOKEN= hass +HASSIO=192.168.1.100:80 HASSIO_TOKEN=abcdefghj1234 hass ``` Voila. Your local Home Assistant installation will now connect to a remote Hass.io instance. ## Frontend development -:::tip -This requires Home Assistant 0.71 or later. -::: - -We need a couple more steps to do frontend development. First, make sure you have a Home Assistant frontend development set up ([instructions](frontend_index.md)). +To do frontend development you need to have a [Home Assistant frontend development environment](frontend_index.md) set up. Update the Hass.io component configuration in your `configuration.yaml` to point at the frontend repository: ```yaml # configuration.yaml hassio: + # Example path. Change it to where you have checked out the frontend repository development_repo: /home/paulus/dev/hass/frontend ``` @@ -55,6 +59,6 @@ cd hassio script/develop ``` -Now start Home Assistant as discussed in the previous section and it will now connect to the remote Hass.io but show your local frontend. +Now start Home Assistant as discussed in the previous section and it will now connect to the remote Supervisor but load the frontend from your local development environment. -Once you have `script/develop` the Supervisor panel will be rebuilt whenever you make changes to the source files. +While `script/develop` is running, the Supervisor panel will be rebuilt whenever you make changes to the source files. diff --git a/static/img/en/architecture/ha_architecture_2020.png b/static/img/en/architecture/ha_architecture_2020.png new file mode 100644 index 0000000000000000000000000000000000000000..f2122dff4e9573404eab0a08ed859836a676ed5b GIT binary patch literal 18651 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 literal 0 HcmV?d00001