10 |
11 | [rob]: https://github.com/rob-smallshire
12 |
--------------------------------------------------------------------------------
/docs/frontend/custom-ui/registering-resources.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Registering Resources"
3 | ---
4 |
5 | Resources can be registered from the "Resources" tab of the Lovelace Configuration UI.
6 |
7 | 
8 |
9 | This tab is only available when the active user's profile has "advanced mode" enabled.
10 |
11 | 
12 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Generate",
6 | "type": "shell",
7 | "command": "yarn build",
8 | "group": {
9 | "kind": "build",
10 | "isDefault": true
11 | }
12 | },
13 | {
14 | "label": "Preview",
15 | "type": "shell",
16 | "command": "yarn start",
17 | "group": {
18 | "kind": "test",
19 | "isDefault": true,
20 | }
21 | },
22 | ]
23 | }
--------------------------------------------------------------------------------
/docs/api/native-app-integration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Native App Integration"
3 | sidebar_label: "Introduction"
4 | ---
5 |
6 | This guide describes how to build a native Home Assistant app that communicates with Home Assistant and offers a seamless integration. Below is a list of the things that we will discuss in this guide.
7 |
8 | - Allow the user to establish a connection and authenticate with their own Home Assistant instance.
9 | - Send location and device info back to Home Assistant.
10 | - Call services, fire events and render templates.
11 | - A view to control the house via an authenticated webview.
12 |
--------------------------------------------------------------------------------
/docs/development_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Starting with Development"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | Home Assistant is built from the ground up to be easily extensible using integrations. In this section, we're focusing on how to develop integrations.
7 |
8 | Before you start, make sure that you have read up on the [Home Assistant architecture](architecture_index.md) so that you are familiar with the concepts that make up Home Assistant.
9 |
10 | If you run into trouble following this documentation, don't hesitate to join our #devs_core channel on [Discord](https://www.home-assistant.io/join-chat/).
11 |
--------------------------------------------------------------------------------
/docs/api/native-app-integration/webview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Authenticated Webview"
3 | ---
4 |
5 | Your application already asked the user to authenticate. This means that your app should not ask the user to authenticate again when they open the Home Assistant UI.
6 |
7 | To make this possible, the Home Assistant UI supports [external authentication](frontend/external-authentication.md). This allows your app to provide hooks so that the frontend will ask your app for access tokens.
8 |
9 | Home Assistant also supports further integration between frontend and app via an [external bus](frontend/external-bus.md).
10 |
11 | Note that this feature requires a direct connection to the instance.
12 |
--------------------------------------------------------------------------------
/docs/device_automation_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Device Automations"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | Device Automations provide users with a device-centric layer on top of the core concepts of Home Assistant. When creating automations, users no longer have to deal with core concepts like states and events. Instead, they will be able to pick a device and then pick from a list of pre-defined triggers, conditions and actions.
7 |
8 | Integrations can hook into this system by exposing functions to generate the pre-defined triggers, conditions, actions and having functions that can listen for the triggers, check the condition and execute the action.
9 |
10 | Device automations are not exposing extra functionality but are a way for users to not have to learn new concepts. Device automations are using events, state and service helpers under the hood.
11 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | # Settings in the [build] context are global and are applied to all contexts
2 | # unless otherwise overridden by more specific contexts.
3 | # See: https://docs.netlify.com/configure-builds/file-based-configuration
4 | [build]
5 | # Directory to change to before starting a build.
6 | # This is where we will look for package.json/.nvmrc/etc.
7 | base = ""
8 |
9 | # Directory (relative to root of your repo) that contains the deploy-ready
10 | # HTML files and assets generated by the build. If a base directory has
11 | # been specified, include it in the publish directory path.
12 | publish = "build"
13 |
14 | # Default build command.
15 | command = "yarn build"
16 |
17 | [[redirects]]
18 | from = "/docs/en/next/*"
19 | to = "/docs/:splat"
20 | status = 301
21 | force = true
22 |
23 | [[redirects]]
24 | from = "/docs/en/*"
25 | to = "/docs/:splat"
26 | status = 301
27 | force = true
28 |
--------------------------------------------------------------------------------
/blog/2018-08-13-deprecating-remote-package.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Deprecating homeassistant.remote
7 | ---
8 |
9 | With the release of Home Assistant 0.76, the functions in the `homeassistant.remote` package will be deprecated and will be removed in 0.77. This package contains functions to call the Home Assistant REST API in a non-async way.
10 |
11 | The reason for removing is two-fold: first the code is not being used inside Home Assistant and thus should not be part of Home Assistant. Second, it is not compatible with the new auth system nor do we want to spend the time to make it compatible.
12 |
13 | If you want to keep using the methods in `homeassistant.remote`, feel free to copy [the code](https://github.com/home-assistant/home-assistant/blob/0.75.0/homeassistant/remote.py) to your own project.
14 |
--------------------------------------------------------------------------------
/docs/api/supervisor/examples.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Examples"
3 | ---
4 |
5 | Examples on how to interface against the supervisor API.
6 |
7 | ## Get network information with cURL
8 |
9 | ```bash
10 | curl -sSL -H "Authorization: Bearer $SUPERVISOR_TOKEN" http://supervisor/network/info
11 | ```
12 |
13 | **response:**
14 |
15 | ```json
16 | {
17 | "result": "ok",
18 | "data": {
19 | "interfaces": {
20 | "eth0": {
21 | "ip_address": "192.168.1.100/24",
22 | "gateway": "192.168.1.1",
23 | "id": "Wired connection 1",
24 | "type": "802-3-ethernet",
25 | "nameservers": ["192.168.1.1"],
26 | "method": "static",
27 | "primary": true
28 | }
29 | }
30 | }
31 | }
32 | ```
33 |
34 | ## Ping the supervisor
35 |
36 | ```bash
37 | curl -sSL http://supervisor/ping
38 | ```
39 |
40 | **response:**
41 |
42 | ```json
43 | {
44 | "result": "ok",
45 | "data": {}
46 | }
47 | ```
--------------------------------------------------------------------------------
/docs/intent_conversation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Registering sentences"
3 | ---
4 |
5 | The conversation component handles incoming commands from the frontend and converts them to intents. It does this based on registered sentences.
6 |
7 | As a component, you can register sentences with the conversation component to allow it to be remote controlled. Refer to named slots by putting the slot name between curly braces: `{item}`. Use square brackets around (partial) words to mark them as optional.
8 |
9 | Example code:
10 |
11 | ```python
12 | async def async_setup(hass, config):
13 | hass.components.conversation.async_register(
14 | "MyCoolIntent",
15 | ["I think that {object} is [very] cool", "Nothing is cooler than {object}"],
16 | )
17 | ```
18 |
19 | If a sentence like "I think that beer is cool" comes in, the conversation component will generate an intent of type `MyCoolIntent` and with 1 slot, named `object` and value `beer`.
20 |
--------------------------------------------------------------------------------
/docs/supervisor/debugging.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Debugging the Home Assistant Supervisor"
3 | sidebar_label: Debugging
4 | ---
5 |
6 | The following debug tips and tricks are for developers who are running the Home Assistant image and are working on the base image. If you use the generic Linux installer script, you should be able to access your host and logs as per your host.
7 |
8 | ## Debug Supervisor
9 |
10 | Visual Studio Code config:
11 |
12 | ```json
13 | {
14 | "version": "0.2.0",
15 | "configurations": [
16 | {
17 | "name": "Supervisor remote debug",
18 | "type": "python",
19 | "request": "attach",
20 | "port": 33333,
21 | "host": "IP",
22 | "pathMappings": [
23 | {
24 | "localRoot": "${workspaceFolder}",
25 | "remoteRoot": "/usr/src/hassio"
26 | }
27 | ]
28 | }
29 | ]
30 | }
31 | ```
32 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "developers.home-assistant",
3 | "dockerFile": "Dockerfile",
4 | "appPort": [
5 | 3000
6 | ],
7 | "postCreateCommand": "yarn install",
8 | "extensions": [
9 | "davidanson.vscode-markdownlint",
10 | "editorconfig.editorconfig",
11 | "streetsidesoftware.code-spell-checker",
12 | "yzhang.markdown-all-in-one"
13 | ],
14 | "settings": {
15 | "editor.rulers": [80, 100, 120],
16 | "editor.renderWhitespace": "boundary",
17 | "errorLens.gutterIconsEnabled": true,
18 | "errorLens.addAnnotationTextPrefixes": false,
19 | "errorLens.enabledDiagnosticLevels": [
20 | "error",
21 | "warning"
22 | ],
23 | "terminal.integrated.shell.linux": "/bin/bash",
24 | "[markdown]":{
25 | "editor.wordWrap": "wordWrapColumn",
26 | "editor.wordWrapColumn": 80,
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "developers-home-assistant-v-2",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "by-node-env",
7 | "start:development": "docusaurus start",
8 | "start:devcontainer": "docusaurus start --poll --host 0.0.0.0",
9 | "build": "docusaurus build",
10 | "swizzle": "docusaurus swizzle",
11 | "deploy": "docusaurus deploy"
12 | },
13 | "dependencies": {
14 | "by-node-env": "^2.0.1",
15 | "@docusaurus/preset-classic": "^2.0.0-alpha.69",
16 | "@docusaurus/core": "^2.0.0-alpha.69",
17 | "classnames": "^2.2.6",
18 | "react": "^16.14.0",
19 | "react-dom": "^16.14.0"
20 | },
21 | "resolutions": {
22 | "@docusaurus/core/**/selfsigned": "1.10.8",
23 | "@docusaurus/preset-classic/**/fbjs": "2.0.0"
24 | },
25 | "browserslist": {
26 | "production": [
27 | ">0.2%",
28 | "not dead",
29 | "not op_mini all"
30 | ],
31 | "development": [
32 | "last 1 chrome version",
33 | "last 1 firefox version",
34 | "last 1 safari version"
35 | ]
36 | }
37 | }
--------------------------------------------------------------------------------
/src/pages/styles.module.css:
--------------------------------------------------------------------------------
1 | /**
2 | * CSS files with the .module.css suffix will be treated as CSS modules
3 | * and scoped locally.
4 | */
5 |
6 | .heroBanner {
7 | padding: 4rem 0;
8 | text-align: center;
9 | position: relative;
10 | overflow: hidden;
11 | }
12 |
13 | .heroTitle {
14 | font-size: 3rem;
15 | color: #ffffff;
16 | }
17 |
18 | .heroTagline {
19 | font-size: 1.4rem;
20 | color: #ffffff;
21 | }
22 |
23 | .heroLogo {
24 | max-height: 16em;
25 | }
26 |
27 | a.heroText{
28 | color: #ffffff;
29 | }
30 |
31 | @media screen and (max-width: 966px) {
32 | .heroBanner {
33 | padding: 2rem;
34 | }
35 |
36 | .heroTitle {
37 | font-size: 2.4rem;
38 | }
39 |
40 | .heroTagline {
41 | font-size: 1rem;
42 | font-weight: bold;
43 | }
44 | }
45 |
46 | .buttons {
47 | display: flex;
48 | align-items: center;
49 | justify-content: center;
50 | }
51 |
52 | .features {
53 | display: flex;
54 | align-items: center;
55 | padding: 2rem 0;
56 | width: 100%;
57 | }
58 |
59 | .featureImage {
60 | height: 200px;
61 | width: 200px;
62 | }
63 |
--------------------------------------------------------------------------------
/blog/2020-04-10-translation-handling.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Translations 2.0
7 | ---
8 |
9 | We've migrated our translation scripts in the Home Assisstant Core repository under a single namespace. It can now all be invoked using `python3 -m script.translations`.
10 |
11 | | Old command | New command |
12 | | ------------------------------ | ----------------------------------------- |
13 | | `script/translations_develop` | `python3 -m script.translations develop` |
14 | | `script/translations_upload` | `python3 -m script.translations upload` |
15 | | `script/translations_download` | `python3 -m script.translations download` |
16 | | `script/translations_clean` | `python3 -m script.translations clean` |
17 |
18 | This will help us prepare for our [Translations 2.0 effort](https://github.com/home-assistant/architecture/blob/master/adr/0009-translations-2.0.md) that will clean up translations and make it scale better.
19 |
--------------------------------------------------------------------------------
/.vscode/cSpell.json:
--------------------------------------------------------------------------------
1 | // cSpell Settings
2 | // Contains additional words for our project
3 | {
4 | "version": "0.1",
5 | "language": "en",
6 | "words": [
7 | "arest",
8 | "automations",
9 | "bloomsky",
10 | "bluesound",
11 | "BTLE",
12 | "Denon",
13 | "endconfiguration",
14 | "endraw",
15 | "Etekcity",
16 | "fitbit",
17 | "Flexit",
18 | "geizhals",
19 | "Harman",
20 | "hass",
21 | "Hass.io",
22 | "HassOS",
23 | "hcitool",
24 | "heos",
25 | "hikvision",
26 | "Homematic",
27 | "IBAN",
28 | "icloud",
29 | "kardon",
30 | "macos",
31 | "Modbus",
32 | "Mosquitto",
33 | "nginx",
34 | "ohmconnect",
35 | "Onkyo",
36 | "paulus",
37 | "templating",
38 | "waqi",
39 | "Webhook"
40 | ],
41 | // flagWords - list of words to be always considered incorrect
42 | // This is useful for offensive words and common spelling errors.
43 | // For example "hte" should be "the"
44 | "flagWords": [
45 | "hte",
46 | "asssistant"
47 | ]
48 | }
--------------------------------------------------------------------------------
/docs/development_checklist.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Development Checklist"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | Before you commit any changes, check your work against these requirements:
7 |
8 | - All communication to external devices or services must be wrapped in an external Python library hosted on [pypi](https://pypi.python.org/pypi).
9 | - New dependencies are added to `requirements_all.txt` (if applicable), using `python3 -m script.gen_requirements_all`
10 | - New codeowners are added to `CODEOWNERS` (if applicable), using `python3 -m script.hassfest`
11 | - The `.coveragerc` file is updated to exclude your platform if there are no tests available or your new code uses a third-party library for communication with the device, service, or sensor
12 | - The code is formatted using Black, as per these [guidelines](https://developers.home-assistant.io/blog/2019/07/31/black.html). This can be done running the command `black --fast homeassistant tests`.
13 | - Documentation is developed for [home-assistant.io](https://home-assistant.io/)
14 | - Visit the [website documentation](/documenting.md) for more information about contributing to [home-assistant.io](https://github.com/home-assistant/home-assistant.io).
15 |
--------------------------------------------------------------------------------
/blog/2020-05-08-logos-custom-integrations.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Franck Nijhof
3 | authorURL: https://twitter.com/frenck
4 | authorImageURL: /img/profile/frenck.png
5 | authorTwitter: frenck
6 | title: Logos for custom integrations
7 | ---
8 |
9 | Recently, Home Assistant started to support images & icons for integrations
10 | to show up in the frontend. They look amazing and really brings some color
11 | to the UI of Home Assistant.
12 |
13 | We got a lot of questions lately on how custom integrations (also known as
14 | custom components) can add their images. As of today, that is possible!
15 |
16 | 
17 |
18 | Created a custom integration? Want the logo & icon for your integration to
19 | show up in the Home Assistant frontend? In that case, head over to our
20 | [GitHub brands repository](https://github.com/home-assistant/brands)
21 | to add yours!
22 |
23 | _PS: Did you know you can also add your custom integration to our [Python wheels
24 | repository](https://github.com/home-assistant/wheels-custom-integrations)?
25 | It will make the installation of your custom integration in
26 | Home Assistant lightning fast!_
27 |
--------------------------------------------------------------------------------
/docs/add-ons/repository.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Create an add-on repository"
3 | ---
4 |
5 | An add-on repository can contain one or more add-ons. Each add-on is stored in its own unique folder. To be identified as a repository, the repository must contain a configuration file.
6 |
7 | Check the [Example add-on repository](https://github.com/home-assistant/addons-example) for further details.
8 |
9 | ## Installing a repository
10 |
11 | A user can add a repository by going to the Supervisor panel in Home Assistant, clicking on the store icon in the top right, copy/paste the URL of your repository into the repository textarea and click on **Save**.
12 |
13 | ## Repository configuration
14 |
15 | Each repository is required to contain `repository.json` at the root in the git repository.
16 |
17 | ```json
18 | {
19 | "name": "Name of repository",
20 | "url": "http://www.example/addons",
21 | "maintainer": "HomeAssistant Team "
22 | }
23 | ```
24 |
25 | | Key | Required | Description |
26 | | --- | -------- | ----------- |
27 | | name | yes | Name of the repository
28 | | url | no | Homepage of the repository. Here you can explain the various add-ons.
29 | | maintainer | no | Contact info of the maintainer.
30 |
--------------------------------------------------------------------------------
/docs/internationalization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Internationalization"
3 | ---
4 |
5 | The Home Assistant internationalization project includes preparing platforms and the frontend for localization, as well as the actual translation of localized strings.
6 |
7 | Some components and platforms will have strings that need to be localized specifically for that platform. These strings are managed in the core [home-assistant](https://github.com/home-assistant/core) repository. The Home Assistant backend will serve strings to the clients based on the loaded components in the running instance.
8 |
9 | There are also localizable strings that exist only on the frontend. These strings are managed in the [home-assistant frontend](https://github.com/home-assistant/frontend) repository. These strings are stored with the frontend and don’t depend on the backend configuration.
10 |
11 | | Type | Location |
12 | | ----------------- | -------- |
13 | | Entity states | Core |
14 | | Config flows | Core |
15 | | Options flows | Core |
16 | | Device automation | Core |
17 | | Text in UI | Frontend |
18 |
19 | Our strings are translated by the community using the online translation tool [Lokalise](https://lokalise.co/).
20 |
--------------------------------------------------------------------------------
/blog/2019-07-31-black.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Adopting Black
7 | ---
8 |
9 | Today we have officially adopted the Python code formatting tool [Black](https://black.readthedocs.io). All code has been formatted with Black and all future contributions will be checked to make sure that they have been formatted using Black.
10 |
11 | As part of adopting Black, all style checks in flake8 and pylint have been disabled.
12 |
13 | To make sure that all files are Black when you commit your changes, we are using [`pre-commit`](https://pre-commit.com/). The hook is automatically installed for new dev environments (as part of `script/setup`).
14 |
15 | If you have an existing developer installation, please run inside your virtual environment:
16 |
17 | ```
18 | pip install pre-commit
19 | pre-commit install
20 | ```
21 |
22 | `pre-commit` does not change your files, but merely confirms that the changed files are formatted by Black. We suggest that you set up your editor to automatically format files with Black when you hit save. Instructions for various editors can be found [here](https://github.com/psf/black#editor-integration).
23 |
--------------------------------------------------------------------------------
/blog/2018-05-22-custom-ui-panels-api.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Updates for Custom UI and Custom Panels
7 | ---
8 |
9 | With the release of Home Assistant 0.70, we've migrated the build pipeline for our frontend from being based on HTML imports to ES module imports (more on this later). One of the effects of this is that we're no longer using the `window` object to share classes, data and utilities with other pieces of code.
10 |
11 | This might impact you if you dependend on some of this. Examples are Polymer (`window.Polymer`) or one of our utilitity functions that used to be available as `window.hassUtil`, `window.HAWS` or `window.hassMixins`.
12 |
13 | To give developers time to migrate, we're adding a temporary legacy support layer that will expose some of our internals again on the `window` object. We've already added `window.Polymer`, `window.Polymer.Element` and `window.Polymer.html`. If you're using other specific things from the window object, [please let us know](https://github.com/home-assistant/home-assistant-polymer/issues/1157).
14 |
15 | Th legacy support layer will no longer be included in releases happening after July 2018.
16 |
--------------------------------------------------------------------------------
/docs/core/entity/remote.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Remote Entity
3 | sidebar_label: Remote
4 | ---
5 |
6 | ## Properties
7 |
8 | :::tip
9 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
10 | :::
11 |
12 | | Name | Type | Default | Description
13 | | ---- | ---- | ------- | -----------
14 |
15 | ## Supported Features
16 |
17 | | Constant | Description
18 | | -------- | -----------
19 | | `SUPPORT_LEARN_COMMAND` | Entity allows learning commands from devices.
20 |
21 | ## Methods
22 |
23 | ### Send Command
24 |
25 | ```python
26 | class MyRemote(RemoteEntity):
27 |
28 | def send_command(self, command: Iterable[str], **kwargs):
29 | """Send commands to a device."""
30 |
31 | async def async_send_command(self, command: Iterable[str], **kwargs):
32 | """Send commands to a device."""
33 | ```
34 |
35 | ### Learn Command
36 |
37 | Only implement this method if the flag `SUPPORT_LEARN_COMMAND` is set.
38 |
39 | ```python
40 | class MyRemote(RemoteEntity):
41 |
42 | def learn_command(self, **kwargs):
43 | """Learn a command from a device."""
44 |
45 | async def async_learn_command(self, **kwargs):
46 | """Learn a command from a device."""
47 | ```
48 |
--------------------------------------------------------------------------------
/docs/reproduce_state_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Reproduce State / Scene support"
3 | ---
4 |
5 | Home Assistant has support for scenes. Scenes are a collection of (partial) entity states. When a scene is activated, Home Assistant will try to call the right services to get the specified scenes in their specified state.
6 |
7 | Integrations are responsible for adding support to Home Assistant to be able to call the right services to reproduce the states in a scene.
8 |
9 | ## Adding support
10 |
11 | The quickest way to add reproduce state support to a new integration is by using our built-in scaffold template. From a Home Assistant dev environment, run `python3 -m script.scaffold reproduce_state` and follow the instructions.
12 |
13 | If you prefer to go the manual route, create a new file in your integration folder called `reproduce_state.py` and implement the following method:
14 |
15 | ```python
16 | import asyncio
17 | from typing import Iterable, Optional
18 | from homeassistant.core import Context, State
19 | from homeassistant.helpers.typing import HomeAssistantType
20 |
21 |
22 | async def async_reproduce_states(
23 | hass: HomeAssistantType, states: Iterable[State], context: Optional[Context] = None
24 | ) -> None:
25 | """Reproduce component states."""
26 | # TODO reproduce states
27 | ```
28 |
--------------------------------------------------------------------------------
/docs/frontend.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Home Assistant Frontend"
3 | sidebar_label: "Introduction"
4 | ---
5 |
6 | The Home Assistant frontend allows users to browse and control the state of their house, manage their automations and configure integrations.
7 |
8 | The frontend is designed as a mobile-first experience. It is a progressive web application and offers an app-like experience to our users.
9 |
10 | The Home Assistant frontend needs to be fast. But it also needs to work on a wide range of old devices. To do this, we ship two versions of the frontend:
11 |
12 | - **Latest:** this build is compatible with the two latest versions of evergreen browsers and is optimized to be fast.
13 | - **ES5:** this build is compatible with browsers released in the last 5+ years and is optimized to be compatible.
14 |
15 | A device that runs the latest technology does not also have to be fast. You can buy budget Android phones that run the latest Android version with access to the latest Firefox and Chrome browsers, but with low performance chipset and limited memory. Our latest build needs to run smooth on these devices too.
16 |
17 | For a deep dive into our frontend and its design choices, see [this blog post](/blog/2019/05/22/internet-of-things-and-the-modern-web).
18 |
19 | 
20 |
--------------------------------------------------------------------------------
/blog/2020-04-23-frontend-translations.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Translations for custom Lovelace
7 | ---
8 |
9 | If you are the author of a custom Lovelace card and use translations, please pay attention as the state translation keys have changed.
10 |
11 | Before 0.109, state translations lived under `state..` or `state...` for binary sensors. Starting with version 0.109, these translations are now part of the backend and so they have the key format for backend translations. We have standardized the state format to always include a device class. The device class `_` is reserved as a fallback for entities without a device class.
12 |
13 | | Old | New |
14 | | --------------------------------------- | ------------------------------------------------- |
15 | | `state..` | `component..state._.` |
16 | | `state...` | `component..state..` |
17 |
18 | In future releases, we're planning to migrate state attribute translations to the backend too. We'll publish this on this blog when it happens.
19 |
--------------------------------------------------------------------------------
/docs/internationalization/custom_integration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Custom Component Localization"
3 | ---
4 |
5 | ## Translation Strings
6 |
7 | Unlike localized strings merged in the `home-assistant` repository, custom components cannot take advantage of Lokalise for user-submitted translations. However, custom component authors can still include translations with their components. These will be read from the `translations` directory, adjacent to the component source. They are named `..json`, e.g., for the German translation of a sensor `sensor.de.json`, unless the translation is for the custom component only, in which case the file is named `.json` in the `translations` directory.
8 |
9 | These files follow the same formatting as [backend translation string files](internationalization/core.md), but a copy will exist for each translated language.
10 |
11 | The language codes follow the [BCP47](https://tools.ietf.org/html/bcp47) format. The [frontend translation files](https://github.com/home-assistant/home-assistant-polymer/tree/master/translations) can also be referred to if you are unsure of the correct language code to use.
12 |
13 | To make sure that your translation files are correct, test with our integration validator Hassfest. [Set up instructions here.](https://developers.home-assistant.io/blog/2020/04/16/hassfest)
14 |
--------------------------------------------------------------------------------
/docs/frontend/extending/adding-more-info-dialogs.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Adding more info dialogs"
3 | ---
4 |
5 | Whenever the user taps or clicks on one of the cards, a more info dialog will show. The header of this dialog will be the state card, followed by the history of this entity for the last 24 hours. Below this the more info component is rendered for that entity. The more info component can show more information or allow more ways of control.
6 |
7 |
11 |
12 | The instructions to add a more info dialog are very similar to adding a new card type. This example will add a new more info component for the domain `camera`:
13 |
14 | 1. Add `'camera'` to the array `DOMAINS_WITH_MORE_INFO` in the file [/common/const.ts](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/common/const.ts).
15 | 2. Create the files `more-info-camera.js` in the folder [/dialogs/more-info/controls](https://github.com/home-assistant/home-assistant-polymer/tree/master/src/dialogs/more-info/controls).
16 | 3. Add `import './more-info-camera.js';` to [/dialogs/more-info/controls/more-info-content.js](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/dialogs/more-info/controls/more-info-content.js)
17 |
--------------------------------------------------------------------------------
/docs/intent_handling.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Handling intents"
3 | ---
4 |
5 | Any component can register to handle intents. This allows a single component to handle intents fired from multiple voice assistants.
6 |
7 | A component has to register an intent handler for each type that it wants to handle. Intent handlers have to extend `homeassistant.helpers.intent.IntentHandler`
8 |
9 | ```python
10 | import asyncio
11 | from homeassistant.helpers import intent
12 |
13 | DATA_KEY = "example_key"
14 |
15 |
16 | @asyncio.coroutine
17 | def async_setup(hass, config):
18 | hass.data[DATA_KEY] = 0
19 | intent.async_register(hass, CountInvocationIntent())
20 |
21 |
22 | class CountInvocationIntent(intent.IntentHandler):
23 | """Handle CountInvocationIntent intents."""
24 |
25 | # Type of intent to handle
26 | intent_type = "CountInvocationIntent"
27 |
28 | # Optional. A validation schema for slots
29 | # slot_schema = {
30 | # 'item': cv.string
31 | # }
32 |
33 | @asyncio.coroutine
34 | def async_handle(self, intent_obj):
35 | """Handle the intent."""
36 | intent_obj.hass.data[DATA_KEY] += 1
37 |
38 | response = intent_obj.create_response()
39 | response.async_set_speech(
40 | f"This intent has been invoked {intent_obj.hass.data[DATA_KEY]} times"
41 | )
42 | return response
43 | ```
44 |
--------------------------------------------------------------------------------
/docs/core/entity/air-quality.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Air Quality Entity
3 | sidebar_label: Air Quality
4 | ---
5 |
6 | ## Properties
7 |
8 | :::tip
9 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
10 | :::
11 |
12 | | Name | Type | Default | Description
13 | | ---- | ---- | ------- | -----------
14 | | particulate_matter_2_5 | float | **Required** | The particulate matter 2.5 (<= 2.5 μm) level.
15 | | particulate_matter_10 | float | **Required** | The particulate matter 10 (<= 10 μm) level.
16 | | particulate_matter_0_1 | float | `None` | The particulate matter 0.1 (<= 0.1 μm) level.
17 | | air_quality_index | float | `None` | The Air Quality Index (AQI).
18 | | ozone | float | `None` | The O3 (ozone) level.
19 | | carbon_monoxide | float | `None` | The CO (carbon monoxide) level.
20 | | carbon_dioxide | float | `None` | The CO2 (carbon dioxide) level.
21 | | sulphur_dioxide | float | `None` | The SO2 (sulphur dioxide) level.
22 | | nitrogen_oxide | float | `None` | The N2O (nitrogen oxide) level.
23 | | nitrogen_monoxide | float | `None` | The NO (nitrogen monoxide) level.
24 | | nitrogen_dioxide | float | `None` | The NO2 (nitrogen dioxide) level.
25 | | volatile_organic_compounds | float | `None` | The volatile organic compounds (VOC) level.
26 |
27 | Properties have to follow the units defined in the `unit_system`.
28 |
--------------------------------------------------------------------------------
/docs/core/entity/sensor.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Sensor Entity
3 | sidebar_label: Sensor
4 | ---
5 |
6 | A sensor is a read-only entity that provides some information. Information has a value and optionally, a unit of measurement.
7 |
8 | ## Properties
9 |
10 | :::tip
11 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
12 | :::
13 |
14 | | Name | Type | Default | Description
15 | | ---- | ---- | ------- | -----------
16 | | state | string | **Required** | The value of the sensor.
17 | | unit_of_measurement | string | `None` | The unit of measurement that the sensor is expressed in.
18 | | device_class | string | `None` | Type of sensor.
19 |
20 | ### Available device classes
21 |
22 | If specifying a device class, your sensor entity will need to also return the correct unit of measurement.
23 |
24 | | Type | Unit | Description
25 | | ---- | ---- | -----------
26 | | battery | % | % of battery that is left.
27 | | humidity | % | % of humidity in the air.
28 | | illuminance | lx/lm | Light level.
29 | | signal_strength | dB/dBm | Signal strength.
30 | | temperature | °C/°F | Temperature.
31 | | timestamp | ISO8601 | Timestamp.
32 | | power | W,kW | Power.
33 | | pressure | hPa,mbar | Pressure.
34 | | current | A | Current.
35 | | energy | Wh,kWh | Energy.
36 | | power_factor | % | Power Factor.
37 | | voltage | V | Voltage.
38 |
--------------------------------------------------------------------------------
/docs/supervisor.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Home Assistant Supervisor
3 | sidebar_label: Introduction
4 | ---
5 |
6 | The Supervisor allows the user to manage their Home Assistant installation from Home Assistant. The Supervisor has the following responsibilities:
7 |
8 | - Run Home Assistant Core
9 | - Update Home Assistant Core. Automatically roll back if the update fails.
10 | - Make and restore backups
11 | - Add-ons
12 | - Unified audio system
13 | - Update the Home Assistant operating system (disabled in a Supervised installation)
14 |
15 | ## Architecture
16 |
17 |
19 |
20 |
23 |
24 | - **Home Assistant Core**: home automation platform
25 | - **Add-ons**: extra applications that the user wants to run on their server
26 | - **DNS**: allows core and add-ons to communicate among one another
27 | - **Audio**: allows core and add-ons to play audio
28 | - **mDNS**: help discover and connect to devices and services in the network
29 | - **Supervisor**: manages all parts of the system and keeps it up to date
30 | - **Docker**: container service to run applications.
31 | - **Operating System**: Linux based operating system
32 | - **D-Bus**: communication system to control parts of the operating system like the network manager
33 |
--------------------------------------------------------------------------------
/static/js/api_endpoint.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | // Styles for this element is defined in src/css/custom.css
4 |
5 | export default class ApiEndpoint extends React.Component {
6 | constructor(props){
7 | super(props);
8 | this.state = {
9 | open: false
10 | }
11 | this.toggleInfo = this.toggleInfo.bind(this);
12 | }
13 |
14 | toggleInfo(e){
15 | this.setState({open: !this.state.open})
16 | }
17 |
18 | render() {
19 | return (
20 |
45 | );
46 | }
47 | }
--------------------------------------------------------------------------------
/docs/dev_101_config.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using Config"
3 | ---
4 |
5 | Based on where you are in the code, `config` can mean various things.
6 |
7 | ### On the hass object
8 |
9 | On the hass object it is an instance of the Config class. The Config class contains the users preferred units, the path to the config directory and which components are loaded. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.Config)
10 |
11 | ### Config passed into component setup
12 |
13 | The `config` parameter passed to a component setup is a dictionary containing all of the user supplied configuration. The keys of the dictionary are the component names and the value is another dictionary with the component configuration.
14 |
15 | The object will have already been validated using your `CONFIG_SCHEMA` or `PLATFORM_SCHEMA` if available. If you have defined a `PLATFORM_SCHEMA`, all references to your component (ie `light 2:` etc) will have been changed to be accessible as a list under `config[DOMAIN]`.
16 |
17 | If your configuration file contains the following lines:
18 |
19 | ```yaml
20 | example:
21 | host: paulusschoutsen.nl
22 | ```
23 |
24 | Then in the setup method of your component you will be able to refer to `config['example']['host']` to get the value `paulusschoutsen.nl`.
25 |
26 | ### Passed into platform setup
27 |
28 | The `config` parameter passed to a platform setup function is only the config for that specific platform.
29 |
--------------------------------------------------------------------------------
/docs/device_automation_action.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Device Actions"
3 | sidebar_label: Actions
4 | ---
5 |
6 | Device actions allow a user to have a device do something. Examples are to turn a light on or open a door.
7 |
8 | Device actions are defined as dictionaries. These dictionaries are created by your integration and are passed to your integration to create a function that performs the action.
9 |
10 | Device actions can be provided by the integration that provides the device (e.g. ZHA, deCONZ) or the entity integrations that the device has entities with (e.g. light, switch).
11 | An example of the former could be to reboot the device, while an example of the latter could be to turn a light on.
12 |
13 | Home Assistant includes a template to get started with device actions. To get started, run inside a development environment `python3 -m script.scaffold device_action`.
14 |
15 | The template will create a new file `device_action.py` in your integration folder and a matching test file. The file contains the following functions and constants:
16 |
17 | #### `ACTION_SCHEMA`
18 |
19 | This is the schema for actions. The base schema should be extended from `homeassistant.helpers.config_validation.DEVICE_ACTION_BASE_SCHEMA`.
20 |
21 | #### `async def async_get_actions(hass, device_id)`
22 |
23 | Return a list of actions that this device supports.
24 |
25 | #### `async def async_call_action_from_config(hass, config, variables, context)`
26 |
27 | Execute the passed in action.
28 |
--------------------------------------------------------------------------------
/docs/creating_component_generic_discovery.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Integration with Multiple Platforms"
3 | sidebar_label: Multiple platforms
4 | ---
5 |
6 | Most integrations consist of a single platform. And in that case, it's fine to just define that one platform. However, if you are going to add a second platform, you will want to centralize your connection logic. This is done inside the component (`__init__.py`).
7 |
8 | If your integration is configurable via `configuration.yaml`, it will cause the entry point of your configuration to change, as now users will need to set up your integration directly, and it is up to your integration to set up the platforms.
9 |
10 | ## Loading platforms when configured via a config entry
11 |
12 | If your integration is set up via a config entry, you will need to forward the config entry to the appropriate integration to set up your platform. For more info, see the [config entry documentation](config_entries_index.md#for-platforms).
13 |
14 | ## Loading platforms when configured via configuration.yaml
15 |
16 | If your integration is not using config entries, it will have to use our discovery helpers to set up its platforms. Note, this approach does not support unloading.
17 |
18 | To do this, you will need to use the `load_platform` and `async_load_platform` methods from the discovery helper.
19 |
20 | - See also a [full example that implements this logic](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_load_platform/)
21 |
--------------------------------------------------------------------------------
/docs/entity_registry_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Entity Registry
3 | sidebar_label: Introduction
4 | ---
5 |
6 | The entity registry is a registry where Home Assistant keeps track of entities. Any entity that is added to Home Assistant which specifies the [`unique_id` attribute](/core/entity.md#generic-properties) will be registered in the registry.
7 |
8 | Being registered has the advantage that the same entity will always get the same entity ID. It will also prevent other entities from using that entity ID.
9 |
10 | A user is also able to override the name of an entity in the entity registry. When set, the name of the entity registry is used in favor of the name the device might give itself.
11 |
12 | ## Unique ID requirements
13 |
14 | An entity is looked up in the registry based on a combination of the platform type (e.g., `light`), and the integration name (domain) (e.g. hue) and the unique ID of the entity. It is therefore very important that the unique ID is unique! It is also important that it is not possible for the user to change the unique ID, because that means it will lose all its settings related to it.
15 |
16 | Good sources for a unique ID:
17 |
18 | - Serial number of a device
19 | - MAC address of a device
20 | - latitude/longitude
21 |
22 | If a device has a single serial but provides multiple entities, combine the serial with unique identifiers for the entities. For example, if a device measures both temperature and humidity, you can uniquely identify the entities using `{serial}-{sensor_type}`.
23 |
--------------------------------------------------------------------------------
/docs/intent_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Intents"
3 | sidebar_label: "Introduction"
4 | ---
5 |
6 | An intent is a description of a user's intention. Intents are generated by user actions, like asking Amazon Echo to turn on a light.
7 |
8 |
9 |
13 |
14 |
15 | Intents are fired by components that receive them from external sources/services. Conversation, Alexa, API.ai and Snips are currently sourcing intents.
16 |
17 | Any component can handle intents. This makes it very easy for developers to integrate with all voice assistants at once.
18 |
19 | Intents are implemented using the `homeassistant.helpers.intent.Intent` class. It contains the following properties:
20 |
21 | | Name | Type | Description |
22 | | ---- | ---- | ----------- |
23 | | `hass` | Home Assistant | The Home Assistant instance that fired the intent.
24 | | `platform` | string | The platform that fired the intent
25 | | `intent_type` | string | The type (name) of the intent
26 | | `slots` | dictionary | Contains the slot values keyed by slot name.
27 | | `text_input` | string | Optional. The raw text input that initiated the intent.
28 |
29 | Description of the slots dictionary values.
30 |
31 | | Name | Type | Description |
32 | | ---- | ---- | ----------- |
33 | | Value | anything | Value of the slot.
34 |
--------------------------------------------------------------------------------
/blog/2020-04-16-hassfest.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Hassfest for custom components
7 | ---
8 |
9 | Hassfest is an internal tool that we use in Home Assistant to make sure that all integrations have valid data. We've now made Hassfest able to validate any integration, including custom integrations. To make it easy to get started with this, [@ludeeus](https://www.github.com/ludeeus) has created a GitHub Action that gets you up and running in less than a minute.
10 |
11 | To install it, follow these steps:
12 |
13 | 1. Go to your custom component repository on GitHub
14 | 2. Click on "Create new file"
15 | 3. For filename, paste `.github/workflows/hassfest.yaml`
16 | 4. Paste the following contents:
17 |
18 | ```yaml
19 | name: Validate with hassfest
20 |
21 | on:
22 | push:
23 | pull_request:
24 | schedule:
25 | - cron: "0 0 * * *"
26 |
27 | jobs:
28 | validate:
29 | runs-on: "ubuntu-latest"
30 | steps:
31 | - uses: "actions/checkout@v2"
32 | - uses: home-assistant/actions/hassfest@master
33 | ```
34 |
35 | GitHub will now lint all incoming PRs and commits with hassfest, and will also run it once every night to check against the latest requirements.
36 |
37 | The Hassfest action will track the beta release channel. That way you will be notified if your integration is incompatible with newer versions of Home Assistant.
38 |
--------------------------------------------------------------------------------
/docs/add-ons.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Developing an add-on"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | Add-ons for Home Assistant allow the user to extend the functionality around Home Assistant. This can be running an application that Home Assistant can integrate with (like an MQTT broker) or to share the configuration via Samba for easy editing from other computers. Add-ons can be configured via the Supervisor panel in Home Assistant.
7 |
8 | Under the hood, add-ons are Docker images published in [Docker Hub](https://hub.docker.com/). Developers can create [GitHub](https://github.com) repositories that contain multiple references to add-ons for easy sharing with the community.
9 |
10 | - [Tutorial: Making your first add-on](add-ons/tutorial.md)
11 | - [Configuration](add-ons/configuration.md)
12 | - [Communication](add-ons/communication.md)
13 | - [Local Testing](add-ons/testing.md)
14 | - [Publishing](add-ons/publishing.md)
15 | - [Presentation](add-ons/presentation.md)
16 | - [Repositories](add-ons/repository.md)
17 | - [Security](add-ons/security.md)
18 |
19 | Useful links:
20 |
21 | - [Supervisor](https://github.com/home-assistant/supervisor)
22 | - [Core Add-ons](https://github.com/home-assistant/hassio-addons)
23 | - [Docker base images](https://github.com/home-assistant/docker-base)
24 | - [Builder](https://github.com/home-assistant/hassio-builder)
25 | - [Home Assistant community Add-ons](https://github.com/hassio-addons)
26 | - [Home Assistant Operating System](https://github.com/home-assistant/operating-system)
27 | - [Home Assistant Docker](https://github.com/home-assistant/docker)
28 |
--------------------------------------------------------------------------------
/blog/2020-05-08-instance-url-helper.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Franck Nijhof
3 | authorURL: https://twitter.com/frenck
4 | authorImageURL: /img/profile/frenck.png
5 | authorTwitter: frenck
6 | title: Instance URL helper
7 | ---
8 |
9 | If you are an integration developer and came across the problem of getting the
10 | URL of the users' Home Assistant instance, you probably know, this wasn't always
11 | easy.
12 |
13 | The main problem is that a Home Assistant instance is generally installed, at home.
14 | Meaning the internal and external address can be different and even those can
15 | have variations (for example, if a user has a Home Assistant Cloud subscription).
16 |
17 | Matters become worse if the integration has specific requirements for the URL;
18 | for example, it must be externally available and requires SSL.
19 |
20 | As of Home Assistant Core 0.110, a new instance URL helper is introduced to
21 | ease that. We started out with the following flow chart to solve this issue:
22 |
23 | [](/img/en/blog/2020-05-instance-url-helper/flowchart.png)
24 |
25 | As a result of this, the previously available `base_url` is now replaced by two
26 | new core configuration settings for the user: the internal and external URL.
27 |
28 | From a development perspective, the use of `hass.config.api.base_url` is now
29 | deprecated in favor of the new `get_url` helper method.
30 |
31 | For more information on using and implementing this new URL helper method,
32 | consult our documentation [here](/docs/instance_url).
33 |
--------------------------------------------------------------------------------
/docs/architecture_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Architecture"
3 | sidebar_label: "Introduction"
4 | ---
5 |
6 | Before we dive into the Home Assistant architecture, let's get a clear overview of the home automation landscape as a whole. This way, we can show how the different parts of Home Assistant fit into the picture.
7 |
8 | For more information about each part in this overview, [check out our blog](https://www.home-assistant.io/blog/2014/12/26/home-control-home-automation-and-the-smart-home). Here's the tl;dr version of the blog:
9 |
10 | - Home Control is responsible for collecting information and controlling devices.
11 | - Home Automation triggers commands based on user configurations.
12 | - Smart Home triggers commands based on previous behavior.
13 |
14 |
18 |
19 | The Home Assistant core is responsible for Home Control. Home Assistant contains four parts which make this possible:
20 |
21 | - **Event Bus**: facilitates the firing and listening of events -- the beating heart of Home Assistant.
22 | - **State Machine**: keeps track of the states of things and fires a `state_changed` event when a state has been changed.
23 | - **Service Registry**: listens on the event bus for `call_service` events and allows other code to register services.
24 | - **Timer**: sends a `time_changed` event every 1 second on the event bus.
25 |
26 |
30 |
--------------------------------------------------------------------------------
/docs/device_automation_condition.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Device Conditions"
3 | sidebar_label: Conditions
4 | ---
5 |
6 | Device conditions allow a user to check if a certain condition is met. Examples are is a light on or is the floor wet.
7 |
8 | Device conditions are defined as dictionaries. These dictionaries are created by your integration and are passed to your integration to create a function that checks the condition.
9 |
10 | Device conditions can be provided by the integration that provides the device (e.g. ZHA, deCONZ) or the entity integrations that the device has entities with (e.g. light, humidity sensor).
11 | An example of the latter could be to check if a light is on or the floor is wet.
12 |
13 | Home Assistant includes a template to get started with device conditions. To get started, run inside a development environment `python3 -m script.scaffold device_condition`.
14 |
15 | The template will create a new file `device_condition.py` in your integration folder and a matching test file. The file contains the following functions and constants:
16 |
17 | #### `CONDITION_SCHEMA`
18 |
19 | This is the schema for conditions. The base schema should be extended from `homeassistant.helpers.config_validation.DEVICE_CONDITION_BASE_SCHEMA`.
20 |
21 | #### `async def async_get_conditions(hass, device_id)`
22 |
23 | Return a list of conditions that this device supports.
24 |
25 | #### `async def async_condition_from_config(config, config_validation)`
26 |
27 | Create a condition function from a function. The condition functions should be an async-friendly callback that evaluates the condition and returns a `bool`.
28 |
--------------------------------------------------------------------------------
/docs/frontend/extending/adding-state-card.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Adding state card"
3 | ---
4 |
5 | The main interface of Home Assistant is a list of the current entities and their states. For each entity in the system, a state card will be rendered. State cards will show an icon, the name of the entity, when the state has last changed and the current state or a control to interact with it.
6 |
7 | 
8 |
9 | The different card types can be found [here](https://github.com/home-assistant/home-assistant-polymer/tree/master/src/state-summary).
10 |
11 | Sensors, when not grouped, are shown as so-called badges on top of the state cards.
12 |
13 | 
14 |
15 | The different badges are located in the file [`/src/components/entity/ha-state-label-badge.ts`](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/components/entity/ha-state-label-badge.ts).
16 |
17 | Adding a custom card type can be done with a few simple steps. For this example we will add a new state card for the domain `camera`:
18 |
19 | 1. Add `'camera'` to the array `DOMAINS_WITH_CARD` in the file [/common/const.ts](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/common/const.ts).
20 | 2. Create the files `state-card-camera.js` in the folder [/state-summary/](https://github.com/home-assistant/home-assistant-polymer/tree/master/src/state-summary).
21 | 3. Add `import './state-card-camera.js';` to [state-card-content.js](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/state-summary/state-card-content.js).
22 |
--------------------------------------------------------------------------------
/blog/2020-05-14-entity-class-names.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://github.com/balloob
4 | authorTwitter: balloob
5 | title: Entity class names
6 | ---
7 |
8 | Ever wondered when implementing entities for our entity integrations why you had to extend `BinarySensorDevice` and not `BinarySensorEntity`? Wonder no longer, as we have addressed the situation in Home Assistant 0.110 by renaming all classes that incorrectly had Device in their name. The old classes are still around but will log a warning when used.
9 |
10 | All integrations in Home Assistant have been upgraded. Custom component authors need to do the migration themselves. You can do this while keeping backwards compatibility by using the following snippet:
11 |
12 | ```python
13 | try:
14 | from homeassistant.components.binary_sensor import BinarySensorEntity
15 | except ImportError:
16 | from homeassistant.components.binary_sensor import BinarySensorDevice as BinarySensorEntity
17 | ```
18 |
19 | The following classes have been renamed:
20 |
21 | | Old Class Name | New Class Name |
22 | | -------------------- | -------------------- |
23 | | `BinarySensorDevice` | `BinarySensorEntity` |
24 | | `MediaPlayerDevice` | `MediaPlayerEntity` |
25 | | `LockDevice` | `LockEntity` |
26 | | `ClimateDevice` | `ClimateEntity` |
27 | | `CoverDevice` | `CoverEntity` |
28 | | `VacuumDevice` | `VacuumEntity` |
29 | | `RemoteDevice` | `RemoteEntity` |
30 | | `Light` | `LightEntity` |
31 | | `SwitchDevice` | `SwitchEntity` |
32 | | `WaterHeaterDevice` | `WaterHeaterEntity` |
33 |
--------------------------------------------------------------------------------
/docs/integration_events.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Firing events"
3 | ---
4 |
5 | Some integrations represent devices or services that have events, like when motion is detected or a momentary button is pushed. An integration can make these available to users by firing them as events in Home Assistant.
6 |
7 | Your integration should fire events of type `_event`. For example, the ZHA integration fires `zha_event` events.
8 |
9 | If the event is related to a specific device/service, it should be correctly attributed. Do this by adding a `device_id` attribute to the event data that contains the device identifier from the device registry.
10 |
11 | ```
12 | event_data = {
13 | "device_id": "my-device-id",
14 | "type": "motion_detected",
15 | }
16 | hass.bus.async_fire("mydomain_event", event_data)
17 | ```
18 |
19 | If a device or service only fires events, you need to [manually register it in the device registry](device_registry_index.md#manual-registration).
20 |
21 | ## Making events accessible to users
22 |
23 | A [Device trigger](device_automation_trigger.md) can be attached to a specific event based on the payload, and will make the event accessible to users. With a device trigger a user will be able to see all available events for the device and use it in their automations.
24 |
25 | ## What not to do
26 |
27 | Event related code should not be part of the entity logic of your integration. You want to enable the logic of converting your integration events to Home Assistant events from inside `async_setup_entry` inside `__init__.py`.
28 |
29 | Entity state should not represent events. For example, you don't want to have a binary sensor that is `on` for 30 seconds when an event happens.
30 |
--------------------------------------------------------------------------------
/blog/2020-05-09-custom-iconsets.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Bram Kragten
3 | authorURL: https://github.com/bramkragten
4 | authorTwitter: bramkragten
5 | title: Custom icon sets
6 | ---
7 |
8 | If you are the maintainer of a custom icon set, you might need to update it.
9 |
10 | In Home Assistant core version 0.110 we will change the way our icons are loaded. We no longer load all the `mdi` icons at once, and they will not become DOM elements.
11 | This will save us almost 5000 DOM elements and will reduce loading time.
12 |
13 | This also means we no longer use or load ``, if your icon set relied on this element, you will have to change your icon set.
14 |
15 | We introduced a new API where you can register your custom icon set with an async function, that we will call with the icon name as parameter.
16 | We expect a promise with an object of the icon requested. Your icon set can decide on a strategy for loading and caching.
17 |
18 | The format of the API is:
19 | ```ts
20 | window.customIconsets: {
21 | [iconset_name: string]: (icon_name: string) => Promise< { path: string; viewBox?: string } >
22 | };
23 | ```
24 | `path` is the path of the `svg`. This is the string that is in the `d` attribute of the `` element.
25 | The `viewBox` is optional and will default to `0 0 24 24`.
26 |
27 | An very simple example of this for the icon `custom:icon`:
28 |
29 | ```js
30 | async function getIcon(name) {
31 | return {
32 | path: "M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z",
33 | };
34 | }
35 | window.customIconsets = window.customIconsets || {};
36 | window.customIconsets["custom"] = getIcon;
37 | ```
38 |
39 | Home Assistant will call the fuction `getIcon("icon")` when the icon `custom:icon` is set.
40 |
--------------------------------------------------------------------------------
/docs/intent_firing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Firing intents"
3 | ---
4 |
5 | When you fire an intent, you will get a response back or an error will be raised. It is up to the component to return the result to the user.
6 |
7 | Example code to handle an intent in Home Assistant.
8 |
9 | ```python
10 | from homeassistant.helpers import intent
11 |
12 | intent_type = "TurnLightOn"
13 | slots = {"entity": {"value": "Kitchen"}}
14 |
15 | try:
16 | intent_response = yield from intent.async_handle(
17 | hass, "example_component", intent_type, slots
18 | )
19 |
20 | except intent.UnknownIntent as err:
21 | _LOGGER.warning("Received unknown intent %s", intent_type)
22 |
23 | except intent.InvalidSlotInfo as err:
24 | _LOGGER.error("Received invalid slot data: %s", err)
25 |
26 | except intent.IntentError:
27 | _LOGGER.exception("Error handling request for %s", intent_type)
28 | ```
29 |
30 | The intent response is an instance of `homeassistant.helpers.intent.IntentResponse`.
31 |
32 | | Name | Type | Description |
33 | | ---- | ---- | ----------- |
34 | | `intent` | Intent | Instance of intent that triggered response. |
35 | | `speech` | Dictionary | Speech responses. Each key is a type. Allowed types are `plain` and `ssml`. |
36 | | `card` | Dictionary | Card responses. Each key is a type. |
37 |
38 | Speech dictionary values:
39 |
40 | | Name | Type | Description |
41 | | ---- | ---- | ----------- |
42 | | `speech` | String | The text to say
43 | | `extra_data` | Any | Extra information related to this speech.
44 |
45 | Card dictionary values:
46 |
47 | | Name | Type | Description |
48 | | ---- | ---- | ----------- |
49 | | `title` | String | The title of the card
50 | | `content` | Any | The content of the card
51 |
--------------------------------------------------------------------------------
/docs/development_typing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Adding type hints to your code"
3 | ---
4 |
5 | Type hints in Python are static annotations of variables and functions, to let humans more easily understand the code. See the standard library [docs](https://docs.python.org/3/library/typing.html) and this PyCascades 2018 [talk](https://youtu.be/zKre4DKAB30).
6 |
7 | Type hints are not required for all modules at the moment in Home Assistant, but we aim to have complete coverage of the core modules.
8 |
9 | Adding type hints to an existing codebase can be a daunting task. To speed this up and help developers doing this, Instagram made the [`monkeytype`](https://pypi.org/project/MonkeyType/) program. It will analyze calls during runtime and try to assign the correct type hints to the code.
10 |
11 | See [this instagram blog post](https://instagram-engineering.com/let-your-code-type-hint-itself-introducing-open-source-monkeytype-a855c7284881) for a description of the workflow involved to use the monkeytype program.
12 |
13 | We've added a script to start a run of our test suite or a test module and tell the `monkeytype` program to analyze the run.
14 |
15 | ### Basic workflow
16 |
17 | 1. Run `script/monkeytype tests/path/to/your_test_module.py`.
18 | 2. Run `monkeytype stub homeassistant.your_actual_module`.
19 | 3. Look at output from the monkeytyped typing stub. If not totally bad, apply the stub to your module. You most likely will need to manually edit the typing in the last step.
20 | 4. Run `monkeytype apply homeassistant.your_actual_module`.
21 | 5. Check the diff and manually correct the typing if needed. Commit, push the branch and make a PR.
22 |
23 | **Note:**
24 | Applying a monkeytyped stub to a module that has existing typing annotations might error and not work. This tool is most useful for totally untyped modules.
25 |
--------------------------------------------------------------------------------
/docs/entity_number.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Number Entity
3 | sidebar_label: Number
4 | ---
5 |
6 | A `number` is an entity that allows the user to input an arbitrary value to an integration. Derive entity platforms from [`homeassistant.components.number.NumberEntity`](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/number/__init__.py)
7 |
8 | ## Properties
9 |
10 | > Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
11 |
12 | | Name | Type | Default | Description
13 | | ---- | ---- | ------- | -----------
14 | | value | float | **Required** | Current value of the entity
15 | | min_value | float | 0 | The minimum accepted value (inclusive)
16 | | max_value | float | 100 | The maximum accepted value (inclusive)
17 | | step | float | **See below** | Defines the resolution of the values, i.e. the smallest increment or decrement
18 |
19 | Other properties that are common to all entities such as `icon`, `unit_of_measurement`, `name` etc are also applicable.
20 |
21 | The default step value is dynamically chosen based on the range (max - min) values. If the difference between max_value and min_value is greater than 1.0, then the default step is 1.0. If however the range is smaller, then the step is iteratively devided by 10 until it becomes lower than the range.
22 |
23 | ## Methods
24 |
25 | ### Set value
26 |
27 | Called when the user or automation wants to update the value.
28 |
29 | ```python
30 | class MyNumber(NumberEntity):
31 | # Implement one of these methods.
32 |
33 | def set_value(self, value: float) -> None:
34 | """Update the current value."""
35 |
36 | async def async_set_value(self, value: float) -> None:
37 | """Update the current value."""
38 |
39 | ```
40 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | ## Proposed change
7 |
11 |
12 |
13 | ## Type of change
14 |
20 |
21 | - [ ] Document existing features within Home Assistant
22 | - [ ] Document new or changing features which there is an existing pull request elsewhere
23 | - [ ] Spelling or grammatical corrections, or rewording for improved clarity
24 | - [ ] Changes to the backend of this documentation
25 | - [ ] Removed stale or deprecated documentation
26 |
27 | ## Additional information
28 |
36 |
37 | - This PR fixes or closes issue: fixes #
38 | - Link to relevant existing code or pull request:
39 |
--------------------------------------------------------------------------------
/docs/creating_platform_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Integration Platforms"
3 | sidebar_label: "Platforms"
4 | ---
5 |
6 | Home Assistant has various built-in integrations that abstract device types. There are [lights](core/entity/light.md), [switches](core/entity/switch.md), [covers](core/entity/cover.md), [climate devices](core/entity/climate.md), and [many more](core/entity.md). Your integration can hook into these integrations by creating a platform. You will need a platform for each integration that you are integrating with.
7 |
8 | To create a platform, you will need to create a file with the domain name of the integration that you are building a platform for. So if you are building a light, you will add a new file `light.py` to your integration folder.
9 |
10 | We have created two example integrations that should give you a look at how this works:
11 |
12 | - [Example sensor platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_sensor/): hello world of platforms.
13 | - [Example light platform](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_light/): showing best practices.
14 |
15 | ### Interfacing with devices
16 |
17 | One Home Assistant rule is that the integration should never interface directly with devices. Instead, it should interact with a third-party Python 3 library. This way, Home Assistant can share code with the Python community and keep the project maintainable.
18 |
19 | Once you have your Python library ready and published to PyPI, add it to the [manifest](creating_integration_manifest.md). It will now be time to implement the Entity base class that is provided by the integration that you are creating a platform for.
20 |
21 | Find your integration at the [entity index](core/entity.md) to see what methods and properties are available to implement.
22 |
--------------------------------------------------------------------------------
/docs/maintenance.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Maintenance"
3 | ---
4 |
5 | This page documents a couple of points for maintaining the Home Assistant code. Most of the tasks don't need to be performed on a regular base thus the steps, used tools, or details are preserved here.
6 |
7 | ## Source code
8 |
9 | ### Line separator
10 |
11 | People are using various operating systems to develop components and platforms for Home Assistant. This could lead to different line endings on file. We prefer `LN`. Especially Microsoft Windows tools tend to use `CRLF`.
12 |
13 | ```shell
14 | $ find homeassistant -name "*.py" -exec file {} \; | grep BOM
15 | $ find homeassistant -name "*.py" -exec file {} \; | grep CRLF
16 | ```
17 |
18 | To fix the line separator, use `dos2unix` or `sed`.
19 |
20 | ```shell
21 | $ dos2unix homeassistant/components/notify/kodi.py
22 | ```
23 |
24 | ### File permissions
25 |
26 | Most files don't need to the be executable. `0644` is fine.
27 |
28 | ### Dependencies
29 |
30 | A lot of components and platforms depends on third-party Python modules. The dependencies which are stored in the `requirements_all.txt` files can be tracked with [`pur`](https://pypi.org/project/pur/) or [`pip-upgrader`](https://github.com/simion/pip-upgrader).
31 |
32 | If you update the requirements of a component/platform by updating `manifest.json`, run the provided script to update the `requirements_*.txt` file(s).
33 |
34 | ```shell
35 | $ script/gen_requirements_all.py
36 | ```
37 |
38 | Start a test run of Home Assistant. If that was successful, include all files in a Pull Request. Add a short summary of the changes, a sample configuration entry, details about the tests you performed to ensure the update works, and other useful information to the description.
39 |
40 |
41 | ## Documentation
42 |
43 | - Merge `current` into `next` on a regular base.
44 | - Optimize the images.
45 |
46 |
--------------------------------------------------------------------------------
/blog/2020-02-18-106-custom-card-changes.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Bram Kragten
3 | authorURL: https://github.com/bramkragten
4 | authorTwitter: bramkragten
5 | title: "Changes that can affect custom cards in 0.106"
6 | ---
7 |
8 | We made some changes that can affect custom Lovelace cards in Home Assistant Core 0.106, if you are a custom card developer, please read the following.
9 |
10 | ### Freeze config
11 |
12 | We used to give a copy of the configuration to every card because some cards altered the configuration Lovelace passed to them. In 0.105 we stopped doing this because it is not good for performance to create a deep copy for every card.
13 | This resulted in some problems because cards were still altering the configuration. In 0.106 we freeze the configuration. This means that a custom card cannot alter the configuration. If it tries to do it anyway, it will throw an exception or fail silently, depending on if it is run in strict mode.
14 |
15 | Please check if your custom card still works with 0.106 and make adjustments to not alter the configuration. You can create a copy of the configuration yourself if you need to.
16 |
17 | ### Helper functions
18 |
19 | :::info
20 | We decided to postpone this change until 0.107.
21 | :::
22 |
23 | A second change that was made, is that we no longer load all element types by default. We load them when they are needed. This will also help performance but might break your custom card.
24 |
25 | We introduced a set of helpers that you can use to create a Lovelace element, these are the same functions Home Assistant uses internally and will always be up to date to the version the user is using.
26 | You can use them as follows:
27 |
28 | ```js
29 | const helpers = await loadCardHelpers();
30 | const element = helpers.createRowElement(config);
31 | element.hass = this.hass;
32 | ```
33 |
34 | For more info see https://github.com/home-assistant/home-assistant-polymer/pull/4853
35 |
--------------------------------------------------------------------------------
/docs/dev_101_hass.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Hass object"
3 | ---
4 |
5 | While developing Home Assistant you will see a variable that is everywhere: `hass`. This is the Home Assistant instance that will give you access to all the various parts of the system.
6 |
7 | ### The `hass` object
8 |
9 | The Home Assistant instance contains four objects to help you interact with the system.
10 |
11 | | Object | Description |
12 | | ------ | ----------- |
13 | | `hass` | This is the instance of Home Assistant. Allows starting, stopping and enqueuing new jobs. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.HomeAssistant)
14 | | `hass.config` | This is the core configuration of Home Assistant exposing location, temperature preferences and config directory path. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.Config)
15 | | `hass.states` | This is the StateMachine. It allows you to set states and track when they are changed. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.StateMachine) |
16 | | `hass.bus` | This is the EventBus. It allows you to trigger and listen for events. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.EventBus) |
17 | | `hass.services` | This is the ServiceRegistry. It allows you to register services. [See available methods.](https://dev-docs.home-assistant.io/en/master/api/core.html#homeassistant.core.ServiceRegistry) |
18 |
19 | ### Where to find `hass`
20 |
21 | Depending on what you're writing, there are different ways the `hass` object is made available.
22 |
23 | **Component**
24 | Passed into `setup(hass, config)` or `async_setup(hass, config)`.
25 |
26 | **Platform**
27 | Passed into `setup_platform(hass, config, add_devices, discovery_info=None)` or `async_setup_platform(hass, config, async_add_devices, discovery_info=None)`.
28 |
29 | **Entity**
30 | Available as `self.hass` once the entity has been added via the `add_devices` callback inside a platform.
31 |
--------------------------------------------------------------------------------
/docs/core/entity/binary-sensor.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Binary Sensor Entity
3 | sidebar_label: Binary Sensor
4 | ---
5 |
6 | A binary sensor is a sensor that can only have two states.
7 |
8 | ## Properties
9 |
10 | :::tip
11 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
12 | :::
13 |
14 | | Name | Type | Default | Description
15 | | ---- | ---- | ------- | -----------
16 | | is_on| boolean | **Required** | If the binary sensor is currently on or off.
17 | | device_class | string | `None` | Type of binary sensor.
18 |
19 | ### Available device classes
20 |
21 | | Value | Description
22 | | ----- | -----------
23 | | battery | On means low, Off means normal.
24 | | battery_charging | On means charging, Off means not charging.
25 | | cold | On means cold, Off means normal.
26 | | connectivity | On means connected, Off means disconnected.
27 | | door | On means open, Off means closed.
28 | | garage_door | On means open, Off means closed.
29 | | gas | On means gas detected, Off means no gas (clear).
30 | | heat | On means hot, Off means normal.
31 | | light | On means light detected, Off means no light.
32 | | lock | On means open (unlocked), Off means closed (locked).
33 | | moisture | On means wet, Off means dry.
34 | | motion | On means motion detected, Off means no motion (clear).
35 | | moving | On means moving, Off means not moving (stopped).
36 | | occupancy | On means occupied, Off means not occupied (clear).
37 | | opening | On means open, Off means closed.
38 | | plug | On means plugged in, Off means unplugged.
39 | | power | On means power detected, Off means no power.
40 | | presence | On means home, Off means away.
41 | | problem | On means problem detected, Off means no problem (OK).
42 | | safety | On means unsafe, Off means safe.
43 | | smoke | On means smoke detected, Off means no smoke (clear).
44 | | sound | On means sound detected, Off means no sound (clear).
45 | | vibration | On means vibration detected, Off means no vibration.
46 | | window | On means open, Off means closed.
47 |
--------------------------------------------------------------------------------
/docs/asyncio_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Asynchronous Programming"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | On September 29, 2016 we released [Home Assistant 0.29][0.29] as part of our bi-weekly release schedule. This release introduced a complete overhaul of the core spearheaded by [Ben Bangert][ben].
7 |
8 | The old core was set up like a “traditional” threaded application. Each resource that was not thread safe (ie. the state of entities) would be protected by a lock. This caused a lot of waiting and potential inconsistency because a task could now end up waiting halfway through its job until some resource got freed.
9 |
10 | Our new core is based on Python’s built-in **asyncio** module. Instead of having all threads have access to the core API objects, access is now limited to a special thread called the *event loop*. All components will now schedule themselves as a task to be executed by the event loop. This gives us the guarantee that only a single task is executed at the same time, meaning we no longer need any locks.
11 |
12 | The only problem with running everything inside the event loop is when a task does blocking I/O; something most third-party Python libraries do. For example, while requesting new information from a device, the core will stop running until we get a response from the device. To handle this, a task is able to suspend itself until the response is available, after which it will be enqueued in the event loop to process the result.
13 |
14 | For a task to be able to suspend itself, all code that it calls must support this capability. In practice, this would mean that each device integration will need a full rewrite of the library that offers the integration! As this is something that cannot be achieved, ever, a 100% backwards compatible API has been added so that no platform will require updating.
15 |
16 | The backwards compatible API schedules a task in a different thread and blocks that thread until the task has been processed by the event loop.
17 |
18 | [0.29]: https://www.home-assistant.io/blog/2016/09/29/async-sleepiq-emoncms-stocks/
19 | [ben]: https://github.com/bbangert/
20 |
--------------------------------------------------------------------------------
/docs/add-ons/security.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Add-on security"
3 | ---
4 |
5 | Home Assistant rates every add-on based on the wanted rights. An add-on with a rating of 6 is very secure. If an add-on has a rating of 1, you shouldn't run this add-on unless you are 100% sure that you can trust the source.
6 |
7 | ## API Role
8 |
9 | For access to Supervisor API you need define a role or you run in default mode. This is only required for Supervisor API not Home Assistant proxy. Any of the roles already have access to the default API calls, and do not require any additional settings.
10 |
11 | ### Available Roles
12 |
13 | | Role | Description |
14 | |------|-------------|
15 | | default | Have access to all `info` calls |
16 | | homeassistant | Can access all Home Assistant API endpoints |
17 | | backup | Can access all snapshot API endpoints |
18 | | manager | Is for Add-ons that run CLIs and need extended rights |
19 | | admin | Have access to every API call. That is the only one they can disable/enable the Add-on protection mode |
20 |
21 | ## Protection
22 |
23 | Default, all add-ons run in protection enabled mode. This mode prevents the add-on from getting any rights on the system. If an add-on requires more rights, you can disable this protection via the API add-on options for that add-on. But be careful, an add-on with disabled protection can destroy your system!
24 |
25 | ## Making a secure add-on
26 |
27 | As a developer, follow the following best practices to make your add-on secure:
28 |
29 | - Don't run on host network
30 | - Create an AppArmor profile
31 | - Map folders read only if you don't need write access
32 | - If you need any API access, make sure that you do not grant permission that aren't needed
33 |
34 | ## Use Home Assistant User backend
35 |
36 | Instead of allowing users to set new login credential in plain text config, use the Home Assistant [Auth backend][hassio-api-auth]. You can enable the access to API with `auth_api: true`. Now you are able to send the login credential to auth backend and validate it again Home Assistant.
37 |
38 | [supervisor-api-auth]: /api/supervisor/endpoints.md#auth
39 |
--------------------------------------------------------------------------------
/docs/creating_component_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Creating your first integration"
3 | ---
4 |
5 | Alright, you learned about the [manifest](creating_integration_manifest.md), so it's time to write your first code for your integration. AWESOME. Don't worry, we've tried hard to keep it as easy as possible. From a Home Assistant development environment, type the following and follow the instructions:
6 |
7 | ```shell
8 | python3 -m script.scaffold integration
9 | ```
10 |
11 | This will set you up with everything that you need to build an integration that is able to be set up via the user interface. More extensive examples of integrations are available from [our example repository](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/).
12 |
13 | ## The minimum
14 |
15 | The scaffold integration contains a bit more than just the bare minimum. The minimum is that you define a `DOMAIN` constant that contains the domain of the integration. The second part is that it needs to define a setup method that returns a boolean if the set up was successful.
16 |
17 | ```python
18 | DOMAIN = "hello_state"
19 |
20 |
21 | def setup(hass, config):
22 | hass.states.set("hello_state.world", "Paulus")
23 |
24 | # Return boolean to indicate that initialization was successful.
25 | return True
26 | ```
27 |
28 | And if you prefer an async component:
29 |
30 | ```python
31 | DOMAIN = "hello_state"
32 |
33 |
34 | async def async_setup(hass, config):
35 | hass.states.async_set("hello_state.world", "Paulus")
36 |
37 | # Return boolean to indicate that initialization was successful.
38 | return True
39 | ```
40 |
41 | To load this, add `hello_state:` to your `configuration.yaml` file and create a file `/custom_components/hello_state/__init__.py` with one of the two codeblocks above to test it locally.
42 |
43 | ## What the scaffold offers
44 |
45 | When using the scaffold script, it will go past the bare minimum of an integration. It will include a config flow, tests for the config flow and basic translation infrastructure to provide internationalization for your config flow.
46 |
--------------------------------------------------------------------------------
/blog/2020-04-12-s6-overlay.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Franck Nijhof
3 | authorURL: https://twitter.com/frenck
4 | authorImageURL: /img/profile/frenck.png
5 | authorTwitter: frenck
6 | title: S6 Overlay for our Docker containers
7 | ---
8 |
9 | Home Assistant uses a lot of different Docker containers for all kinds of
10 | purposes. Not only the Home Assistant Core that is available as Docker
11 | containers but also our Supervisor and all add-ons are leveraging Docker.
12 |
13 | In many situations, we need to run multiple processes in our containers,
14 | that all need to be managed. We used to do this using simple Bash scripting,
15 | but quickly learned we need a proper process manager to handle this.
16 |
17 | We decided to use the [S6 Overlay init system][s6-overlay], which is based on
18 | the excellent [S6][s6] toolset that provides process supervision and
19 | management, logging, and system initialization.
20 |
21 | The S6 Overlay has been added to our [Docker base images][base-imags],
22 | which is used by every Docker image Home Assistant ships.
23 |
24 | All containers have been updated, and changes are automatically handled by the
25 | Home Assistant Supervisor; For Home Assistant users, there is no noticeable
26 | impact.
27 |
28 | For users of the Home Assistant Core containers on Docker, this might impact
29 | the way you run or start the container. If you run your Home Assistant Core
30 | container with an override of the Docker entry point or command, you need to
31 | adapt those. For example, some container management systems, like Portainer
32 | and Synology, automatically override those for you so you are impacted.
33 |
34 | In those cases:
35 |
36 | - The entry point has changed to: `/init`
37 | - The command (CMD) has changed to: ` ` _(Empty/not set)_
38 |
39 | If you override the command endpoint to start Home Assistant, the init system
40 | in the entry point will still be active in the background and a second launch
41 | Home Assistant. This can lead to unexpected behavior.
42 |
43 | [base-imags]: https://github.com/home-assistant/docker-base
44 | [s6-overlay]: https://github.com/just-containers/s6-overlay
45 | [s6]: http://skarnet.org/software/s6/
46 |
--------------------------------------------------------------------------------
/blog/2020-02-04-new-zwave.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Update on the Z-Wave integration
7 | ---
8 |
9 | import DiscussionBox from '../static/js/discourse_discussion.jsx'
10 |
11 | At the State of the Union we [introduced that we're working on a new Z-Wave integration](https://youtu.be/tc17q1Zn0Xs?t=4482). It's based on a new project by the Open Z-Wave project called [OZWDaemon](https://github.com/OpenZWave/qt-openzwave) and we will communicate with it over MQTT.
12 |
13 | This new approach allows us to integrate directly with the core of Open Z-Wave without relying on bindings via other languages. This allows us to easily keep up to date with the latest Open Z-Wave versions.
14 |
15 | There has been some great progress on the integration thanks to [@cgarwood] and [@marcelveldt] and you can start testing it out today as [a custom component](https://github.com/cgarwood/homeassistant-zwave_mqtt). It's still early and not every device type is supported yet. Currently it supports lights, switches, sensors and binary sensors. The custom component is powered by the new [`python-openzwave-mqtt`](https://github.com/cgarwood/python-openzwave-mqtt) package.
16 |
17 | [Please try it out.](https://github.com/cgarwood/homeassistant-zwave_mqtt#requirements) If you find any bugs, [create an issue](https://github.com/cgarwood/homeassistant-zwave_mqtt/issues/new). If you are using Home Assistant 0.105, use the new `mqtt.dump` service on topic `openzwave/#` to make a dump of your Open Z-Wave instance and attach that to your issue. The dump will be written to `mqtt_dump.txt` in your config folder.
18 |
19 | Once the integration is mature enough, it will become part of Home Assistant Core.
20 |
21 | [@cgarwood]: https://github.com/cgarwood
22 | [@marcelveldt]: https://github.com/marcelveldt
23 |
24 |
25 |
26 | ## Comments
27 |
28 |
29 |
30 |
32 |
--------------------------------------------------------------------------------
/docs/intent_builtin.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Built-in intents"
3 | ---
4 |
5 | Home Assistant comes with a couple of built-in intents. These intents aim to offer similar functionality as exposed via the services. All built-in intents are prefixed with "Hass" to avoid collision with user defined intents.
6 |
7 | ## Core
8 |
9 | ### HassTurnOff
10 |
11 | Turn an entity off.
12 |
13 | | Slot name | Type | Required | Description
14 | | --------- | ---- | -------- | -----------
15 | | name | string | Yes | Name of the entity to turn off.
16 |
17 | ### HassTurnOn
18 |
19 | Turn an entity on.
20 |
21 | | Slot name | Type | Required | Description
22 | | --------- | ---- | -------- | -----------
23 | | name | string | Yes | Name of the entity to turn on.
24 |
25 | ### HassToggle
26 |
27 | Toggle the state of an entity.
28 |
29 | | Slot name | Type | Required | Description
30 | | --------- | ---- | -------- | -----------
31 | | name | string | Yes | Name of the entity to toggle.
32 |
33 | ## Cover
34 |
35 | ### HassOpenCover
36 |
37 | Open a cover.
38 |
39 | | Slot name | Type | Required | Description
40 | | --------- | ---- | -------- | -----------
41 | | name | string | Yes | Name of the cover entity to open.
42 |
43 | ### HassCloseCover
44 |
45 | Close a cover.
46 |
47 | | Slot name | Type | Required | Description
48 | | --------- | ---- | -------- | -----------
49 | | name | string | Yes | Name of the cover entity to close.
50 |
51 | ## Light
52 |
53 | ### HassLightSet
54 |
55 | Set the state of a light.
56 |
57 | | Slot name | Type | Required | Description
58 | | --------- | ---- | -------- | -----------
59 | | name | string | Yes | Name of the entity to toggle.
60 | | color | string, name of valid color | No | Color to change the light to.
61 | | brightness | integer, 0-100 | No | Brightness to change the light to.
62 |
63 | ## Shopping List
64 |
65 | ### HassShoppingListAddItem
66 |
67 | Add an item to the shopping list.
68 |
69 | | Slot name | Type | Required | Description
70 | | --------- | ---- | -------- | -----------
71 | | item | string | Yes | Name of item to add to the list.
72 |
73 | ### HassShoppingListLastItems
74 |
75 | List the last 5 items on the shopping list.
76 |
77 | _This intent has no slots._
78 |
--------------------------------------------------------------------------------
/blog/2020-06-01-getCardSize.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Bram Kragten
3 | authorURL: https://github.com/bramkragten
4 | authorTwitter: bramkragten
5 | title: "Lovelace: getCardSize can now be async"
6 | ---
7 |
8 | Ever since we introduced lazy loading cards to Lovelace, getting the card size of a lazy loaded card was hard.
9 |
10 | We used to send out an error element before the element was loaded, which would have a `getCardSize` function. But that would be the wrong size.
11 | When the element would be defined we would, fire and rebuild the event so the right card would be recreated.
12 |
13 | In 0.110 we stopped doing this, we would give back the correct element, but the element constructor would not be loaded yet, so it doesn't have the `getCardSize`.
14 | When the constructor is loaded, the element will be upgraded and we set the config. From that moment we can call `getCardSize`.
15 |
16 | In this version, we changed the logic for `getCardSize` so it will wait for this. This means some cards, like stacks, will return a promise because they have to wait for their children to be defined.
17 |
18 | If you are a custom card developer and your custom card uses `getCardSize` to get the size of other cards, you have to adjust it to handle these promises.
19 |
20 | Our function to get the card size, which you could copy, now looks like this:
21 |
22 | ```ts
23 | export const computeCardSize = (
24 | card: LovelaceCard | LovelaceHeaderFooter
25 | ): number | Promise => {
26 | if (typeof card.getCardSize === "function") {
27 | return card.getCardSize();
28 | }
29 | if (customElements.get(card.localName)) {
30 | return 1;
31 | }
32 | return customElements
33 | .whenDefined(card.localName)
34 | .then(() => computeCardSize(card));
35 | };
36 | ```
37 |
38 | We first have the same check as before, if the element has a `getCardSize` function we will return that value, this should be a `number` or `Promise` that resolves to a `number`.
39 |
40 | If the function doesn't exist, we will check if the constructor of the element is registered, if it is, this means the element doesn't have a `getCardSize` and we will return `1` as we did before.
41 |
42 | If the element isn't registered yet, we will wait until it is and then call the same function again of the now defined card to get the size.
43 |
--------------------------------------------------------------------------------
/docs/creating_integration_file_structure.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Integration File Structure"
3 | sidebar_label: "File Structure"
4 | ---
5 |
6 | Each integration is stored inside a directory named after the integration domain. The domain is a short name consisting of characters and underscores. This domain has to be unique and cannot be changed. Example of the domain for the mobile app integration: `mobile_app`. So all files for this integration are in the folder `mobile_app/`.
7 |
8 | The bare minimum content of this folder looks like this:
9 |
10 | - `manifest.json`: The manifest file describes the integration and its dependencies. [More info](creating_integration_manifest.md)
11 | - `__init__.py`: The component file. If the integration only offers a platform, you can keep this file limited to a docstring introducing the integration `"""The Mobile App integration."""`.
12 |
13 | ## Integrating devices - `light.py`, `switch.py` etc
14 |
15 | If your integration is going to integrate one or more devices, you will need to do this by creating a platform that interacts with an entity integration. For example, if you want to represent a light device inside Home Assistant, you will create `light.py`, which will contain a light platform for the light integration.
16 |
17 | - More info on [available entity integrations](core/entity.md).
18 | - More info on [creating platforms](creating_platform_index.md).
19 |
20 | ## Integrating services - `services.yaml`
21 |
22 | If your integration is going to register services, it will need to provide a description of the available services. The description is stored in `services.yaml`. [More information about `services.yaml`.](dev_101_services.md)
23 |
24 | ## Where Home Assistant looks for integrations
25 |
26 | Home Assistant will look for an integration when it sees the domain referenced in the config file (i.e. `mobile_app:`) or if it is a dependency of another integration. Home Assistant will look at the following locations:
27 |
28 | - `/custom_components/`
29 | - `homeassistant/components/` (built-in integrations)
30 |
31 | You can override a built-in integration by having an integration with the same domain in your `config/custom_components` folder. Note that overriding built-in components is not recommended as you will no longer get updates. It is recommended to pick a unique name.
32 |
--------------------------------------------------------------------------------
/docs/core/entity/vacuum.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Vacuum Entity
3 | sidebar_label: Vacuum
4 | ---
5 |
6 | ## Properties
7 |
8 | :::tip
9 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
10 | :::
11 |
12 | | Name | Type | Default | Description
13 | | ---- | ---- | ------- | -----------
14 | | name | string | **Required** | Name of the device.
15 | | state | string | **Required** | One of the states listed in the states section.
16 | | battery_level | int | `none` | Current battery level.
17 | | battery_icon | string | function | Battery icon to show in UI.
18 | | cleaning_mode | string | `none` | The current cleaning mode.
19 | | cleaning_mode_list | list | `NotImplementedError()`| List of available fan speeds and cleaning modes.
20 | | error | string | **Required** with `STATE_ERROR` | An error message if the vacuum is in `STATE_ERROR`.
21 |
22 | ## States
23 |
24 | | State | Description
25 | | ----- | -----------
26 | | `STATE_CLEANING` | The vacuum is currently cleaning.
27 | | `STATE_DOCKED` | The vacuum is currently docked, it is assumed that docked can also mean charging.
28 | | `STATE_PAUSED` | The vacuum was cleaning but was paused without returning to the dock.
29 | | `STATE_IDLE` | The vacuum is not paused, not docked and does not have any errors.
30 | | `STATE_RETURNING` | The vacuum is done cleaning and is currently returning to the dock, but not yet docked.
31 | | `STATE_ERROR` | The vacuum encountered an error while cleaning, the error can be specified as a property on the entity.
32 |
33 | ## Methods
34 |
35 | ### `turn_on` or `async_turn_on`
36 |
37 | Turn the vacuum on and start cleaning.
38 |
39 | ### `turn_off` or `async_turn_off`
40 |
41 | Turn the vacuum off stopping the cleaning and returning home.
42 |
43 | ### `return_to_base` or `async_return_to_base`
44 |
45 | Set the vacuum cleaner to return to the dock.
46 |
47 | ### `stop` or `async_stop`
48 |
49 | Stop the vacuum cleaner, do not return to base.
50 |
51 | ### `clean_spot` or `async_clean_spot`
52 |
53 | Perform a spot clean-up.
54 |
55 | ### `locate` or `async_locate`
56 |
57 | Locate the vacuum cleaner.
58 |
59 | ### `set_cleaning_mode` or `async_set_cleaning_mode`
60 |
61 | Set the cleaning mode.
62 |
63 | ### `send_command` or `async_send_command`
64 |
65 | Send a command to a vacuum cleaner.
66 |
--------------------------------------------------------------------------------
/blog/2020-11-09-system-health-and-templates.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: System Health and Templates
7 | ---
8 |
9 | In Home Assistant 0.118, there will be two changes that could impact your custom integration.
10 |
11 | ## Removed deprecated `helpers.template.extract_entities`
12 |
13 | The previously deprecated `extract_entities` method from the Template helper has been removed ([PR 42601](https://github.com/home-assistant/core/pull/42601)). Instead of extracting entities and then manually listen for state changes, use the new `async_track_template_result` from the Event helper. It will dynamically make sure that every touched entity is tracked correctly.
14 |
15 | ```python
16 | from homeassistant.helpers.event import async_track_template_result, TrackTemplate
17 |
18 | template = "{{ light.kitchen.state == 'on' }}"
19 |
20 | async_track_template_result(
21 | hass,
22 | [TrackTemplate(template, None)],
23 | lambda event, updates: print(event, updates),
24 | )
25 | ```
26 |
27 | ## Improved System Health
28 |
29 | Starting with Home Assistant 0.118, we're deprecating the old way of providing system health information for your integration. Instead, create a `system_health.py` file in your integration ([PR 42785](https://github.com/home-assistant/core/pull/42785)).
30 |
31 | Starting this release, you can also include health checks that take longer to resolve ([PR 42831](https://github.com/home-assistant/core/pull/42831)), like checking if the service is online. The results will be passed to the frontend when they are ready.
32 |
33 | ```python
34 | """Provide info to system health."""
35 | from homeassistant.components import system_health
36 | from homeassistant.core import HomeAssistant, callback
37 |
38 | from .const import DOMAIN
39 |
40 |
41 | @callback
42 | def async_register(
43 | hass: HomeAssistant, register: system_health.RegisterSystemHealth
44 | ) -> None:
45 | """Register system health callbacks."""
46 | register.async_register_info(system_health_info)
47 |
48 |
49 | async def system_health_info(hass):
50 | """Get info for the info page."""
51 | client = hass.data[DOMAIN]
52 |
53 | return {
54 | "server_version": client.server_version,
55 | "can_reach_server": system_health.async_check_can_reach_url(
56 | hass, client.server_url
57 | )
58 | }
59 | ```
60 |
--------------------------------------------------------------------------------
/docs/development_catching_up.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Catching up with Reality"
3 | ---
4 |
5 | If it's taking a while to develop your feature, and you want to catch up with what's in the current Home Assistant `dev` branch, you can use `git rebase`. This will pull the latest Home Assistant changes locally, rewind your commits, bring in the latest changes from Home Assistant, and replay all of your commits on top.
6 |
7 | :::tip
8 | If you use the workflow below, it is important that you force push the update as described. Git might prompt you to do `git pull` first. Do **NOT** do that! It would mess up your commit history.
9 | :::
10 |
11 | You should have added an additional `remote` after you clone your fork. If you did not, do it now before proceeding.
12 |
13 | ```shell
14 | git remote add upstream https://github.com/home-assistant/core.git
15 | ```
16 |
17 | ```shell
18 | # Run this from your feature branch
19 | git fetch upstream dev # to pull the latest changes into a local dev branch
20 | git rebase upstream/dev # to put those changes into your feature branch before your changes
21 | ```
22 |
23 | If rebase detects conflicts, repeat this process until all changes have been resolved:
24 |
25 | 1. `git status` shows you the file with the conflict; edit the file and resolve the lines between `<<<< | >>>>`
26 | 2. Add the modified file: `git add ` or `git add .`
27 | 3. Continue rebase: `git rebase --continue`
28 | 4. Repeat until you've resolved all conflicts
29 |
30 | After rebasing your branch, you will have rewritten history relative to your GitHub fork's branch. When you go to push you will see an error that your history has diverged from the original branch. In order to get your GitHub fork up-to-date with your local branch, you will need to force push, using the following command:
31 |
32 | ```shell
33 | # Run this from your feature branch
34 | git push origin --force-with-lease
35 | ```
36 |
37 | If that command fails, it means that new work was pushed to the branch from either you or another contributor since your last rebase.
38 | You will have to start over the git fetch and rebase process described above, or if you are really confident those changes are not needed, just overwrite them:
39 |
40 | ```shell
41 | # Run this from your feature branch, overwriting any changes in the remote branch
42 | git push origin --force
43 | ```
44 |
45 | Other workflows are covered in detail in the [Github documentation](https://help.github.com/articles/fork-a-repo/).
46 |
--------------------------------------------------------------------------------
/docs/core/entity/light.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Light Entity
3 | sidebar_label: Light
4 | ---
5 |
6 |
7 | A light entity controls the brightness, hue and saturation color value, white value, color temperature and effects of a light source. Derive platform entities from [`homeassistant.components.light.LightEntity`](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/light/__init__.py).
8 |
9 | ## Properties
10 |
11 | | Name | Type | Default | Description
12 | | ---- | ---- | ---- | ----
13 | | brightness | int | None | Return the brightness of this light between 0..255
14 | | color_temp | int | None | Return the CT color value in mireds.
15 | | effect | String | None | Return the current effect.
16 | | effect_list | list | None | Return the list of supported effects.
17 | | hs_color | list | None | Return the hue and saturation color value [float, float].
18 | | is_on | bool | bool | Returns if the light entity is on or not.
19 | | max_mireds | int | int | Return the warmest color_temp that this light supports.
20 | | min_mireds | int | int | Return the coldest color_temp that this light supports.
21 | | supported_features | int | int | Flag supported features.
22 | | white_value | int | None | Return the white value of this light between 0..255.
23 |
24 | ## Support Feature
25 |
26 | | Constant | Description
27 | |----------|-----------------------
28 | | `SUPPORT_BRIGHTNESS` | Controls the brightness of a light source
29 | | `SUPPORT_COLOR` | Controls the color a light source shows
30 | | `SUPPORT_COLOR_TEMP` | Controls the representation a light source shows based on temperature
31 | | `SUPPORT_EFFECT` | Controls the effect a light source shows
32 | | `SUPPORT_FLASH` | Controls the duration of a flash a light source shows
33 | | `SUPPORT_TRANSITION` | Controls the duration of transitions between color and effects
34 | | `SUPPORT_WHITE_VALUE` | Controls the white light a light source shows.
35 |
36 | ## Methods
37 |
38 | ### Turn on Light Device
39 |
40 | ```python
41 | class MyLightEntity(LightEntity):
42 | def turn_on(self, **kwargs):
43 | """Turn the device on."""
44 |
45 | async def async_turn_on(self, **kwargs):
46 | """Turn device on."""
47 | ```
48 |
49 | ### Turn Off Light Device
50 |
51 | ```python
52 | class MyLightEntity(LightEntity):
53 | def turn_off(self, **kwargs):
54 | """Turn the device off."""
55 |
56 | async def async_turn_off(self, **kwargs):
57 | """Turn device off."""
58 | ```
59 |
--------------------------------------------------------------------------------
/docs/dev_101_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Development 101"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | The goal of development 101 is to get you familiar with the basics of developing for Home Assistant. Before we start, please make sure you familiarize yourself with the [architecture](architecture_index.md).
7 |
8 | To get our code running inside Home Assistant we're going to create a custom component. The first step is to locate your config folder. You can find the path to your config folder by opening the Home Assistant frontend, click on the . It's the path after the text "Path to configuration.yaml".
9 |
10 | Inside your configuration directory create a new folder called `custom_components`. It might be that one already exists, that's fine too. This is the folder that Home Assistant will look at when looking for custom code.
11 |
12 | :::info
13 | The Home Assistant API has two variants: a synchronous and an asynchronous version (asyncio). This development course will focus on the synchronous version.
14 | :::
15 |
16 | To verify that everything is working correctly, let's create a small Hello World component. To do so, create a file called `hello_world.py` in your custom components folder. Copy paste the following content to it:
17 |
18 | ```python
19 | # The domain of your component. Equal to the filename of your component.
20 | DOMAIN = "hello_world"
21 |
22 |
23 | def setup(hass, config):
24 | """Setup the hello_world component."""
25 | # States are in the format DOMAIN.OBJECT_ID.
26 | hass.states.set("hello_world.Hello_World", "Works!")
27 |
28 | # Return boolean to indicate that initialization was successfully.
29 | return True
30 | ```
31 |
32 | Last step is to add `hello_world:` entry to your `configuration.yaml` file.
33 |
34 | ```yaml
35 | # Hello World component
36 | hello_world:
37 | ```
38 |
39 | After running `hass`, we should see log entries stating that `hello_world` component was loaded. What is more, an additional state card will appear within the main panel.
40 |
41 | ```log
42 | 2018-04-03 21:44:20 INFO (MainThread) [homeassistant.loader] Loaded hello_world from custom_components.hello_world
43 | 2018-04-03 21:44:20 INFO (MainThread) [homeassistant.setup] Setting up hello_world
44 | ```
45 |
46 |
50 |
--------------------------------------------------------------------------------
/docs/config_entries_options_flow_handler.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Integration Configuration Options
3 | sidebar_label: Configuration Options
4 | ---
5 |
6 | An integration that is configured via a config entry can expose options to the user to allow tweaking behavior of the integration, like which devices or locations should be integrated.
7 |
8 | Config Entry Options uses the [Data Flow Entry framework](data_entry_flow_index.md) to allow users to update a config entries options. Components that want to support config entry options will need to define an Options Flow Handler.
9 |
10 | ## Options support
11 |
12 | For an integration to support options it needs to have an `async_get_options_flow` method in its config flow handler. Calling it will return an instance of the components options flow handler.
13 |
14 | ```python
15 | @staticmethod
16 | @callback
17 | def async_get_options_flow(config_entry):
18 | return OptionsFlowHandler()
19 | ```
20 |
21 | ## Flow handler
22 |
23 | The Flow handler works just like the config flow handler, except that the first step in the flow will always be `async_step_init`.
24 |
25 | ```python
26 | class OptionsFlowHandler(config_entries.OptionsFlow):
27 | async def async_step_init(self, user_input=None):
28 | """Manage the options."""
29 | if user_input is not None:
30 | return self.async_create_entry(title="", data=user_input)
31 |
32 | return self.async_show_form(
33 | step_id="init",
34 | data_schema=vol.Schema(
35 | {
36 | vol.Required(
37 | "show_things",
38 | default=self.config_entry.options.get("show_things"),
39 | ): bool
40 | }
41 | ),
42 | )
43 | ```
44 |
45 | ## Signal updates
46 |
47 | If the component should act on updated options, you can register an update listener to the config entry that will be called when the entry is updated.
48 |
49 | ```python
50 | unsub = entry.add_update_listener(update_listener)
51 | ```
52 |
53 | The Listener shall be an async function that takes the same input as async_setup_entry. Options can then be accessed from `entry.options`.
54 |
55 | ```python
56 | async def update_listener(hass, entry):
57 | """Handle options update."""
58 | ```
59 |
60 | Don't forget to unsubscribe the update listener when your config entry is unloaded. You can do this by calling the unsubscribe function returned from adding the listener:
61 |
62 | ```python
63 | unsub()
64 | ```
65 |
--------------------------------------------------------------------------------
/docs/development_submitting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Submit your work"
3 | ---
4 |
5 | :::tip
6 | Always base your Pull Requests off of the current **`dev`** branch, not `master`.
7 | :::
8 |
9 | Submit your improvements, fixes, and new features to Home Assistant one at a time, using GitHub [Pull Requests](https://help.github.com/articles/using-pull-requests). Here are the steps:
10 |
11 | 1. From your fork's dev branch, create a new branch to hold your changes:
12 |
13 | `git checkout -b some-feature`
14 |
15 | 2. Make your changes, create a [new platform](creating_platform_index.md), develop a [new integration](creating_component_index.md), or fix [issues](https://github.com/home-assistant/home-assistant/issues).
16 |
17 | 3. [Test your changes](development_testing.md) and check for style violations.
18 | Consider adding tests to ensure that your code works.
19 |
20 | 4. If everything looks good according to these [musts](development_checklist.md), commit your changes:
21 |
22 | `git add .`
23 |
24 | `git commit -m "Add some feature"`
25 |
26 | - Write a meaningful commit message and not only something like `Update` or `Fix`.
27 | - Use a capital letter to start with your commit message and do not finish with a full-stop (period).
28 | - Don't prefix your commit message with `[bla.bla]` or `platform:`.
29 | - Write your commit message using the imperative voice, e.g. `Add some feature` not `Adds some feature`.
30 |
31 |
32 | 5. Push your committed changes back to your fork on GitHub:
33 |
34 | `git push origin HEAD`
35 |
36 | 6. Follow [these steps](https://help.github.com/articles/creating-a-pull-request/) to create your pull request.
37 |
38 | - On GitHub, navigate to the [main page of the Home Assistant repository](https://github.com/home-assistant/core).
39 | - In the "Branch" menu, choose the branch that contains your commits (from your fork).
40 | - To the right of the Branch menu, click **New pull request**.
41 | - Use the base branch dropdown menu to select the branch you'd like to merge your changes into, then use the compare branch drop-down menu to choose the topic branch you made your changes in. Make sure the Home Assistant branch matches with your forked branch (`dev`) else you will propose ALL commits between branches.
42 | - Type a title and complete the provided template for your pull request.
43 | - Click **Create pull request**.
44 |
45 | 7. Check for comments and suggestions on your pull request and keep an eye on the [CI output](https://travis-ci.org/home-assistant/home-assistant/).
46 |
--------------------------------------------------------------------------------
/docs/core/entity/lock.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Lock Entity
3 | sidebar_label: Lock
4 | ---
5 |
6 | A lock entity is able to be locked and unlocked. Locking and unlocking can optionally be secured with a user code. Some locks also allow for opening of latches, this may also be secured with a user code. Derive a platform entity from [`homeassistant.components.lock.LockEntity`](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/lock/__init__.py).
7 |
8 | ## Properties
9 |
10 | :::tip
11 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
12 | :::
13 |
14 | | Name | Type | Default | Description
15 | | ---- | ---- | ------- | -----------
16 | | changed_by | string | None | Describes what the last change was triggered by.
17 | | code_format | string | None | Regex for code format or None if no code is required.
18 | | is_locked | bool | None | Indication of whether the lock is currently locked. Used to determine `state`.
19 |
20 | ### Supported Features
21 |
22 | Supported features constants are combined using the bitwise or (`|`) operator.
23 |
24 | | Constant | Description |
25 | |----------|--------------------------------------|
26 | | `SUPPORT_OPEN` | This lock supports opening the door latch.
27 |
28 | ## Methods
29 |
30 | ### Lock
31 |
32 | ```python
33 | class MyLock(LockEntity):
34 |
35 | def lock(self, **kwargs):
36 | """Lock all or specified locks. A code to lock the lock with may optionally be specified."""
37 |
38 | async def async_lock(self, **kwargs):
39 | """Lock all or specified locks. A code to lock the lock with may optionally be specified."""
40 | ```
41 |
42 | ### Unlock
43 |
44 | ```python
45 | class MyLock(LockEntity):
46 |
47 | def unlock(self, **kwargs):
48 | """Unlock all or specified locks. A code to unlock the lock with may optionally be specified."""
49 |
50 | async def async_unlock(self, **kwargs):
51 | """Unlock all or specified locks. A code to unlock the lock with may optionally be specified."""
52 | ```
53 |
54 | ### Open
55 |
56 | Only implement this method if the flag `SUPPORT_OPEN` is set.
57 |
58 | ```python
59 | class MyLock(LockEntity):
60 |
61 | def open(self, **kwargs):
62 | """Open (unlatch) all or specified locks. A code to open the lock with may optionally be specified."""
63 |
64 | async def async_open(self, **kwargs):
65 | """Open (unlatch) all or specified locks. A code to open the lock with may optionally be specified."""
66 | ```
67 |
--------------------------------------------------------------------------------
/docs/core/entity/switch.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Switch Entity
3 | sidebar_label: Switch
4 | ---
5 |
6 | A switch entity turns on or off something, for example a relay. Derive a platform entity from [`homeassistant.components.switch.SwitchEntity`](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/switch/__init__.py).
7 | To represent something which can be turned on or off but can't be controlled, for example a wall switch which transmits its state but can't be turned on or off from Home Assistant, a Binary Sensor is a better choice.
8 | To represent something which doesn't have a state, for example a door bell push button, a custom event or a Device Trigger is a better choice.
9 |
10 | ## Properties
11 |
12 | :::tip
13 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
14 | :::
15 |
16 | | Name | Type | Default | Description
17 | | ---- | ---- | ------- | -----------
18 | | is_on | boolean | **Required** | If the switch is currently on or off.
19 | | current_power_w | float | `None` | The current power usage in W.
20 | | today_energy_kwh | float | `None` | Total energy usage in kWh.
21 | | is_standby | boolean | `None` | Indicate if the device connected to the switch is currently in standby.
22 |
23 | ## Methods
24 |
25 | ### Turn On
26 |
27 | Turn the switch on.
28 |
29 | ```python
30 | class MySwitch(SwitchEntity):
31 | # Implement one of these methods.
32 |
33 | def turn_on(self, **kwargs) -> None:
34 | """Turn the entity on."""
35 |
36 | async def async_turn_on(self, **kwargs):
37 | """Turn the entity on."""
38 | ```
39 |
40 | ### Turn Off
41 |
42 | Turn the switch off.
43 |
44 | ```python
45 | class MySwitch(SwitchEntity):
46 | # Implement one of these methods.
47 |
48 | def turn_off(self, **kwargs):
49 | """Turn the entity off."""
50 |
51 | async def async_turn_off(self, **kwargs):
52 | """Turn the entity off."""
53 | ```
54 |
55 | ### Toggle
56 |
57 | Optional. If not implemented will default to checking what method to call using the `is_on` property.
58 |
59 | ```python
60 | class MySwitch(SwitchEntity):
61 | # Implement one of these methods.
62 |
63 | def toggle(self, **kwargs):
64 | """Toggle the entity."""
65 |
66 | async def async_toggle(self, **kwargs):
67 | """Toggle the entity."""
68 | ```
69 |
70 | ### Available device classes
71 |
72 | Optional. What type of device this. It will possibly map to google device types.
73 |
74 | | Value | Description
75 | | ----- | -----------
76 | | outlet | Device is an outlet for power.
77 | | switch | Device is switch for some type of entity.
78 |
--------------------------------------------------------------------------------
/docs/api_lib_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Building a Python library for an API"
3 | sidebar_label: "Introduction"
4 | ---
5 |
6 | One of the foundational rules of Home Assistant is that we do not include any protocol specific code. Instead, this code should be put into a standalone Python library and published to PyPI. This guide will describe how to get started with this!
7 |
8 | For this guide we're going to assume that we're building a library for a Rest API that is accessible over HTTP and returning data structured as JSON objects. This is the most common type of API that we see. These APIs can either be accessible on the device itself, or in the cloud.
9 |
10 | This guide is not a perfect fit for every API. You might have to tweak the examples.
11 |
12 | :::info
13 | If you are a manufacturer designing a new API for your product, [please read about the best type of API to add to your products here](https://www.home-assistant.io/blog/2016/02/12/classifying-the-internet-of-things/#local-device-pushing-new-state).
14 | :::
15 |
16 | HTTP API requests consist of four different parts:
17 |
18 | - The URL. This is the path that we fetch data from. With a Rest API the URL will uniquely identify the resource. Examples of urls are `http://example.com/api/lights` and `http://example.com/api/light/1234`.
19 | - The HTTP method. This defines what we want from the API. The most common ones are:
20 | - `GET` for when we want to get information like the state of a light
21 | - `POST` for if we want something to be done (ie turn on a light)
22 | - The body. This is the data that we sent to the server to identify what needs to be done. This is how we send the command in the case of a `POST` request.
23 | - The headers. This contains metadata to describe your request. This will used to attach the authorization to the request.
24 |
25 | ## Structuring the library
26 |
27 | Our library will consist of two different parts:
28 |
29 | - **Authentication:** Responsible for making authenticated HTTP requests to the API endpoint and returning the results. This is the only piece of code that will actually interact with the API.
30 | - **Data models:** Represent the data and offer commands to interact with the data.
31 |
32 | ## Trying your library inside Home Assistant
33 |
34 | You will need to run an editable version of your library if you want to try your library in Home Assistant before it is published to PyPI.
35 |
36 | Do so by going to your Home Assistant development environment, activating the virtual environment and typing:
37 |
38 | ```shell
39 | pip3 install -e ../my_lib_folder
40 | ```
41 |
42 | Now run Home Assistant without installing dependencies from PyPI to avoid overriding your package.
43 |
44 | ```shell
45 | hass --skip-pip
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/dev_101_events.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using Events"
3 | ---
4 |
5 | The core of Home Assistant is driven by events. That means that if you want to respond to something happening, you'll have to respond to events. Most of the times you won't interact directly with the event system but use one of the [event listener helpers][helpers].
6 |
7 | The event system is very flexible. There are no limitations on the event type, as long as it's a string. Each event can contain data. The data is a dictionary that can contain any data as long as it's JSON serializable. This means that you can use number, string, dictionary and list.
8 |
9 | [List of events that Home Assistant fires.][object]
10 |
11 | ## Firing events
12 |
13 | To fire an event, you have to interact with the event bus. The event bus is available on the Home Assistant instance as `hass.bus`. Please be mindful of the data structure as documented on our [Data Science portal](https://data.home-assistant.io/docs/events/#database-table).
14 |
15 | Example component that will fire an event when loaded. Note that custom event names are prefixed with the component name.
16 |
17 | ```python
18 | DOMAIN = "example_component"
19 |
20 |
21 | def setup(hass, config):
22 | """Set up is called when Home Assistant is loading our component."""
23 |
24 | # Fire event example_component_my_cool_event with event data answer=42
25 | hass.bus.fire("example_component_my_cool_event", {"answer": 42})
26 |
27 | # Return successful setup
28 | return True
29 | ```
30 |
31 | ## Listening to events
32 |
33 | Most of the times you'll not be firing events but instead listen to events. For example, the state change of an entity is broadcasted as an event.
34 |
35 | ```python
36 | DOMAIN = "example_component"
37 |
38 |
39 | def setup(hass, config):
40 | """Set up is called when Home Assistant is loading our component."""
41 | count = 0
42 |
43 | # Listener to handle fired events
44 | def handle_event(event):
45 | nonlocal count
46 | count += 1
47 | print(f"Answer {count} is: {event.data.get('answer')}")
48 |
49 | # Listen for when example_component_my_cool_event is fired
50 | hass.bus.listen("example_component_my_cool_event", handle_event)
51 |
52 | # Return successful setup
53 | return True
54 | ```
55 |
56 | ### Helpers
57 |
58 | Home Assistant comes with a lot of bundled helpers to listen to specific types of event. There are helpers to track a point in time, to track a time interval, a state change or the sun set. [See available methods.][helpers]
59 |
60 | [helpers]: https://dev-docs.home-assistant.io/en/master/api/helpers.html#module-homeassistant.helpers.event
61 | [object]: https://www.home-assistant.io/docs/configuration/events/
62 |
--------------------------------------------------------------------------------
/docs/frontend/architecture.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Frontend Architecture"
3 | sidebar_label: "Architecture"
4 | ---
5 |
6 | The Home Assistant frontend is built using web components. This is a modern web technology allowing us to encapsulate templates, styling and logic into a single file and expose it as an HTML tag in the browser. These components are composable, allowing a very dynamic and powerful foundation of our application.
7 |
8 | ## Structure
9 |
10 | The Home Assistant frontend can be broken up in 4 parts:
11 |
12 | ### Bootstrap
13 |
14 | File: `src/entrypoints/core.js`
15 |
16 | This is a very tiny script which is the first thing that is loaded on the page. It is responsible for checking for authentication credentials and setting up the websocket connection with the backend.
17 |
18 | The script allows us to start downloading the data while also downloading the rest of the UI in parallel.
19 |
20 | ### App shell
21 |
22 | File: `src/entrypoints/app.js`
23 |
24 | This is everything that is required to render the sidebar and handle the routing.
25 |
26 | ### Panels
27 |
28 | Folder: `src/panels/`
29 |
30 | Each page in Home Assistant is a panel. Components can register extra panels to be shown to the user. Examples of panels are "states", "map", "logbook" and "history".
31 |
32 | ### Dialogs
33 |
34 | Folder: `src/dialogs`
35 |
36 | Certain information and data entry is presented to users in flows. Dialogs can be triggered on any page. The most common one is the entity more info dialog, which allows users to dig into an entity state, history and setting.s
37 |
38 | ## Data Flow
39 |
40 | The frontend leverages the [Websocket API](api/websocket.md) and the [Rest API](api/rest.md) to interact with Home Assistant.
41 |
42 | The data is made available as the `hass` property which is passed down to every component. The `hass` property contains the core state and has methods to call APIs.
43 |
44 | Components can subscribe to information that is not available in the core state. Subscriptions run through the websocket API which keeps the data in sync with the backend.
45 |
46 | We use a unidirectional data flow. When you make a change in the backend (like turning on a light), the `hass` object will be updated at the root of the application and will be made available to every component that needs it.
47 |
48 | ## Routing
49 |
50 | The frontend uses decentralized routing. Each component only knows enough about the routing to know how to handle the part it's responsible for. Further routing is passed down the component tree.
51 |
52 | For example, the `` main component will look at the first part of the url to decide which panel should be loaded. Each panel can have its own mapping between the url and what content to show.
53 |
--------------------------------------------------------------------------------
/blog/2018-06-01-071-custom-panels.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: "0.71: Improved custom panels and minor changes for custom UI"
7 | ---
8 |
9 | Efforts to modernize and localize the frontend are moving full speed. This blog post will touch upon the upcoming features for Home Assistant 0.71 which should hit the beta channel today and is planned for a release a week from now.
10 |
11 | ## Improved Custom Panel support
12 |
13 | Custom panels allow developers to build panels that will plug into the Home Assistant user interface, with the same possibilities like our other panels like history, map etc. The Home Assistant frontend will manage authentication and the subscription for states of the backend, the panel only has to take care of displaying the data and can offer users option to control things (calling services etc).
14 |
15 | This support has been around for a while, but last week we've spend some time [polishing](https://github.com/home-assistant/home-assistant/pull/14708) our support and have three new additions:
16 |
17 | First new feature is that we now allow importing a panel from a JavaScript URL. This is going to be the preferred way to distribute panels moving forward. This also means that you can refer to a panel hosted externally. The user will have to approve before external panels get loaded. It's still possible for users to host it locally (and no approval is needed) by copying the panel to `/www/your-panel.js` and use `/local/your-panel.js` as the url.
18 |
19 | Second new feature is that we can now embed your panel in an iFrame. This allows panel developers to not have to worry about including duplicate web components and it makes it possible to develop React-based panels. In the past, React-based panels didn't work because React doesn't work well inside Shadow DOM ([more info](https://github.com/facebook/react/pull/12163)).
20 |
21 | Third new feature is that we now make a [starter kit](https://github.com/home-assistant/custom-panel-starter-kit-react) available to start developing React based panels! The kit contains everything that is needed to start developing React-based panels and share them with the community. Let us know what you're building!
22 |
23 | ## Custom UI: `` and ``
24 |
25 | If you're building custom UI, odds are that you're using either `` and ``. Although not officially supported as external facing API, we still want to give a heads up that it's going to be needed to pass the `hass` object in.
26 |
27 | This is necessary because `` can now be localized thanks to c727 in [#1241](https://github.com/home-assistant/home-assistant-polymer/pull/1241.)
28 |
--------------------------------------------------------------------------------
/docs/configuration_yaml_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Integration Configuration via YAML"
3 | ---
4 |
5 | `configuration.yaml` is a configuration file defined by the user. It is automatically created by Home Assistant on first launch. It defines which components to load.
6 |
7 | :::info Note about YAML for devices and/or services
8 |
9 | Integrations that communicate with devices and/or services are configured via a config flow. In rare cases, we can make an exception. Existing integrations that should not have a YAML configuration are allowed and encouraged to implement a configuration flow and remove YAML support. Changes to existing YAML configuration for these same existing integrations will no longer be accepted.
10 |
11 | For more detail read [ADR-0010](https://github.com/home-assistant/architecture/blob/master/adr/0010-integration-configuration.md#decision)
12 | :::
13 |
14 | ## Pre-processing
15 |
16 | Home Assistant will do some pre-processing on the config based on the components that are specified to load.
17 |
18 | ### CONFIG_SCHEMA
19 |
20 | If a component defines a variable `CONFIG_SCHEMA`, the config object that is passed in will be the result of running the config through `CONFIG_SCHEMA`. `CONFIG_SCHEMA` should be a voluptuous schema.
21 |
22 | ### PLATFORM_SCHEMA
23 |
24 | If a component defines a variable `PLATFORM_SCHEMA`, the component will be treated as an entity component. The configuration of entity components is a list of platform configurations.
25 |
26 | Home Assistant will gather all platform configurations for this component. It will do so by looking for configuration entries under the domain of the component (ie `light`) but also under any entry of domain + extra text.
27 |
28 | While gathering the platform configs, Home Assistant will validate them. It will see if the platform exists and if the platform defines a PLATFORM_SCHEMA, validate against that schema. If not defined, it will validate the config against the PLATFORM_SCHEMA defined in the component. Any configuration that references non existing platforms or contains invalid config will be removed.
29 |
30 | The following `configuration.yaml`:
31 |
32 | ```yaml
33 | unrelated_component:
34 | some_key: some_value
35 |
36 | switch:
37 | platform: example1
38 |
39 | switch living room:
40 | - platform: example2
41 | some_config: true
42 | - platform: invalid_platform
43 | ```
44 |
45 | will be passed to the component as
46 |
47 | ```python
48 | {
49 | "unrelated_component": {
50 | "some_key": "some_value"
51 | },
52 | "switch": [
53 | {
54 | "platform": "example1"
55 | },
56 | {
57 | "platform": "example2",
58 | "some_config": True
59 | }
60 | ],
61 | }
62 | ```
63 |
--------------------------------------------------------------------------------
/docs/core/entity/weather.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Weather Entity
3 | sidebar_label: Weather
4 | ---
5 |
6 | ## Properties
7 |
8 | :::tip
9 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
10 | :::
11 |
12 | | Name | Type | Default | Description
13 | | ---- | ---- | ------- | -----------
14 | | condition | string | **Required** | The current weather condition.
15 | | temperature | float | **Required** | The current temperature in °C or °F.
16 | | temperature_unit | string | **Required** | The temperature unit, °C or °F.
17 | | pressure | float | `None` | The current air pressure in hPa or inHg.
18 | | humidity | float | `None` | The current humidity in %.
19 | | ozone | float | `None` | The current ozone level.
20 | | visibility | float | `None` | The current visibility in km or mi.
21 | | wind_speed | float | `None` | The current wind speed in km/h or mi/h.
22 | | wind_bearing | float or string | `None` | The current wind bearing in azimuth angle (degrees) or 1-3 letter cardinal direction.
23 | | forecast | array | `None` | Daily or Hourly forecast data.
24 | | attribution | string | `None` | The branding text required by the API provider.
25 |
26 | Properties have to follow the units defined in the `unit_system`.
27 |
28 | ### Forecast
29 |
30 | Forecast data should either be daily or hourly.
31 |
32 | | Name | Type | Default | Description
33 | | ---- | ---- | ------- | -----------
34 | | datetime | string | **Required** | UTC Date time in RFC 3339 format.
35 | | temperature | float | **Required** | The higher temperature in °C or °F
36 | | condition | string | `None` | The weather condition at this point.
37 | | templow | float | `None` | The lower daily Temperature in °C or °F
38 | | precipitation | float | `None` | The precipitation amount in mm or inch.
39 | | precipitation_probability | int | `None` | The probability of precipitation in %.
40 | | wind_bearing | float or string | `None` | The wind bearing in azimuth angle (degrees) or 1-3 letter cardinal direction.
41 | | wind_speed | int | `None` | The wind speed in km/h or mi/h.
42 |
43 | ### Recommended values for state and condition
44 |
45 | These weather conditions are included in our translation files and also show the corresponding icon.
46 |
47 | | Condition | Description
48 | | --------- | -----------
49 | | clear-night | Clear night
50 | | cloudy | Many clouds
51 | | exceptional | Exceptional
52 | | fog | Fog
53 | | hail | Hail
54 | | lightning | Lightning/ thunderstorms
55 | | lightning-rainy | Lightning/ thunderstorms and rain
56 | | partlycloudy | A few clouds
57 | | pouring | Pouring rain
58 | | rainy | Rain
59 | | snowy | Snow
60 | | snowy-rainy | Snow and Rain
61 | | sunny | Sunshine
62 | | windy | Wind
63 | | windy-variant | Wind and clouds
64 |
65 | This means that the `weather` platforms don't need to support languages.
66 |
--------------------------------------------------------------------------------
/docs/auth_auth_provider.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Authentication Providers"
3 | ---
4 |
5 | Authentication providers confirm the identity of users. The user proofs their identity by going through the login flow for an auth provider. The auth provider defines the login flow and can ask the user all information this needs. This will commonly be username and password but could also include a 2FA token or other challenges.
6 |
7 | Once an authentication provider has confirmed the identity of a user, it will pass that on to Home Assistant in the form of a Credentials object.
8 |
9 | ## Defining an auth provider
10 |
11 | :::info
12 | We currently only support built-in auth providers. Support for custom auth providers might arrive in the future.
13 | :::
14 |
15 | Auth providers are defined in `homeassistant/auth/providers/.py`. The auth provider module will need to provide an implementation of the `AuthProvider` class and `LoginFlow` class, it is what asks user for information and validates it base on `data_entry_flow`.
16 |
17 | For an example of a fully implemented auth provider, please see [insecure_example.py](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/auth/providers/insecure_example.py).
18 |
19 | Auth providers shall extend the following methods of `AuthProvider` class.
20 |
21 | | method | Required | Description
22 | | ------ | -------- | -----------
23 | | async def async_login_flow(self) | Yes | Return an instance of the login flow for a user to identify itself.
24 | | async def async_get_or_create_credentials(self, flow_result) | Yes | Given the result of a login flow, return a credentials object. This can either be an existing one or a new one.
25 | | async def async_user_meta_for_credentials(credentials) | No | Callback called Home Assistant is going to create a user from a Credentials object. Can be used to populate extra fields for the user.
26 |
27 | Auth providers shall extend the following methods of `LoginFlow` class.
28 |
29 | | method | Required | Description
30 | | ------ | -------- | -----------
31 | | async def async_step_init(self, user_input=None) | Yes | Handle the login form, see more detail in below.
32 |
33 | ## async_step_init of LoginFlow
34 |
35 | :::info
36 | We may change this interface in near future.
37 | :::
38 |
39 | `LoginFlow` extends `data_entry_flow.FlowHandler`. The first step of data entry flow is hard coded as `init`, so each flow has to implement `async_step_init` method. The pattern of `async_step_init` likes following pseudo-code:
40 |
41 | ```python
42 | async def async_step_init(self, user_input=None):
43 | if user_input is None:
44 | return self.async_show_form(
45 | step_id="init", data_schema="some schema to construct ui form"
46 | )
47 | if is_invalid(user_input):
48 | return self.async_show_form(step_id="init", errors=errors)
49 | return await self.async_finish(user_input)
50 | ```
51 |
--------------------------------------------------------------------------------
/docs/supervisor/developing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Develop Supervisor integration in Core & Frontend"
3 | sidebar_label: "Developing"
4 | ---
5 |
6 | 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.
7 |
8 | For this guide, we're going to assume that you have a [Home Assistant Core development environment](development_environment.md) set up.
9 |
10 | ## Supervisor API Access
11 |
12 | 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.
13 |
14 | - Add our developer Add-on repository:
15 | - Install the Add-on "Remote API proxy"
16 | - Click Start
17 | - The token will be printed in the logs
18 |
19 | The add-on needs to keep running to allow Home Assistant Core to connect.
20 |
21 | 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:
22 |
23 | ```shell
24 | docker inspect homeassistant | grep HASSIO_TOKEN
25 | ```
26 |
27 | Note that either token can change after a reboot or update of OS/container.
28 |
29 | ## Setting up Home Assistant Core
30 |
31 | To configure Home Assistant Core to connect to a remote supervisor, set the following environment variables when starting Home Assistant:
32 |
33 | - `HASSIO`: Set to the IP of the machine running Home Assistant and port 80 (the API proxy add-on)
34 | - `HASSIO_TOKEN`: Set this to the token that you extracted in the previous step
35 |
36 | ```shell
37 | HASSIO=192.168.1.100:80 HASSIO_TOKEN=abcdefghj1234 hass
38 | ```
39 |
40 | Voilà. Your local Home Assistant installation will now connect to a remote Home Assistant instance.
41 |
42 | ## Frontend development
43 |
44 | To do frontend development you need to have a [Home Assistant frontend development environment](/frontend/development.md) set up.
45 |
46 | Update the `hassio` component configuration in your `configuration.yaml` file to point at the frontend repository:
47 |
48 | ```yaml
49 | # configuration.yaml
50 | hassio:
51 | # Example path. Change it to where you have checked out the frontend repository
52 | development_repo: /home/paulus/dev/hass/frontend
53 | ```
54 |
55 | To build a local version of the Supervisor panel, go to the frontend repository and run:
56 |
57 | ```shell
58 | cd hassio
59 | script/develop
60 | ```
61 |
62 | 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.
63 |
64 | While `script/develop` is running, the Supervisor panel will be rebuilt whenever you make changes to the source files.
65 |
--------------------------------------------------------------------------------
/docs/frontend/external-authentication.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "External Authentication"
3 | ---
4 |
5 | By default, the frontend will take care of its own authentication tokens. If none found, it will redirect the user to the login page and it will take care that the token is up to date.
6 |
7 | If you want to embed the Home Assistant frontend in an external app, you will want to store the authentication inside the app but make it available to the frontend. To support this, Home Assistant exposes an external authentication API.
8 |
9 | To activate this API, load the frontend with `?external_auth=1` appended to the URL. If this is passed in, Home Assistant will expect either `window.externalApp` (for Android) or `window.webkit.messageHandlers` (for iOS) to be defined containing the methods described below.
10 |
11 | ## Get Access Token
12 |
13 | _This API has been introduced in Home Assistant 0.78._
14 |
15 | When the frontend loads, it will request an access token from the external authentication. It does so by calling one of the following methods with an options object. The options object defines the callback method to be called with the response and an optional `force` boolean which is set to `true` if the access token should be refreshed, regardless if it has expired or not.
16 |
17 | The `force` boolean has been introduced in Home Assistant 0.104 and might not always be available.
18 |
19 | ```js
20 | window.externalApp.getExternalAuth({
21 | callback: "externalAuthSetToken",
22 | force: true
23 | });
24 | // or
25 | window.webkit.messageHandlers.getExternalAuth.postMessage({
26 | callback: "externalAuthSetToken",
27 | force: true
28 | });
29 | ```
30 |
31 | The response should contain a boolean if it was successful and an object containing an access token and the number of seconds that it will remain valid. Pass the response to the function defined in the options object.
32 |
33 | ```js
34 | // To be called by external app
35 | window.externalAuthSetToken(true, {
36 | access_token: "qwere",
37 | expires_in: 1800
38 | });
39 |
40 | // If unable to get new access token
41 | window.externalAuthSetToken(false);
42 | ```
43 |
44 | The frontend will call this method when the page first loads and whenever it needs a valid token but the previous received token has expired.
45 |
46 | ## Revoke Token
47 |
48 | _This API has been introduced in Home Assistant 0.78._
49 |
50 | When the user presses the logout button on the profile page, the external app will have to [revoke the refresh token](auth_api.md#revoking-a-refresh-token), and log the user out.
51 |
52 | ```js
53 | window.externalApp.revokeExternalAuth({
54 | callback: "externalAuthRevokeToken"
55 | });
56 | // or
57 | window.webkit.messageHandlers.revokeExternalAuth.postMessage({
58 | callback: "externalAuthRevokeToken"
59 | });
60 | ```
61 |
62 | When done, the external app has to call the function defined in the options object.
63 |
64 | ```js
65 | // To be called by external app
66 | window.externalAuthRevokeToken(true);
67 |
68 | // If unable to logout
69 | window.externalAuthRevokeToken(false);
70 | ```
71 |
--------------------------------------------------------------------------------
/blog/2018-07-02-trying-new-auth.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Trying the new auth system
7 | ---
8 |
9 | In Home Assistant 0.69 we introduced the foundation for a new [authentication API](/docs/auth_index). We're switching from a single hardcoded API password to a refresh/access token based authentication system (powered by OAuth2).
10 |
11 | For Home Assistant 0.73, I've sprinted together with [@awarecan] to ensure that we have reached a minimum viable product of the auth system:
12 |
13 | - Users can be managed via a built-in command line script.
14 | - The frontend will ask for username and password to login
15 | - If you opt-in for the new system, the API password will no longer work.
16 | - To not force a hard break with the ecosystem around Home Assistant, a temporary legacy mode has been added to turn API password support back on. This will be removed in the future.
17 |
18 | **The system is not yet ready for mainstream consumption**, we still need to add Hass.io support and a user interface to help guiding the user to create their first user account and to manage users. You can follow (and join!) the work to be done [here](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3Aauth).
19 |
20 | If you're interested in trying it out, keep on reading.
21 |
22 |
23 |
24 | ## Trying it out
25 |
26 | This requires you to be running Home Assistant 0.73 beta or a later version.
27 |
28 | First step will be to configure an auth provider. We are going to configure the built-in `homeassistant` auth provider. This provider will be the default one and stores users securely in the config directory.
29 |
30 | ```yaml
31 | # Example configuration.yaml entry
32 | homeassistant:
33 | auth_providers:
34 | - type: homeassistant
35 | # Uncomment next line if you want to enable legacy API password support
36 | # - type: legacy_api_password
37 |
38 | # Enable the auth component
39 | auth:
40 | ```
41 |
42 | :::info
43 | This rest of the instructions are no longer necessary in Home Assistant 0.74 or later.
44 | :::
45 |
46 | Next step is to create users. Open a terminal and navigate to your Home Assistant installation. The script for managing users is built into Home Assistant and can be invoked using `hass --script auth --config /path/to/config`.
47 |
48 | 
49 |
50 | If you restart Home Assistant and navigate to the frontend, you'll be prompted with a new login screen. If you enabled both auth providers, you will first have to pick which auth provider to use for authentication.
51 |
52 | Once logged in, the frontend will store the access and a refresh token. The access token expires every 30 minutes and whenever Home Assistant restarts. The fronend will automatically fetch a new access token using the stored refresh token. We're using the OAuth2 standard for this. [More info in the docs](/docs/auth_api).
53 |
54 | [@awarecan]: https://github.com/awarecan
55 |
--------------------------------------------------------------------------------
/docs/development_guidelines.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Style guidelines"
3 | ---
4 |
5 | Home Assistant enforces quite strict [PEP8 style](https://www.python.org/dev/peps/pep-0008/) and [PEP 257 (Docstring Conventions)](https://www.python.org/dev/peps/pep-0257/) compliance on all code submitted.
6 |
7 | We use [Black](https://github.com/psf/black) for uncompromised code formatting. Every pull request is automatically checked as part of the linting process and we never merge submissions that diverge.
8 |
9 | Summary of the most relevant points:
10 |
11 | - Comments should be full sentences and end with a period.
12 | - [Imports](https://www.python.org/dev/peps/pep-0008/#imports) should be ordered.
13 | - Constants and the content of lists and dictionaries should be in alphabetical order.
14 |
15 | It is advisable to adjust IDE or editor settings to match those requirements.
16 |
17 | ## Our recommendations
18 |
19 | For some cases [PEPs](https://www.python.org/dev/peps/) don't make a statement. This section covers our recommendations about the code style. Those points were collected from the existing code and based on what contributors and developers were using the most. This is basically a majority decision, thus you may not agree with it. But we would like to encourage you follow those recommendations to keep the code consistent.
20 |
21 | ### File headers
22 |
23 | The docstring in the file header should describe what the file is about.
24 |
25 | ```python
26 | """Support for MQTT lights."""
27 | ```
28 |
29 | ### Log messages
30 |
31 | There is no need to add the platform or component name to the log messages. This will be added automatically. Like `syslog` messages there shouldn't be any period at the end. A widely used style is shown below but you are free to compose the messages as you like.
32 |
33 | ```python
34 | _LOGGER.error("No route to device: %s", self._resource)
35 | ```
36 |
37 | ```log
38 | 2017-05-01 14:28:07 ERROR [homeassistant.components.sensor.arest] No route to device: 192.168.0.18
39 | ```
40 |
41 | Do not print out API keys, tokens, usernames or passwords (even if they are wrong).
42 | Also note that `_LOGGER.info` is reserved for the core, use `_LOGGER.debug` for anything else.
43 |
44 | ### Ordering of imports
45 |
46 | Instead of order the imports manually, use [`isort`](https://github.com/timothycrosley/isort).
47 |
48 | ```shell
49 | pip3 install isort
50 | isort homeassistant/components/sensor/fixer.py
51 | ```
52 |
53 | ### Use new style string formatting
54 |
55 | Prefer [f-strings](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) over `%` or `str.format`.
56 |
57 | ```python
58 | # New
59 | f"{some_value} {some_other_value}"
60 | # Old, wrong
61 | "{} {}".format("New", "style")
62 | "%s %s" % ("Old", "style")
63 | ```
64 |
65 | One exception is for logging which uses the percentage formatting. This is to avoid formatting the log message when it is suppressed.
66 |
67 | ```python
68 | _LOGGER.info("Can't connect to the webservice %s at %s", string1, string2)
69 | ```
70 |
71 | ### Typing of functions
72 |
73 | Either completely type a function or do not type a function at all.
74 |
--------------------------------------------------------------------------------
/docs/core/entity/water-heater.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Water Heater Entity
3 | sidebar_label: Water Heater
4 | ---
5 |
6 | ## Properties
7 |
8 | :::tip
9 | Properties should always only return information from memory and not do I/O (like network requests). Implement `update()` or `async_update()` to fetch data.
10 | :::
11 |
12 | | Name | Type | Default | Description
13 | | --------------------- | ----------- | --------- | -----------
14 | | `min_temp` | `float` | 110°F | The minimum temperature that can be set.
15 | | `max_temp` | `float` | 140°F | The maximum temperature that can be set.
16 | | `current_temperature` | `float` | `None` | The current temperature.
17 | | `target_temperature` | `float` | `None` | The temperature we are trying to reach.
18 | | `target_temperature_high` | `float` | `None` | Upper bound of the temperature we are trying to reach.
19 | | `target_temperature_low` | `float` | `None` | Lower bound of the temperature we are trying to reach.
20 | | `temperature_unit` | `str` | `NotImplementedError` | One of `TEMP_CELSIUS`, `TEMP_FAHRENHEIT`, or `TEMP_KELVIN`.
21 | | `current_operation` | `string` | `None` | The current operation mode.
22 | | `operation_list` | `List[str]` | `None` | List of possible operation modes.
23 | | `supported_features` | `List[str]` | `NotImplementedError` | List of supported features.
24 | | `is_away_mode_on` | `bool` | `None` | The current status of away mode.
25 |
26 | The allowed operation modes are the states specified in the base component and implementations of the water_heater component cannot differ.
27 |
28 | Properties have to follow the units defined in the `temperature_unit`.
29 |
30 | ## States
31 |
32 | | State | Description
33 | | ----- | -----------
34 | | `STATE_ECO` | Energy efficient mode, provides energy savings and fast heating.
35 | | `STATE_ELECTRIC` | Electric only mode, uses the most energy.
36 | | `STATE_PERFORMANCE` | High performance mode.
37 | | `STATE_HIGH_DEMAND` | Meet high demands when water heater is undersized.
38 | | `STATE_HEAT_PUMP` | Slowest to heat, but uses less energy.
39 | | `STATE_GAS` | Gas only mode, uses the most energy.
40 | | `STATE_OFF` | The water heater is off.
41 |
42 | ## Supported Features
43 |
44 | | Feature | Description
45 | | ---------------------------- | -----------
46 | | `SUPPORT_TARGET_TEMPERATURE` | Temperature can be set
47 | | `SUPPORT_OPERATION_MODE` | Operation mode can be set
48 | | `SUPPORT_AWAY_MODE` | Away mode can be set
49 |
50 | ## Methods
51 |
52 | ### `set_temperature` or `async_set_temperature`
53 |
54 | Sets the temperature the water heater should heat water to.
55 |
56 | ### `set_operation_mode`or `async_set_operation_mode`
57 |
58 | Sets the operation mode of the water heater. Must be in the operation_list.
59 |
60 | ### `turn_away_mode_on` or `async_turn_away_mode_on`
61 |
62 | Set the water heater to away mode.
63 |
64 | ### `turn_away_mode_off` or `async_turn_away_mode_off`
65 |
66 | Set the water heater back to the previous operation mode. Turn off away mode.
67 |
--------------------------------------------------------------------------------
/blog/2019-04-12-new-integration-structure.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: Introducing Integrations
7 | ---
8 |
9 | We have finished [the great migration](/blog/2019/02/19/the-great-migration). The result will be released as part of Home Assistant 0.92. The release has been a bit delayed because we had a lot of things to fix! With the migration done, we now consider components and platforms that share the same name to be part of the same integration. Each integration is either a single Python file, or a folder with an `__init__.py`. file. We have updated the documentation and introduced a new section for [integrations](/docs/creating_integration_file_structure).
10 |
11 | Home Assistant 0.92 introduces a new [`manifest.json`](/docs/creating_integration_manifest) for integrations. This file, which is optional for custom components, is used by integrations to specify metadata: name, link to the documentation, dependencies, requirements and code owners. We are exploring leveraging `manifest.json` for additional future features, like tracking breaking changes or allowing custom components to provide config flows and being discovered.
12 |
13 | With all these changes, we had to drop a few deprecated things and change some behavior:
14 |
15 | - Platforms can no longer be in the directory of the entity component, like `light/my_platform.py`. Instead, create a new `my_platform` folder in your custom_components, create an empty `__init__.py` file and move `light/my_platform.py` to `my_platform/light.py`.
16 | - Platforms can no longer have dependencies or requirements. Instead, create a [`manifest.json`](/docs/creating_integration_manifest) in the `my_platform` folder to specify them, or add `REQUIREMENTS` or `DEPENDENCIES` constants to the `__init__.py` file.
17 | - A platform will now always require the component, if available, to be set up first.
18 | - It is no longer possible to provide translations for components that are contained in a single Python file. Convert them to an integration in [a directory](/docs/creating_integration_file_structure).
19 | - If you want to override a built-in integration, you need to specify a `manifest.json` for your custom integration. Note that we strongly discourage overriding built-in integrations. Instead, if you want to run an integration with custom changes change the integration name. For example if you want to run a custom version of the MQTT integration, named `mqtt` in Home Assistant:
20 | - Copy the content of the `mqtt` folder from [the Home Assistant repository](https://github.com/home-assistant/home-assistant/tree/dev/homeassistant/components/mqtt) to a new folder `/custom_components/mqtt_custom/`
21 | - Open `mqtt_custom/manifest.json` and change the value for `domain` from `mqtt` to `mqtt_custom`
22 | - Open `mqtt_custom/__init__.py` and change the value of `DOMAIN` from `mqtt` to `mqtt_custom`
23 | - Anywhere in your config where you referenced `mqtt`, reference `mqtt_custom`. So use `mqtt_custom:` to specify the host and use `platform: mqtt_custom` when specifying platforms.
24 |
--------------------------------------------------------------------------------
/blog/2020-09-30-customViewChanges.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Zack Barett
3 | authorURL: https://github.com/zsarnett
4 | authorTwitter: zsarnett
5 | title: "Lovelace: Custom View Layouts"
6 | ---
7 |
8 | Custom Element developers can now create Custom View Layouts that users can load and use!
9 |
10 | In 0.116, we will be changing the way that we create Views in Lovelace. In the past, we had 2 views, a default view and a panel view. When talking about adding Drag and Drop to Lovelace, we decided we could do even better and start allowing custom view types.
11 |
12 | Custom Developers will now be able to create a view that receives the following properties:
13 |
14 | ```ts
15 | interface LovelaceViewElement {
16 | hass?: HomeAssistant;
17 | lovelace?: Lovelace;
18 | index?: number;
19 | cards?: Array;
20 | badges?: LovelaceBadge[];
21 | setConfig(config: LovelaceViewConfig): void;
22 | }
23 | ```
24 |
25 | Cards and Badges will be created and maintained by the core code and given to the custom view. The custom views are meant to load the cards and badges and display them in a customized layout.
26 |
27 | Here is an example below: (note: this example does not have all of the properties but the necessities to show the example)
28 |
29 | ```js
30 | class MyNewView extends LitElement {
31 | setConfig(_config) {}
32 |
33 | static get properties() {
34 | return {
35 | cards: {type: Array, attribute: false}
36 | };
37 | }
38 |
39 | render() {
40 | if(!this.cards) {
41 | return html``;
42 | }
43 | return html`${this.cards.map((card) => html`
${card}
`)}`;
44 | }
45 | }
46 | ```
47 |
48 | And you can define this element in the Custom Element Registry just as you would with a Custom Card:
49 |
50 | ```js
51 | customElements.define("my-new-view", MyNewView);
52 | ```
53 |
54 | You can find an example of this in our default view: `Masonry View` Located here: [frontend/src/panels/lovelace/views/hui-masonry-view.ts](https://github.com/home-assistant/frontend/blob/master/src/panels/lovelace/views/hui-masonry-view.ts)
55 |
56 | A user who downloads and installs your new Custom View can then use it via editing the YAML configuration of their view to be:
57 |
58 | ```yaml
59 | - title: Home View
60 | type: custom:my-new-view
61 | badges: [...]
62 | cards: [...]
63 | ```
64 |
65 | Custom Developers can add a `layout` property to each card that can store a key, position info, width, height, etc:
66 |
67 | ```yaml
68 | - type: weather-card
69 | layout:
70 | key: 1234
71 | width: 54px
72 | entity: weather.my_weather
73 | ```
74 |
75 | ### Breaking Change
76 |
77 | For Custom Card developers that use something like this:
78 |
79 | ```js
80 | const LitElement = Object.getPrototypeOf(customElements.get("hui-view"));
81 | ```
82 |
83 | You will no longer be able to use the `hui-view` element to retrieve LitElement as it has been changed to be an `updatingElement`. Instead you can use:
84 |
85 | ```js
86 | const LitElement = Object.getPrototypeOf(customElements.get("hui-masonry-view"));
87 | ```
88 |
89 | But Note! This is not supported by HA. In the future, this may not work to import LitElement.
90 |
--------------------------------------------------------------------------------
/static/js/discourse_discussion.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | export default class DiscussionBox extends React.Component {
5 |
6 | constructor(props) {
7 | super(props);
8 | this.postMessageReceived = this.postMessageReceived.bind(this);
9 | }
10 |
11 | componentDidMount() {
12 | this.DiscourseEmbed = {
13 | discourseUrl: this.props.discourseUrl,
14 | discourseEmbedUrl: this.props.discourseEmbedUrl,
15 | };
16 | window.addEventListener('message', this.postMessageReceived, false);
17 | }
18 |
19 | componentWillUnmount() {
20 | window.removeEventListener('message', this.postMessageReceived);
21 | }
22 |
23 | getIframeSource() {
24 | const { discourseUrl, discourseEmbedUrl, discourseUserName } = this.props;
25 | const queryParams = {};
26 |
27 | if (discourseEmbedUrl) {
28 | if (discourseEmbedUrl.indexOf('/') === 0) {
29 | console.error('discourseEmbedUrl must be a full URL, not a relative path');
30 | }
31 |
32 | queryParams.embed_url = encodeURIComponent(discourseEmbedUrl);
33 | }
34 |
35 | if (discourseUserName) {
36 | queryParams.discourse_username = discourseUserName;
37 | }
38 |
39 | let src = discourseUrl + 'embed/comments';
40 | const keys = Object.keys(queryParams);
41 | if (keys.length > 0) {
42 | src += '?';
43 |
44 | for (let i = 0; i < keys.length; i++) {
45 | if (i > 0) { src += '&'; }
46 |
47 | const k = keys[i];
48 | src += k + '=' + queryParams[k];
49 | }
50 | }
51 |
52 | return src;
53 | }
54 |
55 | postMessageReceived(e) {
56 | if (!e) { return; }
57 |
58 | const iframe = this.iframe;
59 | const { discourseUrl } = this.props;
60 |
61 | if (normalizeUrl(discourseUrl).indexOf(normalizeUrl(e.origin)) === -1) { return; }
62 |
63 | if (e.data) {
64 | if (e.data.type === 'discourse-resize' && e.data.height) {
65 | iframe.height = e.data.height + 'px';
66 | }
67 |
68 | if (e.data.type === 'discourse-scroll' && e.data.top) {
69 | // find iframe offset
70 | const destY = findPosY(iframe) + e.data.top;
71 | window.scrollTo(0, destY);
72 | }
73 | }
74 | }
75 |
76 | render() {
77 | return (
78 |
81 |
91 | );
92 | }
93 | }
94 |
95 | function normalizeUrl(url) {
96 | return url.toLowerCase().replace(/^https?(\:\/\/)?/, '');
97 | }
98 |
99 | function findPosY(obj) {
100 | let top = 0;
101 | if (obj.offsetParent) {
102 | while (1) {
103 | top += obj.offsetTop;
104 | if (!obj.offsetParent) {
105 | break;
106 | }
107 | obj = obj.offsetParent;
108 | }
109 | } else if (obj.y) {
110 | top += obj.y;
111 | }
112 | return top;
113 | }
114 |
--------------------------------------------------------------------------------
/blog/2019-02-19-the-great-migration.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Paulus Schoutsen
3 | authorURL: https://twitter.com/balloob
4 | authorImageURL: /img/profile/paulus.jpg
5 | authorTwitter: balloob
6 | title: The Great Migration
7 | ---
8 |
9 | Home Assistant is based around components. One type of components is the one that provide an entity abstraction for a type of device, like lights, switches or media players. Historically, to integrate with these abstractions, you would create a platform for this component. If the light component would be `light/`, the integration would create its platform as `light/hue.py`. This way, all logic for the lights was kept together.
10 |
11 | As Home Assistant grown, so has the capabilities/size of the devices/services that we've integrated with. It's no longer that an integration is just a platform for an entity component, it is five platforms + a component to manage the connection. With integrations that big, having the files be spread out as `light/zwave.py`, `switch/zwave.py`, `cover/zwave.py` etc becomes a maintenance hell. It also makes distribution of custom components harder, as now users need to create files across different folders.
12 |
13 | So with Home Assistant 0.87 we started a migration. Instead of looking up platforms for entity components as `light/hue.py`, we will now look it up as `hue/light.py`. The content of the file will stay exactly the same. By moving the files out of the entity component folder, we will also be able to break up big entity components into multiple files, to support maintainability.
14 |
15 | This change has been implemented mostly backwards compatible with a minor breaking change for custom components: if you override a built-in platform, you will now need to use the new `hue/light.py` filename format.
16 |
17 | With the consolidation of integration files into a single folder, we're also going to enforce a new rule: all platforms will be loaded from the same source as the component. This means that if you want to override a built-in component/platform with a custom version, you will need to copy over all component and platform files, not just the one you want to load. By doing so, we can prevent custom platforms or components from breaking if a Home Assistant upgrade moves internal files/values around.
18 |
19 | ## Notes for custom component developers
20 |
21 | - Components are created in `/custom_components//`. Always make sure you create at least an empty `__init__.py` file in that folder.
22 | - If you make a platform for an entity component, put it in the folder with the name of the integration: `/light.py`
23 | - If you want to share an adjusted version of a Home Assistant integration, copy over ALL the files. Do your users a favor and stick to relative imports to avoid having your component break during an upgrade. Example of a relative import is `from . import DATA_BRIDGE`.
24 |
25 | ## Resources
26 |
27 | Related architecture issues:
28 |
29 | - [Embedded platforms and the road to packaged components](https://github.com/home-assistant/architecture/issues/124)
30 | - [Disable partial custom component overlays](https://github.com/home-assistant/architecture/issues/141)
31 | - [Config structure for embedded platforms](https://github.com/home-assistant/architecture/issues/142)
32 |
--------------------------------------------------------------------------------
/docs/entity_registry_disabled_by.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Entity Registry and disabling entities
3 | sidebar_label: Disabling entities
4 | ---
5 |
6 | The entity registry tracks all entities with unique IDs. For each entity, the registry keeps track of options that impact how the entity interacts with the core. One of these options is `disabled_by`.
7 |
8 | When `disabled_by` is set to a string value, the entity will not be added to Home Assistant when the integration passes it to `async_add_entities`.
9 |
10 | ## Integration Architecture
11 |
12 | Integrations will need to make sure that they work correctly when their entities get disabled. If your integration is keeping references to the created entity objects, it should register those references only inside the entity's lifecycle method `async_added_to_hass`. This lifecycle method is only called if the entity is actually added to Home Assistant (and so it's not disabled).
13 |
14 | Entity disabling works with entities provided via a config entry or via an entry in configuration.yaml. If your integration is set up via a config entry and supports [unloading](config_entries_index.md#unloading-entries), Home Assistant will be able to reload your integration after entities have been enabled/disabled to apply the changes without a restart.
15 |
16 | ## Users editing the entity registry
17 |
18 | One way an entity can be disabled is by the user editing the entity registry via the UI. In this case, the `disabled_by` value will be set to `user`. This will only work with entities that are already registered.
19 |
20 | ## Integrations setting default value of disabled_by for new entity registry entries
21 |
22 | As an integration you can control if your entity is enabled when it is first registered. This is controlled by the `entity_registry_enabled_default` property. It defaults to `True`, which means the entity will be enabled.
23 |
24 | If the property returns `False`, the `disabled_by` value of the newly registered entity will be set to `integration`.
25 |
26 | ## Config entry system options setting default value of disabled_by for new entity registry entries
27 |
28 | The user can also control how new entities that are related to a config entry are received by setting the system option `disable_new_entities` of a config entry to `True`. This can be done via the UI.
29 |
30 | If an entity is getting registered and this system option is set to `True`, the `disabled_by` property will be initialized as `config_entry`.
31 |
32 | If `disable_new_entities` is set to `True` and `entity_registry_enabled_default` returns `False`, the `disabled_by` value will be set to `integration`.
33 |
34 | ## Integrations offering options to control disabled_by
35 |
36 | Some integrations will want to offer options to the user to control which entities are being added to Home Assistant. For example, the Unifi integration offers options to enable/disable wireless and wired clients.
37 |
38 | Integrations can offer options to users either via [configuration.yaml](/configuration_yaml_index.md) or using an [Options Flow](/config_entries_options_flow_handler.md).
39 |
40 | If this option is offered by integrations, you should not leverage the disabled_by property in the entity registry. Instead, if entities are disabled via a config options flow, remove them from the device and entity registry.
41 |
--------------------------------------------------------------------------------
/docs/architecture_components.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Components Architecture"
3 | sidebar_label: "Components"
4 | ---
5 |
6 | Home Assistant can be extended with **components**. Each component is responsible for a specific domain within Home Assistant. Components can listen for or trigger events, offer services, and maintain states. Components are written in Python and can do all the goodness that Python has to offer. Out of the box, Home Assistant offers a bunch of [built-in components](https://www.home-assistant.io/integrations/).
7 |
8 |
11 |
12 | There are two types of components within Home Assistant: components that interact with an Internet of Things domain, and components that respond to events that happen within Home Assistant. Read on to learn about each type!
13 |
14 | ## Components that interact with an Internet-of-Things domain
15 |
16 | These components track devices within a specific domain and consist of a core part and platform-specific logic. These components make their information available via the State Machine and the Event Bus. The components also register services in the Service Registry to expose control of the devices.
17 |
18 | For example, the built-in [`switch` component](https://www.home-assistant.io/components/switch/) is responsible for interaction with different types of switches. A platform provides support for a particular kind or brand of device. For example, a switch could use a WeMo or Orvibo platform and a light component might interact with the Hue or LIFX platform.
19 |
20 | If you want to add support for a new platform, check out the [add new platform section](creating_platform_index.md).
21 |
22 | ## Components that respond to events that happen within Home Assistant
23 |
24 | These components provide small pieces of home automation logic or involve services that do common tasks within your house.
25 |
26 | For example, the [`device_sun_light_trigger` component](https://www.home-assistant.io/components/device_sun_light_trigger/) tracks the state of devices and the sun to make sure that the lights are turned on when it gets dark and people are home. The component uses logic like this:
27 |
28 | ```text
29 | In the event that device 'Paulus Nexus 5' changes to the 'Home' state:
30 | If the sun has set and the lights are not on:
31 | Turn on the lights
32 | ```
33 |
34 | ```text
35 | In the event that the combined state of all tracked devices changes to 'Not Home':
36 | If the lights are on:
37 | Turn off the lights
38 | ```
39 |
40 | ```text
41 | In the event of the sun setting:
42 | If the lights are off and the combined state of all tracked device equals 'Home':
43 | Turn on the lights
44 | ```
45 |
46 | ## The full picture
47 |
48 | When we put all the different pieces of Home Assistant together, it's a close match for the initial home automation overview sketch. The smart home AI has not been implemented yet, so it's not included in this picture.
49 |
50 |
54 |
55 | The platform logic for components uses third-party Python libraries to communicate with the devices. Through this, we can leverage some of the best libraries in the Python community.
56 |
--------------------------------------------------------------------------------
/static/_redirects:
--------------------------------------------------------------------------------
1 | # These redirects are handled by Netlify
2 | #
3 |
4 | # Documentation restructuring redirects
5 | /docs/app_integration_index /docs/api/native-app-integration
6 | /docs/app_integration_notifications /docs/api/native-app-integration/notifications
7 | /docs/app_integration_sending_data /docs/api/native-app-integration/sending-data
8 | /docs/app_integration_sensors /docs/api/native-app-integration/sensors
9 | /docs/app_integration_setup /docs/api/native-app-integration/setup
10 | /docs/app_integration_webview /docs/api/native-app-integration/webview
11 | /docs/architecture_entities /docs/core/entity
12 | /docs/architecture_hassio /docs/supervisor
13 | /docs/documentation_create_page /docs/documenting/create-page
14 | /docs/documentation_index /docs/documenting
15 | /docs/documentation_standards /docs/documenting/standards
16 | /docs/entity_air_quality /docs/core/entity/air-quality
17 | /docs/entity_alarm_control_panel /docs/core/entity/alarm-control-panel
18 | /docs/entity_binary_sensor /docs/core/entity/binary-sensor
19 | /docs/entity_climate /docs/core/entity/climate
20 | /docs/entity_cover /docs/core/entity/cover
21 | /docs/entity_fan /docs/core/entity/fan
22 | /docs/entity_index /docs/core/entity
23 | /docs/entity_light /docs/core/entity/light
24 | /docs/entity_lock /docs/core/entity/lock
25 | /docs/entity_media_player /docs/core/entity/media-player
26 | /docs/entity_remote /docs/core/entity/remote
27 | /docs/entity_sensor /docs/core/entity/sensor
28 | /docs/entity_switch /docs/core/entity/switch
29 | /docs/entity_vacuum /docs/core/entity/vacuum
30 | /docs/entity_water_heater /docs/core/entity/water-heater
31 | /docs/entity_weather /docs/core/entity/weather
32 | /docs/external_api_rest /docs/api/rest
33 | /docs/external_api_websocket /docs/api/websocket
34 | /docs/frontend_add_card /docs/frontend/extending/adding-state-card
35 | /docs/frontend_add_more_info /docs/frontend/extending/adding-more-info-dialogs
36 | /docs/frontend_add_websocket_api /docs/frontend/extending/websocket-api
37 | /docs/frontend_architecture /docs/frontend/architecture
38 | /docs/frontend_creating_custom_panels /docs/frontend/custom-ui/creating-custom-panels
39 | /docs/frontend_data /docs/frontend/data
40 | /docs/frontend_development /docs/frontend/development
41 | /docs/frontend_external_auth /docs/frontend/external-authentication
42 | /docs/frontend_external_bus /docs/frontend/external-bus
43 | /docs/frontend_index /docs/frontend
44 | /docs/hassio_addon_communication /docs/add-ons/communication
45 | /docs/hassio_addon_config /docs/add-ons/configuration
46 | /docs/hassio_addon_index /docs/add-ons
47 | /docs/hassio_addon_presentation /docs/add-ons/presentation
48 | /docs/hassio_addon_publishing /docs/add-ons/publishing
49 | /docs/hassio_addon_repository /docs/add-ons/repository
50 | /docs/hassio_addon_security /docs/add-ons/security
51 | /docs/hassio_addon_testing /docs/add-ons/testing
52 | /docs/hassio_addon_tutorial /docs/add-ons/tutorial
53 | /docs/hassio_debugging /docs/supervisor/debugging
54 | /docs/hassio_hass /docs/supervisor/developing
55 | /docs/internationalization_backend_localization /docs/internationalization/core
56 | /docs/internationalization_custom_component_localization /docs/internationalization/custom_integration
57 | /docs/internationalization_index /docs/internationalization
58 | /docs/internationalization_translation /docs/translations
59 | /docs/internationalization_translation.html /docs/translations
60 | /docs/lovelace_custom_card /docs/frontend/custom-ui/lovelace-custom-card
61 |
--------------------------------------------------------------------------------
/docs/development_validation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Validate the input"
3 | ---
4 |
5 | The `configuration.yaml` file contains the configuration options for components and platforms. We use [voluptuous](https://pypi.python.org/pypi/voluptuous) to make sure that the configuration provided by the user is valid. Some entries are optional or could be required to set up a platform or a component. Others must be a defined type or from an already-defined list.
6 |
7 | We test the configuration to ensure that users have a great experience and minimize notifications if something is wrong with a platform or component setup before Home Assistant runs.
8 |
9 | Besides [voluptuous](https://pypi.python.org/pypi/voluptuous) default types, many custom types are available. For an overview, take a look at the [config_validation.py](https://github.com/home-assistant/home-assistant/blob/master/homeassistant/helpers/config_validation.py) helper.
10 |
11 | - Types: `string`, `byte`, and `boolean`
12 | - Entity ID: `entity_id` and `entity_ids`
13 | - Numbers: `small_float` and `positive_int`
14 | - Time: `time`, `time_zone`
15 | - Misc: `template`, `slug`, `temperature_unit`, `latitude`, `longitude`, `isfile`, `sun_event`, `ensure_list`, `port`, `url`, and `icon`
16 |
17 | To validate platforms using [MQTT](https://www.home-assistant.io/components/mqtt/), `valid_subscribe_topic` and `valid_publish_topic` are available.
18 |
19 | Some things to keep in mind:
20 |
21 | - Use the constants defined in `const.py`
22 | - Import `PLATFORM_SCHEMA` from the integration you are integrating with and extend it.
23 | - Preferred order is `required` first and `optional` second
24 | - Default values for optional configuration keys need to be valid values. Don't use a default which is `None` like `vol.Optional(CONF_SOMETHING, default=None): cv.string`, set the default to `default=''` if required.
25 |
26 | ### Snippets
27 |
28 | This section contains snippets for the validation we use.
29 |
30 | #### Default name
31 |
32 | It's common to set a default for a sensor if the user doesn't provide a name to use.
33 |
34 | ```python
35 | DEFAULT_NAME = "Sensor name"
36 |
37 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
38 | {
39 | # ...
40 | vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
41 | }
42 | )
43 | ```
44 |
45 | #### Limit the values
46 |
47 | You might want to limit the user's input to a couple of options.
48 |
49 | ```python
50 | DEFAULT_METHOD = "GET"
51 |
52 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
53 | {
54 | # ...
55 | vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(["POST", "GET"]),
56 | }
57 | )
58 | ```
59 |
60 | #### Port
61 |
62 | All port numbers are from a range of 1 to 65535.
63 |
64 | ```python
65 | DEFAULT_PORT = 993
66 |
67 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
68 | {
69 | # ...
70 | vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
71 | }
72 | )
73 | ```
74 |
75 | #### Lists
76 |
77 | If a sensor has a pre-defined list of available options, test to make sure the configuration entry matches the list.
78 |
79 | ```python
80 | SENSOR_TYPES = {
81 | "article_cache": ("Article Cache", "MB"),
82 | "average_download_rate": ("Average Speed", "MB/s"),
83 | }
84 |
85 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
86 | {
87 | # ...
88 | vol.Optional(CONF_MONITORED_VARIABLES, default=[]): vol.All(
89 | cv.ensure_list, [vol.In(SENSOR_TYPES)]
90 | ),
91 | }
92 | )
93 | ```
94 |
--------------------------------------------------------------------------------
/docs/auth_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Authentication"
3 | sidebar_label: Introduction
4 | ---
5 |
6 | Home Assistant has a built-in authentication system allowing different users to interact with Home Assistant. The authentication system consist of various parts.
7 |
8 |
10 |
11 | ## Authentication providers
12 |
13 | An authentication provider is used for users to authenticate themselves. It's up to the authentication provider to choose the method of authentication and the backend to use. By default we enable the built-in Home Assistant authentication provider which stores the users securely inside your configuration directory.
14 |
15 | The authentication providers that Home Assistant will use are specified inside `configuration.yaml`. It is possible to have multiple instances of the same authentication provider active. In that case, each will be identified by a unique identifier. Authentication providers of the same type will not share credentials.
16 |
17 | ## Credentials
18 |
19 | Credentials store the authentication of a user with a specific authentication provider. It is produced when a user successfully authenticates. It will allow the system to find the user in our system. If the user does not exist, a new user will be created. This user will not be activated but will require approval by the owner.
20 |
21 | It is possible for a user to have multiple credentials linked to it. However, it can only have a single credential per specific authentication provider.
22 |
23 | ## Users
24 |
25 | Each person is a user in the system. To log in as a specific user, authenticate with any of the authentication providers that are linked to this user. When a user logs in, it will get a refresh and an access token to make requests to Home Assistant.
26 |
27 | ### Owner
28 |
29 | The user that is created during onboarding will be marked as "owner". The owner is able to manage other users and will always have access to all permissions.
30 |
31 | ## Groups
32 |
33 | Users are a member of one or more groups. Group membership is how a user is granted permissions.
34 |
35 | ## Permission Policy
36 |
37 | This is the permission policy that describes to which resources a group has access. For more information about permissions and policies, see [Permissions](auth_permissions.md).
38 |
39 | ## Access and refresh tokens
40 |
41 | Applications that want to access Home Assistant will ask the user to start an authorization flow. The flow results in an authorization code when a user successfully authorizes the application with Home Assistant. This code can be used to retrieve an access and a refresh token. The access token will have a limited lifetime while refresh tokens will remain valid until a user deletes it.
42 |
43 | The access token is used to access the Home Assistant APIs. The refresh token is used to retrieve a new valid access token.
44 |
45 | ### Refresh token types
46 |
47 | There are three different types of refresh tokens:
48 |
49 | - *Normal*: These are the tokens that are generated when a user authorizes an application. The application will hold on to these tokens on behalf of the user.
50 | - *Long-lived Access Token*: These are refresh tokens that back a long lived access token. They are created internally and never exposed to the user.
51 | - *System*: These tokens are limited to be generated and used by system users like Home Assistant OS and the Supervisor. They are never exposed to the user.
52 |
--------------------------------------------------------------------------------
/docs/frontend/custom-ui/lovelace-custom-view.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Lovelace: Custom Views"
3 | ---
4 |
5 | Custom View Layouts allow developers and users to customize the way that Cards and Badges are displayed in a view by loading the layout and specifying the type on the view. You are now not limited to our built-in sorting methods.
6 |
7 | ## API
8 |
9 | You define your custom view as a [custom element](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements). It's up to you to decide how to render your DOM inside your element. You can use Lit Element, Preact, or any other popular framework (except for React – [more info on React here](https://custom-elements-everywhere.com/#react)).
10 |
11 | Custom Views receive the following:
12 |
13 | ```ts
14 | interface LovelaceViewElement {
15 | hass?: HomeAssistant;
16 | lovelace?: Lovelace;
17 | index?: number;
18 | cards?: Array;
19 | badges?: LovelaceBadge[];
20 | setConfig(config: LovelaceViewConfig): void;
21 | }
22 | ```
23 |
24 | Cards and Badges will be created and maintained by the core code and given to the custom view. The custom views are meant to load the cards and badges and display them in a customized layout.
25 |
26 | ## Example
27 | (note: this example does not have all of the properties but the necessities to show the example)
28 |
29 | ```js
30 | class MyNewView extends LitElement {
31 | setConfig(_config) {}
32 |
33 | static get properties() {
34 | return {
35 | cards: {type: Array, attribute: false}
36 | };
37 | }
38 |
39 | render() {
40 | if(!this.cards) {
41 | return html``;
42 | }
43 | return html`${this.cards.map((card) => html`
${card}
`)}`;
44 | }
45 | }
46 | ```
47 |
48 | And you can define this element in the Custom Element Registry just as you would with a Custom Card:
49 |
50 | ```js
51 | customElements.define("my-new-view", MyNewView);
52 | ```
53 |
54 | You can find an example of this in our default view: `Masonry View` Located here: [frontend/src/panels/lovelace/views/hui-masonry-view.ts](https://github.com/home-assistant/frontend/blob/master/src/panels/lovelace/views/hui-masonry-view.ts)
55 |
56 | A user who downloads and installs your new Custom View can then use it via editing the YAML configuration of their view to be:
57 |
58 | ```yaml
59 | - title: Home View
60 | type: custom:my-new-view
61 | badges: [...]
62 | cards: [...]
63 | ```
64 |
65 | ## Store Custom Data
66 |
67 | If your view requires data to persist at a card level, there is a `layout` in the card configuration that can be used to store information. Example: Key, X and Y coordinates, width and height, etc. This can be useful when you need to store the location or dimensions of a card for your view.
68 |
69 | ```yaml
70 | - type: weather-card
71 | layout:
72 | key: 1234
73 | width: 54px
74 | entity: weather.my_weather
75 | ```
76 |
77 | ## Edit, Delete, or Add a Card
78 |
79 | To call the core frontend dialogs to edit, delete or add a card, you can simply call these three events:
80 |
81 | ```
82 | Event: "ll-delete-card"
83 | Detail: { path: [number] | [number, number] }
84 |
85 | Event: "ll-edit-card"
86 | Detail: { path: [number] | [number, number] }
87 |
88 | Event: "ll-add-card"
89 | Detail: none
90 | ```
91 |
92 | To call an event, you can use:
93 |
94 | ```js
95 | // Delete 4th card in the current view
96 | this.dispatchEvent(new Event("ll-edit-card", { detail: { path: [3] } })) // this refers to the card element
97 | ```
98 |
--------------------------------------------------------------------------------
/src/css/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 | /* You can override the default Infima variables here. */
8 | :root {
9 | --ifm-color-primary: #03a9f4;
10 | --ifm-color-primary-dark: #0398dc;
11 | --ifm-color-primary-darker: #0390cf;
12 | --ifm-color-primary-darkest: #0276ab;
13 | --ifm-color-primary-light: #14b4fc;
14 | --ifm-color-primary-lighter: #20b8fc;
15 | --ifm-color-primary-lightest: #44c3fd;
16 | --ifm-code-font-size: 95%;
17 | }
18 |
19 | .docusaurus-highlight-code-line {
20 | background-color: rgb(72, 77, 91);
21 | display: block;
22 | margin: 0 calc(-1 * var(--ifm-pre-padding));
23 | padding: 0 var(--ifm-pre-padding);
24 | }
25 |
26 | .videoSection {
27 | padding: 20px 0;
28 | }
29 |
30 | .videoWrapper {
31 | position: relative;
32 | padding-bottom: 56.25%; /* 16:9 */
33 | height: 0;
34 | background: #000;
35 | }
36 |
37 | .videoWrapper iframe {
38 | position: absolute;
39 | top: 0;
40 | left: 0;
41 | width: 100%;
42 | height: 100%;
43 | }
44 |
45 | .introSection {
46 | padding-bottom: 20px;
47 | }
48 |
49 | img.inline {
50 | display: inline-block;
51 | }
52 |
53 | small {
54 | font-size: smaller;
55 | }
56 |
57 | @media only screen and (min-device-width: 360px) and (max-device-width: 736px) {
58 | }
59 |
60 | @media only screen and (min-width: 1024px) {
61 | }
62 |
63 | @media only screen and (max-width: 1023px) {
64 | }
65 |
66 | @media only screen and (min-width: 1400px) {
67 | }
68 |
69 | @media only screen and (min-width: 1500px) {
70 | }
71 |
72 | #demo {
73 | width: 100%;
74 | height: 475px;
75 | border: 2px solid #03A9F4;
76 | border-radius: 4px;
77 | }
78 | #discourse-comments {
79 | margin-top: 2em;
80 | }
81 | .show-small {
82 | display: none;
83 | }
84 | .onPageNav {
85 | display: none;
86 | }
87 | @media (max-width: 600px) {
88 | .hide-small {
89 | display: none;
90 | }
91 | .show-small {
92 | display: initial;
93 | }
94 | }
95 |
96 | html[data-theme='dark'] .invertDark {
97 | filter: invert(1.0)
98 | }
99 |
100 | /* Styles for @site/static/js/api_endpoint.jsx */
101 | .api-endpoint {
102 | margin: 4px 0;
103 | }
104 | .api-endpoint-header {
105 | align-items: center;
106 | background-color: var(--ifm-code-background);
107 | border-radius: var(--ifm-code-border-radius);
108 | cursor: pointer;
109 | display: flex;
110 | padding: var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal);
111 | word-break: break-all;
112 | }
113 | .api-endpoint-content {
114 | padding: 8px 8px 16px;
115 | }
116 |
117 | .api-endpoint-protection {
118 | margin: auto;
119 | margin-right: 0;
120 | }
121 |
122 | .api-endpoint-method {
123 | border-radius: 4px;
124 | color: white;
125 | display: block;
126 | font-weight: bold;
127 | margin-right: 12px;
128 | min-width: 84px;
129 | padding: 4px;
130 | text-align: center;
131 | text-transform: uppercase;
132 | width: 84px;
133 | }
134 |
135 | .api-endpoint-method.delete {
136 | background-color: #f93e3e;
137 | }
138 |
139 | .api-endpoint-method.get {
140 | background-color: #61affe;
141 | }
142 |
143 | .api-endpoint-method.post {
144 | background-color: #49cc90;
145 | }
146 |
147 | .api-endpoint-method.put {
148 | background-color: #fca130;
149 | }
150 | /* Styles for @site/static/js/api_endpoint.jsx */
--------------------------------------------------------------------------------
/docs/integration_quality_scale_index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Integration Quality Scale"
3 | ---
4 |
5 | The Integration Quality Scale scores each integration based on the code quality and user experience. Each level of the quality scale consists of a list of requirements. If an integration matches all requirements, it's considered to have reached that level.
6 |
7 | :::info
8 | Suggestions for changes can be done by creating an issue in the [architecture repo](https://github.com/home-assistant/architecture/issues/).
9 | :::
10 |
11 | ## No score
12 |
13 | This integration passes the bare minimum requirements to become part of the index.
14 |
15 | - Satisfy all requirements for [creating components](creating_component_code_review.md) and [creating platforms](creating_platform_code_review.md).
16 | - Configurable via `configuration.yaml`
17 |
18 | ## Silver 🥈
19 |
20 | This integration is able to cope when things go wrong. It will not print any exceptions nor will it fill the log with retry attempts.
21 |
22 | - Connection/configuration is handled via a component.
23 | - Set an appropriate `SCAN_INTERVAL` (if a polling integration)
24 | - Raise `PlatformNotReady` if unable to connect during platform setup (if appropriate)
25 | - Handles expiration of auth credentials. Refresh if possible or print correct error and fail setup. If based on a config entry, should trigger a new config entry flow to re-authorize.
26 | - Handles internet unavailable. Log a warning once when unavailable, log once when reconnected.
27 | - Handles device/service unavailable. Log a warning once when unavailable, log once when reconnected.
28 | - Set `available` property to `False` if appropriate ([docs](core/entity.md#generic-properties))
29 | - Entities have unique ID (if available) ([docs](entity_registry_index.md#unique-id-requirements))
30 |
31 | ## Gold 🥇
32 |
33 | This is a solid integration that is able to survive poor conditions and can be configured via the user interface.
34 |
35 | - Configurable via config entries.
36 | - Don't allow configuring already configured device/service (example: no 2 entries for same hub)
37 | - Tests for the config flow
38 | - Discoverable (if available)
39 | - Set unique ID in config flow (if available)
40 | - Entities have device info (if available) ([docs](device_registry_index.md#defining-devices))
41 | - Tests for fetching data from the integration and controlling it ([docs](development_testing.md))
42 | - Has a code owner ([docs](creating_integration_manifest.md#code-owners))
43 | - Entities only subscribe to updates inside `async_added_to_hass` and unsubscribe inside `async_will_remove_from_hass` ([docs](core/entity.md#lifecycle-hooks))
44 | - Entities have correct device classes where appropriate ([docs](core/entity.md#generic-properties))
45 | - Supports entities being disabled and leverages `Entity.entity_registry_enabled_default` to disable less popular entities ([docs](core/entity.md#advanced-properties))
46 | - If the device/service API can remove entities, the integration should make sure to clean up the entity and device registry.
47 |
48 | ## Platinum 🏆
49 |
50 | Best of the best. The integration is completely async, meaning it's super fast. Integrations that reach platinum level will require approval by the code owner for each PR.
51 |
52 | - Set appropriate `PARALLEL_UPDATES` constant
53 | - Support config entry unloading (called when config entry is removed)
54 | - Integration + dependency are async
55 | - Uses aiohttp and allows passing in websession (if making HTTP requests)
56 |
57 | ## Internal 🏠
58 |
59 | Integrations which are part of Home Assistant are not rated but marked as **internal**.
60 |
--------------------------------------------------------------------------------
/docs/creating_component_code_review.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Checklist for creating a component"
3 | sidebar_label: Component Checklist
4 | ---
5 |
6 | A checklist of things to do when you're adding a new component.
7 |
8 | :::info
9 | Not all existing code follows the requirements in this checklist. This cannot be used as a reason to not follow them!
10 | :::
11 |
12 | ### 0. Common
13 |
14 | 1. Follow our [Style guidelines](development_guidelines.md)
15 | 2. Use existing constants from [`const.py`](https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/const.py)
16 | - Only add new constants to `const.py` if they are widely used. Otherwise keep them on components level
17 |
18 | ### 1. Requirements
19 |
20 | 1. Requirements have been added to [`manifest.json`](creating_integration_manifest.md). The `REQUIREMENTS` constant is deprecated.
21 | 2. Requirement version should be pinned: `"requirements": ['phue==0.8.1']`
22 | 3. We no longer want requirements hosted on GitHub. Please upload to PyPi.
23 |
24 | ### 2. Configuration
25 |
26 | 1. Voluptuous schema present for [configuration validation](development_validation.md)
27 | 2. Default parameters specified in voluptuous schema, not in `setup(…)`
28 | 3. Schema using as many generic config keys as possible from `homeassistant.const`
29 | 4. If your component has platforms, define a `PLATFORM_SCHEMA` instead of a `CONFIG_SCHEMA`.
30 | 5. If using a `PLATFORM_SCHEMA` to be used with `EntityComponent`, import base from `homeassistant.helpers.config_validation`
31 | 6. Never depend on users adding things to `customize` to configure behavior inside your component.
32 |
33 | ### 3. Component/platform communication
34 |
35 | 1. You can share data with your platforms by leveraging `hass.data[DOMAIN]`.
36 | 2. If the component fetches data that causes its related platform entities to update, you can notify them using the dispatcher code in `homeassistant.helpers.dispatcher`.
37 |
38 | ### 4. Communication with devices/services
39 |
40 | 1. All API specific code has to be part of a third party library hosted on PyPi. Home Assistant should only interact with objects and not make direct calls to the API.
41 |
42 | ```python
43 | # bad
44 | status = requests.get(url("/status"))
45 | # good
46 | from phue import Bridge
47 |
48 | bridge = Bridge(...)
49 | status = bridge.status()
50 | ```
51 |
52 | [Tutorial on publishing your own PyPI package](https://jeffknupp.com/blog/2013/08/16/open-sourcing-a-python-project-the-right-way/)
53 |
54 | ### 5. Make your pull request as small as possible
55 |
56 | Keep a new integration to the minimum functionality needed for someone to get value out of the integration. This allows reviewers to sign off on smaller chunks of code one at a time, and lets us get your new integration/features in sooner. **Pull requests containing large code dumps will not be a priority for review and may be closed.**
57 |
58 | - Limit to a single platform
59 | - Do not add features not needed to directly support the single platform (such as custom services)
60 | - Do not mix clean-ups and new features in a single pull request.
61 | - Do not solve several issues in a single pull request.
62 | - Do not submit pull requests that depend on other work which is still unmerged.
63 |
64 | ### 6. Event names
65 |
66 | Prefix component event names with the domain name. For example, use `netatmo_person` instead of `person` for the `netatmo` component. Please be mindful of the data structure as documented on our [Data Science portal](https://data.home-assistant.io/docs/events/#database-table).
67 |
68 | ### 7. Tests
69 |
70 | Strongly consider adding tests for your component to minimize future regressions.
71 |
--------------------------------------------------------------------------------
/docs/documenting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Documentation"
3 | ---
4 |
5 | The user documentation is located at [https://www.home-assistant.io](https://www.home-assistant.io). This section here is the place where we provide documentation and additional details about creating or modifying content.
6 |
7 | The [home-assistant.io](https://home-assistant.io) website is built using [Jekyll](http://github.com/mojombo/jekyll) and [these dependencies](https://pages.github.com/versions/). The pages are written in [Markdown](http://daringfireball.net/projects/markdown/). To add a page, you don't need to know HTML.
8 |
9 | You can use the "**Edit this page on GitHub**" link to edit pages without creating a fork. Keep in mind that you can't upload images while working this way. You work on your change and propose it via a Pull Request (PR).
10 |
11 | Once you've created a Pull Request (PR), you can see a preview of the proposed changes by clicking *Details* against Netlify checker in the checkers section of the PR as soon as deployment is complete.
12 |
13 | For larger changes, we suggest that you clone the website repository. This way, you can review your changes locally. The process of working on the website is no different from working on Home Assistant itself.
14 |
15 | To test your changes locally, you need to install **Ruby** and its dependencies (gems):
16 |
17 | - [Install Ruby](https://www.ruby-lang.org/en/documentation/installation/) if you don't have it already. Ruby version 2.5.0 or higher is required.
18 | - Install `bundler`, a dependency manager for Ruby: `$ gem install bundler` (You might have to run this command as `sudo`).
19 |
20 | - Shortcut for Fedora: `$ sudo dnf -y install gcc-c++ ruby ruby-devel rubygem-bundler rubygem-json && bundle`
21 | - Shortcut for Debian/Ubuntu: `$ sudo apt-get install ruby ruby-dev ruby-bundler ruby-json g++ zlib1g-dev && bundle`
22 |
23 | - Fork the home-assistant.io [git repository](https://github.com/home-assistant/home-assistant.io).
24 | - In your home-assistant.io root directory, run `$ bundle` to install the gems you need.
25 |
26 | Then you can work on the documentation:
27 |
28 | - Run `bundle exec rake generate` to generate the very first preview. This will take a minute.
29 | - Create/edit/update a page. The integration/platforms documentation is located in `source/_integrations/`. `source/_docs/` contains the Home Assistant documentation itself.
30 | - Test your changes to home-assistant.io locally: run `bundle exec rake preview` and navigate to [http://127.0.0.1:4000](http://127.0.0.1:4000). While this command is working, any changes to a file are automatically detected and will update the affected pages. You will have to manually reload them in the browser though.
31 | - Create a Pull Request (PR) against the **next** branch of home-assistant.io if your documentation is a new feature, platform, or integration.
32 | - Create a Pull Request (PR) against the **current** branch of home-assistant.io if you fix stuff, create Cookbook entries, or expand existing documentation.
33 |
34 | The site generated by `bundle exec rake` is only available locally. If you are developing on a headless machine, use port forwarding:
35 |
36 | ```shell
37 | ssh -L 4000:localhost:4000 user_on_headless_machine@ip_of_headless_machine
38 | ```
39 |
40 | ## Speeding up site generation
41 |
42 | Every release we post long changelogs to the website. This slows down generation of the website a bit. We've include some tools to temporarily exclude integrations and blog posts that you're not working on out of the way.
43 |
44 | ```shell
45 | bundle exec rake isolate[filename-of-blogpost-or-integration]
46 | ```
47 |
48 | When you're done working on the site, run the following command to move the pages back again:
49 |
50 | ```shell
51 | bundle exec rake integrate
52 | ```
53 |
--------------------------------------------------------------------------------