├── .nvmrc ├── .npmrc ├── script ├── netlify ├── bootstrap ├── server └── setup ├── static ├── img │ ├── favicon.ico │ ├── favicon.png │ ├── default-social.png │ ├── profile │ │ ├── frenck.png │ │ └── paulus.jpg │ ├── favicon │ │ └── favicon.ico │ ├── dev-tools │ │ ├── mqtt-icon.png │ │ ├── about-icon.png │ │ ├── events-icon.png │ │ ├── states-icon.png │ │ ├── services-icon.png │ │ └── templates-icon.png │ └── en │ │ ├── intents │ │ └── overview.png │ │ ├── auth │ │ ├── architecture.png │ │ ├── mfa_workflow.png │ │ └── authorize_flow.png │ │ ├── architecture │ │ ├── hassio.png │ │ ├── ha_architecture_2020.png │ │ ├── ha_full_architecture.png │ │ ├── component_interaction.png │ │ └── entities_architecture.png │ │ ├── hass.io │ │ ├── tutorial │ │ │ ├── ssh.png │ │ │ ├── samba.png │ │ │ ├── python3-http-server.png │ │ │ └── addon_hello_world_logs.png │ │ └── screenshots │ │ │ ├── dashboard.png │ │ │ ├── first-start.png │ │ │ ├── ssh-upgrade.png │ │ │ ├── local_repository.png │ │ │ ├── adding_repositories.png │ │ │ ├── addon-hass-configurator.png │ │ │ └── main_panel_addon_store.png │ │ ├── frontend │ │ ├── frontend-hero.png │ │ ├── frontend-badges.png │ │ ├── frontend-cards1.png │ │ ├── hello-world-state-card.png │ │ ├── lovelace-ui-comparison.png │ │ ├── frontend-more-info-light.png │ │ ├── lovelace-ui-resources-tab.png │ │ ├── lovelace-ui-custom-card-screenshot.png │ │ └── lovelace-ui-profile-advanced-mode.png │ │ ├── development │ │ ├── disable-cache.png │ │ ├── bypass-for-network.png │ │ └── create-component01.png │ │ ├── device_registry │ │ └── overview.png │ │ └── blog │ │ ├── 2018-07-experimental-auth │ │ └── cli.png │ │ ├── 2019-03-user-permissions │ │ └── screenshot.png │ │ ├── 2019-10-simple-mode │ │ └── config-concepts.png │ │ ├── 2019-07-building-all-the-things │ │ ├── social.png │ │ ├── test-stages.png │ │ ├── build-cabinet.jpg │ │ ├── test-results.png │ │ └── local-hosted-agent.png │ │ ├── 2020-05-instance-url-helper │ │ └── flowchart.png │ │ └── 2020-05-logos-custom-integrations │ │ └── customlogo.png ├── js │ ├── api_endpoint.jsx │ └── discourse_discussion.jsx └── _redirects ├── docs ├── misc.md ├── operating-system.md ├── creating_component_deps_and_reqs.md ├── creating_platform_example_light.md ├── creating_platform_example_sensor.md ├── area_registry_index.md ├── asyncio_101.md ├── frontend │ ├── custom-ui │ │ ├── registering-resources.md │ │ └── lovelace-custom-view.md │ ├── extending │ │ ├── adding-more-info-dialogs.md │ │ └── adding-state-card.md │ ├── architecture.md │ └── external-authentication.md ├── api │ ├── native-app-integration.md │ ├── native-app-integration │ │ └── webview.md │ └── supervisor │ │ └── examples.md ├── development_index.md ├── device_automation_index.md ├── intent_conversation.md ├── supervisor │ ├── debugging.md │ └── developing.md ├── development_checklist.md ├── add-ons │ ├── repository.md │ └── security.md ├── internationalization.md ├── core │ └── entity │ │ ├── remote.md │ │ ├── air-quality.md │ │ ├── sensor.md │ │ ├── binary-sensor.md │ │ ├── vacuum.md │ │ ├── light.md │ │ ├── lock.md │ │ ├── switch.md │ │ ├── weather.md │ │ └── water-heater.md ├── reproduce_state_index.md ├── frontend.md ├── internationalization │ └── custom_integration.md ├── intent_handling.md ├── supervisor.md ├── dev_101_config.md ├── device_automation_action.md ├── creating_component_generic_discovery.md ├── entity_registry_index.md ├── intent_index.md ├── add-ons.md ├── architecture_index.md ├── device_automation_condition.md ├── integration_events.md ├── intent_firing.md ├── development_typing.md ├── entity_number.md ├── creating_platform_index.md ├── maintenance.md ├── dev_101_hass.md ├── asyncio_index.md ├── creating_component_index.md ├── intent_builtin.md ├── creating_integration_file_structure.md ├── development_catching_up.md ├── dev_101_index.md ├── config_entries_options_flow_handler.md ├── development_submitting.md ├── api_lib_index.md ├── dev_101_events.md ├── configuration_yaml_index.md ├── auth_auth_provider.md ├── development_guidelines.md ├── entity_registry_disabled_by.md ├── architecture_components.md ├── development_validation.md ├── auth_index.md ├── integration_quality_scale_index.md ├── creating_component_code_review.md └── documenting.md ├── .github ├── dependabot.yml ├── move.yml └── pull_request_template.md ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .vscode ├── extensions.json ├── tasks.json └── cSpell.json ├── .gitignore ├── netlify.toml ├── blog ├── 2018-08-13-deprecating-remote-package.md ├── 2020-04-10-translation-handling.md ├── 2020-05-08-logos-custom-integrations.md ├── 2019-07-31-black.md ├── 2018-05-22-custom-ui-panels-api.md ├── 2020-04-23-frontend-translations.md ├── 2020-04-16-hassfest.md ├── 2020-05-08-instance-url-helper.md ├── 2020-05-14-entity-class-names.md ├── 2020-05-09-custom-iconsets.md ├── 2020-02-18-106-custom-card-changes.md ├── 2020-04-12-s6-overlay.md ├── 2020-02-04-new-zwave.md ├── 2020-06-01-getCardSize.md ├── 2020-11-09-system-health-and-templates.md ├── 2018-06-01-071-custom-panels.md ├── 2018-07-02-trying-new-auth.md ├── 2019-04-12-new-integration-structure.md ├── 2020-09-30-customViewChanges.md └── 2019-02-19-the-great-migration.md ├── package.json └── src ├── pages └── styles.module.css └── css └── custom.css /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/* 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | scripts-prepend-node-path=true -------------------------------------------------------------------------------- /script/netlify: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | yarn build 4 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | cd "$(dirname "$0")/.." 4 | 5 | yarn 6 | -------------------------------------------------------------------------------- /script/server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | yarn start 8 | -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/favicon.png -------------------------------------------------------------------------------- /docs/misc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Miscellaneous 3 | --- 4 | 5 | Catch all category. Topics are not related to one another. 6 | -------------------------------------------------------------------------------- /static/img/default-social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/default-social.png -------------------------------------------------------------------------------- /static/img/profile/frenck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/profile/frenck.png -------------------------------------------------------------------------------- /static/img/profile/paulus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/profile/paulus.jpg -------------------------------------------------------------------------------- /static/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/favicon/favicon.ico -------------------------------------------------------------------------------- /static/img/dev-tools/mqtt-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/mqtt-icon.png -------------------------------------------------------------------------------- /static/img/en/intents/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/intents/overview.png -------------------------------------------------------------------------------- /static/img/dev-tools/about-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/about-icon.png -------------------------------------------------------------------------------- /static/img/dev-tools/events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/events-icon.png -------------------------------------------------------------------------------- /static/img/dev-tools/states-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/states-icon.png -------------------------------------------------------------------------------- /static/img/en/auth/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/auth/architecture.png -------------------------------------------------------------------------------- /static/img/en/auth/mfa_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/auth/mfa_workflow.png -------------------------------------------------------------------------------- /script/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Setups the repository. 3 | 4 | # Stop on errors 5 | set -e 6 | 7 | cd "$(dirname "$0")/.." 8 | script/bootstrap 9 | -------------------------------------------------------------------------------- /static/img/dev-tools/services-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/services-icon.png -------------------------------------------------------------------------------- /static/img/dev-tools/templates-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/dev-tools/templates-icon.png -------------------------------------------------------------------------------- /static/img/en/architecture/hassio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/architecture/hassio.png -------------------------------------------------------------------------------- /static/img/en/auth/authorize_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/auth/authorize_flow.png -------------------------------------------------------------------------------- /static/img/en/hass.io/tutorial/ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/tutorial/ssh.png -------------------------------------------------------------------------------- /static/img/en/frontend/frontend-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/frontend-hero.png -------------------------------------------------------------------------------- /static/img/en/hass.io/tutorial/samba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/tutorial/samba.png -------------------------------------------------------------------------------- /static/img/en/development/disable-cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/development/disable-cache.png -------------------------------------------------------------------------------- /static/img/en/device_registry/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/device_registry/overview.png -------------------------------------------------------------------------------- /static/img/en/frontend/frontend-badges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/frontend-badges.png -------------------------------------------------------------------------------- /static/img/en/frontend/frontend-cards1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/frontend-cards1.png -------------------------------------------------------------------------------- /static/img/en/development/bypass-for-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/development/bypass-for-network.png -------------------------------------------------------------------------------- /static/img/en/development/create-component01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/development/create-component01.png -------------------------------------------------------------------------------- /static/img/en/frontend/hello-world-state-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/hello-world-state-card.png -------------------------------------------------------------------------------- /static/img/en/frontend/lovelace-ui-comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/lovelace-ui-comparison.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/dashboard.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/first-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/first-start.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/ssh-upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/ssh-upgrade.png -------------------------------------------------------------------------------- /static/img/en/architecture/ha_architecture_2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/architecture/ha_architecture_2020.png -------------------------------------------------------------------------------- /static/img/en/architecture/ha_full_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/architecture/ha_full_architecture.png -------------------------------------------------------------------------------- /static/img/en/frontend/frontend-more-info-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/frontend-more-info-light.png -------------------------------------------------------------------------------- /static/img/en/architecture/component_interaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/architecture/component_interaction.png -------------------------------------------------------------------------------- /static/img/en/architecture/entities_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/architecture/entities_architecture.png -------------------------------------------------------------------------------- /static/img/en/blog/2018-07-experimental-auth/cli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2018-07-experimental-auth/cli.png -------------------------------------------------------------------------------- /static/img/en/frontend/lovelace-ui-resources-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/lovelace-ui-resources-tab.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/local_repository.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/local_repository.png -------------------------------------------------------------------------------- /static/img/en/hass.io/tutorial/python3-http-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/tutorial/python3-http-server.png -------------------------------------------------------------------------------- /static/img/en/blog/2019-03-user-permissions/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-03-user-permissions/screenshot.png -------------------------------------------------------------------------------- /static/img/en/blog/2019-10-simple-mode/config-concepts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-10-simple-mode/config-concepts.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/adding_repositories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/adding_repositories.png -------------------------------------------------------------------------------- /static/img/en/hass.io/tutorial/addon_hello_world_logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/tutorial/addon_hello_world_logs.png -------------------------------------------------------------------------------- /static/img/en/blog/2019-07-building-all-the-things/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-07-building-all-the-things/social.png -------------------------------------------------------------------------------- /static/img/en/blog/2020-05-instance-url-helper/flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2020-05-instance-url-helper/flowchart.png -------------------------------------------------------------------------------- /static/img/en/frontend/lovelace-ui-custom-card-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/lovelace-ui-custom-card-screenshot.png -------------------------------------------------------------------------------- /static/img/en/frontend/lovelace-ui-profile-advanced-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/frontend/lovelace-ui-profile-advanced-mode.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/addon-hass-configurator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/addon-hass-configurator.png -------------------------------------------------------------------------------- /static/img/en/hass.io/screenshots/main_panel_addon_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/hass.io/screenshots/main_panel_addon_store.png -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "06:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /docs/operating-system.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Home Assistant Operating System 3 | sidebar_label: Introduction 4 | --- 5 | 6 | This is the developer documentation for the Home Assistant Operating System. 7 | -------------------------------------------------------------------------------- /static/img/en/blog/2019-07-building-all-the-things/test-stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-07-building-all-the-things/test-stages.png -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts 2 | 3 | WORKDIR /workspaces 4 | 5 | # Set an environment variable to be able to detect we are in dev container 6 | ENV NODE_ENV=devcontainer 7 | 8 | EXPOSE 3000 9 | -------------------------------------------------------------------------------- /static/img/en/blog/2019-07-building-all-the-things/build-cabinet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-07-building-all-the-things/build-cabinet.jpg -------------------------------------------------------------------------------- /static/img/en/blog/2019-07-building-all-the-things/test-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-07-building-all-the-things/test-results.png -------------------------------------------------------------------------------- /static/img/en/blog/2020-05-logos-custom-integrations/customlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2020-05-logos-custom-integrations/customlogo.png -------------------------------------------------------------------------------- /static/img/en/blog/2019-07-building-all-the-things/local-hosted-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cougar/developers.home-assistant/master/static/img/en/blog/2019-07-building-all-the-things/local-hosted-agent.png -------------------------------------------------------------------------------- /docs/creating_component_deps_and_reqs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "" 3 | --- 4 | 5 | [This page has moved.](creating_integration_manifest.md) 6 | 7 | 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "davidanson.vscode-markdownlint", 4 | "editorconfig.editorconfig", 5 | "streetsidesoftware.code-spell-checker", 6 | "yzhang.markdown-all-in-one" 7 | ] 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/creating_platform_example_light.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "" 3 | --- 4 | 5 | [This page has moved.](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_light) 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/creating_platform_example_sensor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "" 3 | --- 4 | 5 | [This page has moved.](https://github.com/home-assistant/example-custom-config/tree/master/custom_components/example_sensor) 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/move.yml: -------------------------------------------------------------------------------- 1 | # Configuration for move-issues - https://github.com/dessant/move-issues 2 | 3 | # Delete the command comment. Ignored when the comment also contains other content 4 | deleteCommand: true 5 | # Close the source issue after moving 6 | closeSourceIssue: true 7 | # Lock the source issue after moving 8 | lockSourceIssue: false 9 | # Set custom aliases for targets 10 | # aliases: 11 | # r: repo 12 | # or: owner/repo 13 | 14 | -------------------------------------------------------------------------------- /docs/area_registry_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Area Registry 3 | sidebar_label: Introduction 4 | --- 5 | 6 | The area registry is a registry where Home Assistant keeps track of areas. An area represents a physical location for Home Assistant. It can be used to place devices in different areas. 7 | 8 | | Attribute | Description | 9 | | --------- | ----------- | 10 | | id | Unique ID of area (generated by Home Assistant) 11 | | name | Name of this area 12 | -------------------------------------------------------------------------------- /docs/asyncio_101.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Asyncio 101" 3 | --- 4 | 5 | If you are not familiar yet with asyncio, please watch the below video. It's a great introduction by [Robert Smallshire][rob] in how and why asyncio works the way it does. 6 | 7 |
8 | 9 |
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 | ![Screenshot of the Resources tab, found at the top of the Lovelace Configuration UI](/img/en/frontend/lovelace-ui-resources-tab.png) 8 | 9 | This tab is only available when the active user's profile has "advanced mode" enabled. 10 | 11 | ![Screenshot of the Advanced Mode selector found on the Profile page](/img/en/frontend/lovelace-ui-profile-advanced-mode.png) 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 | ![HACS icon in the Home Assistant frontend](/img/en/blog/2020-05-logos-custom-integrations/customlogo.png) 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 | ![Screenshot of the Home Assistant Frontend](/img/en/frontend/frontend-hero.png) 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 | The more info dialog for a light allows the user to control the color and the brightness. 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 | Architecture Overview of Home Assistant 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 |
21 |
25 |
26 | {this.props.method} 27 |
28 | {this.props.path} 29 |
36 | {this.props.unprotected ? ("🔓") : ("🔒")} 37 |
38 |
39 | {this.state.open ? ( 40 |
41 | {this.props.children} 42 |
43 | ): null} 44 |
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 | Architectural overview of intents in Home Assistant 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 | [![Flow chart of getting a Home Assistant instance URL](/img/en/blog/2020-05-instance-url-helper/flowchart.png)](/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 | Home Automation landscape 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 | Overview of the Home Assistant core architecture 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 | ![Cards in the frontend](/img/en/frontend/frontend-cards1.png) 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 | ![Badges in the frontend](/img/en/frontend/frontend-badges.png) 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 service developer tool icon. 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 | State card showing that Hello World component is working as intended. 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 | ![Screenshot showing the help output of the auth script](/img/en/blog/2018-07-experimental-auth/cli.png) 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 |